Merge pull request #26254 from ksooo/video-cleanup-contextmenus
[xbmc.git] / addons / webinterface.default / lib / video-js / video.js
blob6d94cc1162192b5e005cb10297cdb8d0a9f1c8cf
1 /**
2  * @license
3  * Video.js 5.15.1 <http://videojs.com/>
4  * Copyright Brightcove, Inc. <https://www.brightcove.com/>
5  * Available under Apache License Version 2.0
6  * <https://github.com/videojs/video.js/blob/master/LICENSE>
7  *
8  * Includes vtt.js <https://github.com/mozilla/vtt.js>
9  * Available under Apache License Version 2.0
10  * <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
11  */
13 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
14 'use strict';
16 exports.__esModule = true;
18 var _button = _dereq_(2);
20 var _button2 = _interopRequireDefault(_button);
22 var _component = _dereq_(5);
24 var _component2 = _interopRequireDefault(_component);
26 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
28 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
30 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
32 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
33                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file big-play-button.js
34                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
37 /**
38  * The initial play button that shows before the video has played. The hiding of the
39  * `BigPlayButton` get done via CSS and `Player` states.
40  *
41  * @extends Button
42  */
43 var BigPlayButton = function (_Button) {
44   _inherits(BigPlayButton, _Button);
46   function BigPlayButton() {
47     _classCallCheck(this, BigPlayButton);
49     return _possibleConstructorReturn(this, _Button.apply(this, arguments));
50   }
52   /**
53    * Builds the default DOM `className`.
54    *
55    * @return {string}
56    *         The DOM `className` for this object. Always returns 'vjs-big-play-button'.
57    */
58   BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
59     return 'vjs-big-play-button';
60   };
62   /**
63    * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
64    * for more detailed information on what a click can be.
65    *
66    * @param {EventTarget~Event} event
67    *        The `keydown`, `tap`, or `click` event that caused this function to be
68    *        called.
69    *
70    * @listens tap
71    * @listens click
72    */
75   BigPlayButton.prototype.handleClick = function handleClick(event) {
76     this.player_.play();
77   };
79   return BigPlayButton;
80 }(_button2['default']);
82 /**
83  * The text that should display over the `BigPlayButton`s controls. Added to for localization.
84  *
85  * @type {string}
86  * @private
87  */
90 BigPlayButton.prototype.controlText_ = 'Play Video';
92 _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
93 exports['default'] = BigPlayButton;
95 },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
96 'use strict';
98 exports.__esModule = true;
100 var _clickableComponent = _dereq_(3);
102 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
104 var _component = _dereq_(5);
106 var _component2 = _interopRequireDefault(_component);
108 var _log = _dereq_(86);
110 var _log2 = _interopRequireDefault(_log);
112 var _obj = _dereq_(88);
114 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
116 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
118 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
120 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
121                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file button.js
122                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
126  * Base class for all buttons.
128  * @extends ClickableComponent
129  */
130 var Button = function (_ClickableComponent) {
131   _inherits(Button, _ClickableComponent);
133   function Button() {
134     _classCallCheck(this, Button);
136     return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
137   }
139   /**
140    * Create the `Button`s DOM element.
141    *
142    * @param {string} [tag=button]
143    *        Element's node type. e.g. 'button'
144    *
145    * @param {Object} [props={}]
146    *        An object of properties that should be set on the element.
147    *
148    * @param {Object} [attributes={}]
149    *        An object of attributes that should be set on the element.
150    *
151    * @return {Element}
152    *         The element that gets created.
153    */
154   Button.prototype.createEl = function createEl() {
155     var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
156     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
157     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
159     props = (0, _obj.assign)({
160       className: this.buildCSSClass()
161     }, props);
163     if (tag !== 'button') {
164       _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
166       // Add properties for clickable element which is not a native HTML button
167       props = (0, _obj.assign)({
168         tabIndex: 0
169       }, props);
171       // Add ARIA attributes for clickable element which is not a native HTML button
172       attributes = (0, _obj.assign)({
173         role: 'button'
174       }, attributes);
175     }
177     // Add attributes for button element
178     attributes = (0, _obj.assign)({
180       // Necessary since the default button type is "submit"
181       'type': 'button',
183       // let the screen reader user know that the text of the button may change
184       'aria-live': 'polite'
185     }, attributes);
187     var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
189     this.createControlTextEl(el);
191     return el;
192   };
194   /**
195    * Add a child `Component` inside of this `Button`.
196    *
197    * @param {string|Component} child
198    *        The name or instance of a child to add.
199    *
200    * @param {Object} [options={}]
201    *        The key/value store of options that will get passed to children of
202    *        the child.
203    *
204    * @return {Component}
205    *         The `Component` that gets added as a child. When using a string the
206    *         `Component` will get created by this process.
207    *
208    * @deprecated since version 5
209    */
212   Button.prototype.addChild = function addChild(child) {
213     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
215     var className = this.constructor.name;
217     _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
219     // Avoid the error message generated by ClickableComponent's addChild method
220     return _component2['default'].prototype.addChild.call(this, child, options);
221   };
223   /**
224    * Enable the `Button` element so that it can be activated or clicked. Use this with
225    * {@link Button#disable}.
226    */
229   Button.prototype.enable = function enable() {
230     _ClickableComponent.prototype.enable.call(this);
231     this.el_.removeAttribute('disabled');
232   };
234   /**
235    * Enable the `Button` element so that it cannot be activated or clicked. Use this with
236    * {@link Button#enable}.
237    */
240   Button.prototype.disable = function disable() {
241     _ClickableComponent.prototype.disable.call(this);
242     this.el_.setAttribute('disabled', 'disabled');
243   };
245   /**
246    * This gets called when a `Button` has focus and `keydown` is triggered via a key
247    * press.
248    *
249    * @param {EventTarget~Event} event
250    *        The event that caused this function to get called.
251    *
252    * @listens keydown
253    */
256   Button.prototype.handleKeyPress = function handleKeyPress(event) {
258     // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
259     if (event.which === 32 || event.which === 13) {
260       return;
261     }
263     // Pass keypress handling up for unsupported keys
264     _ClickableComponent.prototype.handleKeyPress.call(this, event);
265   };
267   return Button;
268 }(_clickableComponent2['default']);
270 _component2['default'].registerComponent('Button', Button);
271 exports['default'] = Button;
273 },{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){
274 'use strict';
276 exports.__esModule = true;
278 var _component = _dereq_(5);
280 var _component2 = _interopRequireDefault(_component);
282 var _dom = _dereq_(81);
284 var Dom = _interopRequireWildcard(_dom);
286 var _events = _dereq_(82);
288 var Events = _interopRequireWildcard(_events);
290 var _fn = _dereq_(83);
292 var Fn = _interopRequireWildcard(_fn);
294 var _log = _dereq_(86);
296 var _log2 = _interopRequireDefault(_log);
298 var _document = _dereq_(94);
300 var _document2 = _interopRequireDefault(_document);
302 var _obj = _dereq_(88);
304 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
306 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
308 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
310 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
312 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
313                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file button.js
314                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
318  * Clickable Component which is clickable or keyboard actionable,
319  * but is not a native HTML button.
321  * @extends Component
322  */
323 var ClickableComponent = function (_Component) {
324   _inherits(ClickableComponent, _Component);
326   /**
327    * Creates an instance of this class.
328    *
329    * @param  {Player} player
330    *         The `Player` that this class should be attached to.
331    *
332    * @param  {Object} [options]
333    *         The key/value store of player options.
334    */
335   function ClickableComponent(player, options) {
336     _classCallCheck(this, ClickableComponent);
338     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
340     _this.emitTapEvents();
342     _this.enable();
343     return _this;
344   }
346   /**
347    * Create the `Component`s DOM element.
348    *
349    * @param {string} [tag=div]
350    *        The element's node type.
351    *
352    * @param {Object} [props={}]
353    *        An object of properties that should be set on the element.
354    *
355    * @param {Object} [attributes={}]
356    *        An object of attributes that should be set on the element.
357    *
358    * @return {Element}
359    *         The element that gets created.
360    */
363   ClickableComponent.prototype.createEl = function createEl() {
364     var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
365     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
366     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
368     props = (0, _obj.assign)({
369       className: this.buildCSSClass(),
370       tabIndex: 0
371     }, props);
373     if (tag === 'button') {
374       _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
375     }
377     // Add ARIA attributes for clickable element which is not a native HTML button
378     attributes = (0, _obj.assign)({
379       'role': 'button',
381       // let the screen reader user know that the text of the element may change
382       'aria-live': 'polite'
383     }, attributes);
385     this.tabIndex_ = props.tabIndex;
387     var el = _Component.prototype.createEl.call(this, tag, props, attributes);
389     this.createControlTextEl(el);
391     return el;
392   };
394   /**
395    * Create a control text element on this `Component`
396    *
397    * @param {Element} [el]
398    *        Parent element for the control text.
399    *
400    * @return {Element}
401    *         The control text element that gets created.
402    */
405   ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
406     this.controlTextEl_ = Dom.createEl('span', {
407       className: 'vjs-control-text'
408     });
410     if (el) {
411       el.appendChild(this.controlTextEl_);
412     }
414     this.controlText(this.controlText_, el);
416     return this.controlTextEl_;
417   };
419   /**
420    * Get or set the localize text to use for the controls on the `Component`.
421    *
422    * @param {string} [text]
423    *        Control text for element.
424    *
425    * @param {Element} [el=this.el()]
426    *        Element to set the title on.
427    *
428    * @return {string|ClickableComponent}
429    *         - The control text when getting
430    *         - Returns itself when setting; method can be chained.
431    */
434   ClickableComponent.prototype.controlText = function controlText(text) {
435     var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
437     if (!text) {
438       return this.controlText_ || 'Need Text';
439     }
441     var localizedText = this.localize(text);
443     this.controlText_ = text;
444     this.controlTextEl_.innerHTML = localizedText;
445     el.setAttribute('title', localizedText);
447     return this;
448   };
450   /**
451    * Builds the default DOM `className`.
452    *
453    * @return {string}
454    *         The DOM `className` for this object.
455    */
458   ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
459     return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
460   };
462   /**
463    * Enable this `Component`s element.
464    *
465    * @return {ClickableComponent}
466    *         Returns itself; method can be chained.
467    */
470   ClickableComponent.prototype.enable = function enable() {
471     this.removeClass('vjs-disabled');
472     this.el_.setAttribute('aria-disabled', 'false');
473     if (typeof this.tabIndex_ !== 'undefined') {
474       this.el_.setAttribute('tabIndex', this.tabIndex_);
475     }
476     this.on('tap', this.handleClick);
477     this.on('click', this.handleClick);
478     this.on('focus', this.handleFocus);
479     this.on('blur', this.handleBlur);
480     return this;
481   };
483   /**
484    * Disable this `Component`s element.
485    *
486    * @return {ClickableComponent}
487    *         Returns itself; method can be chained.
488    */
491   ClickableComponent.prototype.disable = function disable() {
492     this.addClass('vjs-disabled');
493     this.el_.setAttribute('aria-disabled', 'true');
494     if (typeof this.tabIndex_ !== 'undefined') {
495       this.el_.removeAttribute('tabIndex');
496     }
497     this.off('tap', this.handleClick);
498     this.off('click', this.handleClick);
499     this.off('focus', this.handleFocus);
500     this.off('blur', this.handleBlur);
501     return this;
502   };
504   /**
505    * This gets called when a `ClickableComponent` gets:
506    * - Clicked (via the `click` event, listening starts in the constructor)
507    * - Tapped (via the `tap` event, listening starts in the constructor)
508    * - The following things happen in order:
509    *   1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
510    *      `ClickableComponent`.
511    *   2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
512    *      {@link ClickableComponent#handleKeyPress}.
513    *   3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
514    *      the space or enter key.
515    *   4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
516    *      event as a parameter.
517    *
518    * @param {EventTarget~Event} event
519    *        The `keydown`, `tap`, or `click` event that caused this function to be
520    *        called.
521    *
522    * @listens tap
523    * @listens click
524    * @abstract
525    */
528   ClickableComponent.prototype.handleClick = function handleClick(event) {};
530   /**
531    * This gets called when a `ClickableComponent` gains focus via a `focus` event.
532    * Turns on listening for `keydown` events. When they happen it
533    * calls `this.handleKeyPress`.
534    *
535    * @param {EventTarget~Event} event
536    *        The `focus` event that caused this function to be called.
537    *
538    * @listens focus
539    */
542   ClickableComponent.prototype.handleFocus = function handleFocus(event) {
543     Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
544   };
546   /**
547    * Called when this ClickableComponent has focus and a key gets pressed down. By
548    * default it will call `this.handleClick` when the key is space or enter.
549    *
550    * @param {EventTarget~Event} event
551    *        The `keydown` event that caused this function to be called.
552    *
553    * @listens keydown
554    */
557   ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
559     // Support Space (32) or Enter (13) key operation to fire a click event
560     if (event.which === 32 || event.which === 13) {
561       event.preventDefault();
562       this.handleClick(event);
563     } else if (_Component.prototype.handleKeyPress) {
565       // Pass keypress handling up for unsupported keys
566       _Component.prototype.handleKeyPress.call(this, event);
567     }
568   };
570   /**
571    * Called when a `ClickableComponent` loses focus. Turns off the listener for
572    * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
573    *
574    * @param {EventTarget~Event} event
575    *        The `blur` event that caused this function to be called.
576    *
577    * @listens blur
578    */
581   ClickableComponent.prototype.handleBlur = function handleBlur(event) {
582     Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
583   };
585   return ClickableComponent;
586 }(_component2['default']);
588 _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
589 exports['default'] = ClickableComponent;
591 },{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){
592 'use strict';
594 exports.__esModule = true;
596 var _button = _dereq_(2);
598 var _button2 = _interopRequireDefault(_button);
600 var _component = _dereq_(5);
602 var _component2 = _interopRequireDefault(_component);
604 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
606 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
608 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
610 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
611                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file close-button.js
612                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
616  * The `CloseButton` is a `{@link Button}` that fires a `close` event when
617  * it gets clicked.
619  * @extends Button
620  */
621 var CloseButton = function (_Button) {
622   _inherits(CloseButton, _Button);
624   /**
625    * Creates an instance of the this class.
626    *
627    * @param  {Player} player
628    *         The `Player` that this class should be attached to.
629    *
630    * @param  {Object} [options]
631    *         The key/value store of player options.
632    */
633   function CloseButton(player, options) {
634     _classCallCheck(this, CloseButton);
636     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
638     _this.controlText(options && options.controlText || _this.localize('Close'));
639     return _this;
640   }
642   /**
643    * Builds the default DOM `className`.
644    *
645    * @return {string}
646    *         The DOM `className` for this object.
647    */
650   CloseButton.prototype.buildCSSClass = function buildCSSClass() {
651     return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
652   };
654   /**
655    * This gets called when a `CloseButton` gets clicked. See
656    * {@link ClickableComponent#handleClick} for more information on when this will be
657    * triggered
658    *
659    * @param {EventTarget~Event} event
660    *        The `keydown`, `tap`, or `click` event that caused this function to be
661    *        called.
662    *
663    * @listens tap
664    * @listens click
665    * @fires CloseButton#close
666    */
669   CloseButton.prototype.handleClick = function handleClick(event) {
671     /**
672      * Triggered when the a `CloseButton` is clicked.
673      *
674      * @event CloseButton#close
675      * @type {EventTarget~Event}
676      *
677      * @property {boolean} [bubbles=false]
678      *           set to false so that the close event does not
679      *           bubble up to parents if there is no listener
680      */
681     this.trigger({ type: 'close', bubbles: false });
682   };
684   return CloseButton;
685 }(_button2['default']);
687 _component2['default'].registerComponent('CloseButton', CloseButton);
688 exports['default'] = CloseButton;
690 },{"2":2,"5":5}],5:[function(_dereq_,module,exports){
691 'use strict';
693 exports.__esModule = true;
695 var _window = _dereq_(95);
697 var _window2 = _interopRequireDefault(_window);
699 var _dom = _dereq_(81);
701 var Dom = _interopRequireWildcard(_dom);
703 var _fn = _dereq_(83);
705 var Fn = _interopRequireWildcard(_fn);
707 var _guid = _dereq_(85);
709 var Guid = _interopRequireWildcard(_guid);
711 var _events = _dereq_(82);
713 var Events = _interopRequireWildcard(_events);
715 var _log = _dereq_(86);
717 var _log2 = _interopRequireDefault(_log);
719 var _toTitleCase = _dereq_(91);
721 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
723 var _mergeOptions = _dereq_(87);
725 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
727 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
729 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
731 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
732                                                                                                                                                            * Player Component - Base class for all UI objects
733                                                                                                                                                            *
734                                                                                                                                                            * @file component.js
735                                                                                                                                                            */
739  * Base class for all UI Components.
740  * Components are UI objects which represent both a javascript object and an element
741  * in the DOM. They can be children of other components, and can have
742  * children themselves.
744  * Components can also use methods from {@link EventTarget}
745  */
746 var Component = function () {
748   /**
749    * A callback that is called when a component is ready. Does not have any
750    * parameters and any callback value will be ignored.
751    *
752    * @callback Component~ReadyCallback
753    * @this Component
754    */
756   /**
757    * Creates an instance of this class.
758    *
759    * @param {Player} player
760    *        The `Player` that this class should be attached to.
761    *
762    * @param {Object} [options]
763    *        The key/value store of player options.
764    #
765    * @param {Object[]} [options.children]
766    *        An array of children objects to initialize this component with. Children objects have
767    *        a name property that will be used if more than one component of the same type needs to be
768    *        added.
769    *
770    * @param {Component~ReadyCallback} [ready]
771    *        Function that gets called when the `Component` is ready.
772    */
773   function Component(player, options, ready) {
774     _classCallCheck(this, Component);
776     // The component might be the player itself and we can't pass `this` to super
777     if (!player && this.play) {
778       this.player_ = player = this; // eslint-disable-line
779     } else {
780       this.player_ = player;
781     }
783     // Make a copy of prototype.options_ to protect against overriding defaults
784     this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
786     // Updated options with supplied options
787     options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
789     // Get ID from options or options element if one is supplied
790     this.id_ = options.id || options.el && options.el.id;
792     // If there was no ID from the options, generate one
793     if (!this.id_) {
794       // Don't require the player ID function in the case of mock players
795       var id = player && player.id && player.id() || 'no_player';
797       this.id_ = id + '_component_' + Guid.newGUID();
798     }
800     this.name_ = options.name || null;
802     // Create element if one wasn't provided in options
803     if (options.el) {
804       this.el_ = options.el;
805     } else if (options.createEl !== false) {
806       this.el_ = this.createEl();
807     }
809     this.children_ = [];
810     this.childIndex_ = {};
811     this.childNameIndex_ = {};
813     // Add any child components in options
814     if (options.initChildren !== false) {
815       this.initChildren();
816     }
818     this.ready(ready);
819     // Don't want to trigger ready here or it will before init is actually
820     // finished for all children that run this constructor
822     if (options.reportTouchActivity !== false) {
823       this.enableTouchActivity();
824     }
825   }
827   /**
828    * Dispose of the `Component` and all child components.
829    *
830    * @fires Component#dispose
831    */
834   Component.prototype.dispose = function dispose() {
836     /**
837      * Triggered when a `Component` is disposed.
838      *
839      * @event Component#dispose
840      * @type {EventTarget~Event}
841      *
842      * @property {boolean} [bubbles=false]
843      *           set to false so that the close event does not
844      *           bubble up
845      */
846     this.trigger({ type: 'dispose', bubbles: false });
848     // Dispose all children.
849     if (this.children_) {
850       for (var i = this.children_.length - 1; i >= 0; i--) {
851         if (this.children_[i].dispose) {
852           this.children_[i].dispose();
853         }
854       }
855     }
857     // Delete child references
858     this.children_ = null;
859     this.childIndex_ = null;
860     this.childNameIndex_ = null;
862     // Remove all event listeners.
863     this.off();
865     // Remove element from DOM
866     if (this.el_.parentNode) {
867       this.el_.parentNode.removeChild(this.el_);
868     }
870     Dom.removeElData(this.el_);
871     this.el_ = null;
872   };
874   /**
875    * Return the {@link Player} that the `Component` has attached to.
876    *
877    * @return {Player}
878    *         The player that this `Component` has attached to.
879    */
882   Component.prototype.player = function player() {
883     return this.player_;
884   };
886   /**
887    * Deep merge of options objects with new options.
888    * > Note: When both `obj` and `options` contain properties whose values are objects.
889    *         The two properties get merged using {@link module:mergeOptions}
890    *
891    * @param {Object} obj
892    *        The object that contains new options.
893    *
894    * @return {Object}
895    *         A new object of `this.options_` and `obj` merged together.
896    *
897    * @deprecated since version 5
898    */
901   Component.prototype.options = function options(obj) {
902     _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
904     if (!obj) {
905       return this.options_;
906     }
908     this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
909     return this.options_;
910   };
912   /**
913    * Get the `Component`s DOM element
914    *
915    * @return {Element}
916    *         The DOM element for this `Component`.
917    */
920   Component.prototype.el = function el() {
921     return this.el_;
922   };
924   /**
925    * Create the `Component`s DOM element.
926    *
927    * @param {string} [tagName]
928    *        Element's DOM node type. e.g. 'div'
929    *
930    * @param {Object} [properties]
931    *        An object of properties that should be set.
932    *
933    * @param {Object} [attributes]
934    *        An object of attributes that should be set.
935    *
936    * @return {Element}
937    *         The element that gets created.
938    */
941   Component.prototype.createEl = function createEl(tagName, properties, attributes) {
942     return Dom.createEl(tagName, properties, attributes);
943   };
945   /**
946    * Localize a string given the string in english.
947    *
948    * @param {string} string
949    *        The string to localize.
950    *
951    * @return {string}
952    *         The localized string or if no localization exists the english string.
953    */
956   Component.prototype.localize = function localize(string) {
957     var code = this.player_.language && this.player_.language();
958     var languages = this.player_.languages && this.player_.languages();
960     if (!code || !languages) {
961       return string;
962     }
964     var language = languages[code];
966     if (language && language[string]) {
967       return language[string];
968     }
970     var primaryCode = code.split('-')[0];
971     var primaryLang = languages[primaryCode];
973     if (primaryLang && primaryLang[string]) {
974       return primaryLang[string];
975     }
977     return string;
978   };
980   /**
981    * Return the `Component`s DOM element. This is where children get inserted.
982    * This will usually be the the same as the element returned in {@link Component#el}.
983    *
984    * @return {Element}
985    *         The content element for this `Component`.
986    */
989   Component.prototype.contentEl = function contentEl() {
990     return this.contentEl_ || this.el_;
991   };
993   /**
994    * Get this `Component`s ID
995    *
996    * @return {string}
997    *         The id of this `Component`
998    */
1001   Component.prototype.id = function id() {
1002     return this.id_;
1003   };
1005   /**
1006    * Get the `Component`s name. The name gets used to reference the `Component`
1007    * and is set during registration.
1008    *
1009    * @return {string}
1010    *         The name of this `Component`.
1011    */
1014   Component.prototype.name = function name() {
1015     return this.name_;
1016   };
1018   /**
1019    * Get an array of all child components
1020    *
1021    * @return {Array}
1022    *         The children
1023    */
1026   Component.prototype.children = function children() {
1027     return this.children_;
1028   };
1030   /**
1031    * Returns the child `Component` with the given `id`.
1032    *
1033    * @param {string} id
1034    *        The id of the child `Component` to get.
1035    *
1036    * @return {Component|undefined}
1037    *         The child `Component` with the given `id` or undefined.
1038    */
1041   Component.prototype.getChildById = function getChildById(id) {
1042     return this.childIndex_[id];
1043   };
1045   /**
1046    * Returns the child `Component` with the given `name`.
1047    *
1048    * @param {string} name
1049    *        The name of the child `Component` to get.
1050    *
1051    * @return {Component|undefined}
1052    *         The child `Component` with the given `name` or undefined.
1053    */
1056   Component.prototype.getChild = function getChild(name) {
1057     if (!name) {
1058       return;
1059     }
1061     name = (0, _toTitleCase2['default'])(name);
1063     return this.childNameIndex_[name];
1064   };
1066   /**
1067    * Add a child `Component` inside the current `Component`.
1068    *
1069    *
1070    * @param {string|Component} child
1071    *        The name or instance of a child to add.
1072    *
1073    * @param {Object} [options={}]
1074    *        The key/value store of options that will get passed to children of
1075    *        the child.
1076    *
1077    * @param {number} [index=this.children_.length]
1078    *        The index to attempt to add a child into.
1079    *
1080    * @return {Component}
1081    *         The `Component` that gets added as a child. When using a string the
1082    *         `Component` will get created by this process.
1083    */
1086   Component.prototype.addChild = function addChild(child) {
1087     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1088     var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
1090     var component = void 0;
1091     var componentName = void 0;
1093     // If child is a string, create component with options
1094     if (typeof child === 'string') {
1095       componentName = (0, _toTitleCase2['default'])(child);
1097       // Options can also be specified as a boolean,
1098       // so convert to an empty object if false.
1099       if (!options) {
1100         options = {};
1101       }
1103       // Same as above, but true is deprecated so show a warning.
1104       if (options === true) {
1105         _log2['default'].warn('Initializing a child component with `true` is deprecated.' + 'Children should be defined in an array when possible, ' + 'but if necessary use an object instead of `true`.');
1106         options = {};
1107       }
1109       var componentClassName = options.componentClass || componentName;
1111       // Set name through options
1112       options.name = componentName;
1114       // Create a new object & element for this controls set
1115       // If there's no .player_, this is a player
1116       var ComponentClass = Component.getComponent(componentClassName);
1118       if (!ComponentClass) {
1119         throw new Error('Component ' + componentClassName + ' does not exist');
1120       }
1122       // data stored directly on the videojs object may be
1123       // misidentified as a component to retain
1124       // backwards-compatibility with 4.x. check to make sure the
1125       // component class can be instantiated.
1126       if (typeof ComponentClass !== 'function') {
1127         return null;
1128       }
1130       component = new ComponentClass(this.player_ || this, options);
1132       // child is a component instance
1133     } else {
1134       component = child;
1135     }
1137     this.children_.splice(index, 0, component);
1139     if (typeof component.id === 'function') {
1140       this.childIndex_[component.id()] = component;
1141     }
1143     // If a name wasn't used to create the component, check if we can use the
1144     // name function of the component
1145     componentName = componentName || component.name && component.name();
1147     if (componentName) {
1148       this.childNameIndex_[componentName] = component;
1149     }
1151     // Add the UI object's element to the container div (box)
1152     // Having an element is not required
1153     if (typeof component.el === 'function' && component.el()) {
1154       var childNodes = this.contentEl().children;
1155       var refNode = childNodes[index] || null;
1157       this.contentEl().insertBefore(component.el(), refNode);
1158     }
1160     // Return so it can stored on parent object if desired.
1161     return component;
1162   };
1164   /**
1165    * Remove a child `Component` from this `Component`s list of children. Also removes
1166    * the child `Component`s element from this `Component`s element.
1167    *
1168    * @param {Component} component
1169    *        The child `Component` to remove.
1170    */
1173   Component.prototype.removeChild = function removeChild(component) {
1174     if (typeof component === 'string') {
1175       component = this.getChild(component);
1176     }
1178     if (!component || !this.children_) {
1179       return;
1180     }
1182     var childFound = false;
1184     for (var i = this.children_.length - 1; i >= 0; i--) {
1185       if (this.children_[i] === component) {
1186         childFound = true;
1187         this.children_.splice(i, 1);
1188         break;
1189       }
1190     }
1192     if (!childFound) {
1193       return;
1194     }
1196     this.childIndex_[component.id()] = null;
1197     this.childNameIndex_[component.name()] = null;
1199     var compEl = component.el();
1201     if (compEl && compEl.parentNode === this.contentEl()) {
1202       this.contentEl().removeChild(component.el());
1203     }
1204   };
1206   /**
1207    * Add and initialize default child `Component`s based upon options.
1208    */
1211   Component.prototype.initChildren = function initChildren() {
1212     var _this = this;
1214     var children = this.options_.children;
1216     if (children) {
1217       (function () {
1218         // `this` is `parent`
1219         var parentOptions = _this.options_;
1221         var handleAdd = function handleAdd(child) {
1222           var name = child.name;
1223           var opts = child.opts;
1225           // Allow options for children to be set at the parent options
1226           // e.g. videojs(id, { controlBar: false });
1227           // instead of videojs(id, { children: { controlBar: false });
1228           if (parentOptions[name] !== undefined) {
1229             opts = parentOptions[name];
1230           }
1232           // Allow for disabling default components
1233           // e.g. options['children']['posterImage'] = false
1234           if (opts === false) {
1235             return;
1236           }
1238           // Allow options to be passed as a simple boolean if no configuration
1239           // is necessary.
1240           if (opts === true) {
1241             opts = {};
1242           }
1244           // We also want to pass the original player options
1245           // to each component as well so they don't need to
1246           // reach back into the player for options later.
1247           opts.playerOptions = _this.options_.playerOptions;
1249           // Create and add the child component.
1250           // Add a direct reference to the child by name on the parent instance.
1251           // If two of the same component are used, different names should be supplied
1252           // for each
1253           var newChild = _this.addChild(name, opts);
1255           if (newChild) {
1256             _this[name] = newChild;
1257           }
1258         };
1260         // Allow for an array of children details to passed in the options
1261         var workingChildren = void 0;
1262         var Tech = Component.getComponent('Tech');
1264         if (Array.isArray(children)) {
1265           workingChildren = children;
1266         } else {
1267           workingChildren = Object.keys(children);
1268         }
1270         workingChildren
1271         // children that are in this.options_ but also in workingChildren  would
1272         // give us extra children we do not want. So, we want to filter them out.
1273         .concat(Object.keys(_this.options_).filter(function (child) {
1274           return !workingChildren.some(function (wchild) {
1275             if (typeof wchild === 'string') {
1276               return child === wchild;
1277             }
1278             return child === wchild.name;
1279           });
1280         })).map(function (child) {
1281           var name = void 0;
1282           var opts = void 0;
1284           if (typeof child === 'string') {
1285             name = child;
1286             opts = children[name] || _this.options_[name] || {};
1287           } else {
1288             name = child.name;
1289             opts = child;
1290           }
1292           return { name: name, opts: opts };
1293         }).filter(function (child) {
1294           // we have to make sure that child.name isn't in the techOrder since
1295           // techs are registered as Components but can't aren't compatible
1296           // See https://github.com/videojs/video.js/issues/2772
1297           var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
1299           return c && !Tech.isTech(c);
1300         }).forEach(handleAdd);
1301       })();
1302     }
1303   };
1305   /**
1306    * Builds the default DOM class name. Should be overridden by sub-components.
1307    *
1308    * @return {string}
1309    *         The DOM class name for this object.
1310    *
1311    * @abstract
1312    */
1315   Component.prototype.buildCSSClass = function buildCSSClass() {
1316     // Child classes can include a function that does:
1317     // return 'CLASS NAME' + this._super();
1318     return '';
1319   };
1321   /**
1322    * Add an `event listener` to this `Component`s element.
1323    *
1324    * The benefit of using this over the following:
1325    * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
1326    * - `otherComponent.on('eventName', myFunc)`
1327    *
1328    * 1. Is that the listeners will get cleaned up when either component gets disposed.
1329    * 1. It will also bind `myComponent` as the context of `myFunc`.
1330    * > NOTE: If you remove the element from the DOM that has used `on` you need to
1331    *         clean up references using: `myComponent.trigger(el, 'dispose')`
1332    *         This will also allow the browser to garbage collect it. In special
1333    *         cases such as with `window` and `document`, which are both permanent,
1334    *         this is not necessary.
1335    *
1336    * @param {string|Component|string[]} [first]
1337    *        The event name, and array of event names, or another `Component`.
1338    *
1339    * @param {EventTarget~EventListener|string|string[]} [second]
1340    *        The listener function, an event name, or an Array of events names.
1341    *
1342    * @param {EventTarget~EventListener} [third]
1343    *        The event handler if `first` is a `Component` and `second` is an event name
1344    *        or an Array of event names.
1345    *
1346    * @return {Component}
1347    *         Returns itself; method can be chained.
1348    *
1349    * @listens Component#dispose
1350    */
1353   Component.prototype.on = function on(first, second, third) {
1354     var _this2 = this;
1356     if (typeof first === 'string' || Array.isArray(first)) {
1357       Events.on(this.el_, first, Fn.bind(this, second));
1359       // Targeting another component or element
1360     } else {
1361       (function () {
1362         var target = first;
1363         var type = second;
1364         var fn = Fn.bind(_this2, third);
1366         // When this component is disposed, remove the listener from the other component
1367         var removeOnDispose = function removeOnDispose() {
1368           return _this2.off(target, type, fn);
1369         };
1371         // Use the same function ID so we can remove it later it using the ID
1372         // of the original listener
1373         removeOnDispose.guid = fn.guid;
1374         _this2.on('dispose', removeOnDispose);
1376         // If the other component is disposed first we need to clean the reference
1377         // to the other component in this component's removeOnDispose listener
1378         // Otherwise we create a memory leak.
1379         var cleanRemover = function cleanRemover() {
1380           return _this2.off('dispose', removeOnDispose);
1381         };
1383         // Add the same function ID so we can easily remove it later
1384         cleanRemover.guid = fn.guid;
1386         // Check if this is a DOM node
1387         if (first.nodeName) {
1388           // Add the listener to the other element
1389           Events.on(target, type, fn);
1390           Events.on(target, 'dispose', cleanRemover);
1392           // Should be a component
1393           // Not using `instanceof Component` because it makes mock players difficult
1394         } else if (typeof first.on === 'function') {
1395           // Add the listener to the other component
1396           target.on(type, fn);
1397           target.on('dispose', cleanRemover);
1398         }
1399       })();
1400     }
1402     return this;
1403   };
1405   /**
1406    * Remove an event listener from this `Component`s element. If the second argument is
1407    * excluded all listeners for the type passed in as the first argument will be removed.
1408    *
1409    * @param {string|Component|string[]} [first]
1410    *        The event name, and array of event names, or another `Component`.
1411    *
1412    * @param {EventTarget~EventListener|string|string[]} [second]
1413    *        The listener function, an event name, or an Array of events names.
1414    *
1415    * @param {EventTarget~EventListener} [third]
1416    *        The event handler if `first` is a `Component` and `second` is an event name
1417    *        or an Array of event names.
1418    *
1419    * @return {Component}
1420    *         Returns itself; method can be chained.
1421    */
1424   Component.prototype.off = function off(first, second, third) {
1425     if (!first || typeof first === 'string' || Array.isArray(first)) {
1426       Events.off(this.el_, first, second);
1427     } else {
1428       var target = first;
1429       var type = second;
1430       // Ensure there's at least a guid, even if the function hasn't been used
1431       var fn = Fn.bind(this, third);
1433       // Remove the dispose listener on this component,
1434       // which was given the same guid as the event listener
1435       this.off('dispose', fn);
1437       if (first.nodeName) {
1438         // Remove the listener
1439         Events.off(target, type, fn);
1440         // Remove the listener for cleaning the dispose listener
1441         Events.off(target, 'dispose', fn);
1442       } else {
1443         target.off(type, fn);
1444         target.off('dispose', fn);
1445       }
1446     }
1448     return this;
1449   };
1451   /**
1452    * Add an event listener that gets triggered only once and then gets removed.
1453    *
1454    * @param {string|Component|string[]} [first]
1455    *        The event name, and array of event names, or another `Component`.
1456    *
1457    * @param {EventTarget~EventListener|string|string[]} [second]
1458    *        The listener function, an event name, or an Array of events names.
1459    *
1460    * @param {EventTarget~EventListener} [third]
1461    *        The event handler if `first` is a `Component` and `second` is an event name
1462    *        or an Array of event names.
1463    *
1464    * @return {Component}
1465    *         Returns itself; method can be chained.
1466    */
1469   Component.prototype.one = function one(first, second, third) {
1470     var _this3 = this,
1471         _arguments = arguments;
1473     if (typeof first === 'string' || Array.isArray(first)) {
1474       Events.one(this.el_, first, Fn.bind(this, second));
1475     } else {
1476       (function () {
1477         var target = first;
1478         var type = second;
1479         var fn = Fn.bind(_this3, third);
1481         var newFunc = function newFunc() {
1482           _this3.off(target, type, newFunc);
1483           fn.apply(null, _arguments);
1484         };
1486         // Keep the same function ID so we can remove it later
1487         newFunc.guid = fn.guid;
1489         _this3.on(target, type, newFunc);
1490       })();
1491     }
1493     return this;
1494   };
1496   /**
1497    * Trigger an event on an element.
1498    *
1499    * @param {EventTarget~Event|Object|string} event
1500    *        The event name, and Event, or an event-like object with a type attribute
1501    *        set to the event name.
1502    *
1503    * @param {Object} [hash]
1504    *        Data hash to pass along with the event
1505    *
1506    * @return {Component}
1507    *         Returns itself; method can be chained.
1508    */
1511   Component.prototype.trigger = function trigger(event, hash) {
1512     Events.trigger(this.el_, event, hash);
1513     return this;
1514   };
1516   /**
1517    * Bind a listener to the component's ready state. If the ready event has already
1518    * happened it will trigger the function immediately.
1519    *
1520    * @param  {Component~ReadyCallback} fn
1521    *         A function to call when ready is triggered.
1522    *
1523    * @param  {boolean} [sync=false]
1524    *         Execute the listener synchronously if `Component` is ready.
1525    *
1526    * @return {Component}
1527    *         Returns itself; method can be chained.
1528    */
1531   Component.prototype.ready = function ready(fn) {
1532     var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1534     if (fn) {
1535       if (this.isReady_) {
1536         if (sync) {
1537           fn.call(this);
1538         } else {
1539           // Call the function asynchronously by default for consistency
1540           this.setTimeout(fn, 1);
1541         }
1542       } else {
1543         this.readyQueue_ = this.readyQueue_ || [];
1544         this.readyQueue_.push(fn);
1545       }
1546     }
1547     return this;
1548   };
1550   /**
1551    * Trigger all the ready listeners for this `Component`.
1552    *
1553    * @fires Component#ready
1554    */
1557   Component.prototype.triggerReady = function triggerReady() {
1558     this.isReady_ = true;
1560     // Ensure ready is triggered asynchronously
1561     this.setTimeout(function () {
1562       var readyQueue = this.readyQueue_;
1564       // Reset Ready Queue
1565       this.readyQueue_ = [];
1567       if (readyQueue && readyQueue.length > 0) {
1568         readyQueue.forEach(function (fn) {
1569           fn.call(this);
1570         }, this);
1571       }
1573       // Allow for using event listeners also
1574       /**
1575        * Triggered when a `Component` is ready.
1576        *
1577        * @event Component#ready
1578        * @type {EventTarget~Event}
1579        */
1580       this.trigger('ready');
1581     }, 1);
1582   };
1584   /**
1585    * Find a single DOM element matching a `selector`. This can be within the `Component`s
1586    * `contentEl()` or another custom context.
1587    *
1588    * @param {string} selector
1589    *        A valid CSS selector, which will be passed to `querySelector`.
1590    *
1591    * @param {Element|string} [context=this.contentEl()]
1592    *        A DOM element within which to query. Can also be a selector string in
1593    *        which case the first matching element will get used as context. If
1594    *        missing `this.contentEl()` gets used. If  `this.contentEl()` returns
1595    *        nothing it falls back to `document`.
1596    *
1597    * @return {Element|null}
1598    *         the dom element that was found, or null
1599    *
1600    * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1601    */
1604   Component.prototype.$ = function $(selector, context) {
1605     return Dom.$(selector, context || this.contentEl());
1606   };
1608   /**
1609    * Finds all DOM element matching a `selector`. This can be within the `Component`s
1610    * `contentEl()` or another custom context.
1611    *
1612    * @param {string} selector
1613    *        A valid CSS selector, which will be passed to `querySelectorAll`.
1614    *
1615    * @param {Element|string} [context=this.contentEl()]
1616    *        A DOM element within which to query. Can also be a selector string in
1617    *        which case the first matching element will get used as context. If
1618    *        missing `this.contentEl()` gets used. If  `this.contentEl()` returns
1619    *        nothing it falls back to `document`.
1620    *
1621    * @return {NodeList}
1622    *         a list of dom elements that were found
1623    *
1624    * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1625    */
1628   Component.prototype.$$ = function $$(selector, context) {
1629     return Dom.$$(selector, context || this.contentEl());
1630   };
1632   /**
1633    * Check if a component's element has a CSS class name.
1634    *
1635    * @param {string} classToCheck
1636    *        CSS class name to check.
1637    *
1638    * @return {boolean}
1639    *         - True if the `Component` has the class.
1640    *         - False if the `Component` does not have the class`
1641    */
1644   Component.prototype.hasClass = function hasClass(classToCheck) {
1645     return Dom.hasElClass(this.el_, classToCheck);
1646   };
1648   /**
1649    * Add a CSS class name to the `Component`s element.
1650    *
1651    * @param {string} classToAdd
1652    *        CSS class name to add
1653    *
1654    * @return {Component}
1655    *         Returns itself; method can be chained.
1656    */
1659   Component.prototype.addClass = function addClass(classToAdd) {
1660     Dom.addElClass(this.el_, classToAdd);
1661     return this;
1662   };
1664   /**
1665    * Remove a CSS class name from the `Component`s element.
1666    *
1667    * @param {string} classToRemove
1668    *        CSS class name to remove
1669    *
1670    * @return {Component}
1671    *         Returns itself; method can be chained.
1672    */
1675   Component.prototype.removeClass = function removeClass(classToRemove) {
1676     Dom.removeElClass(this.el_, classToRemove);
1677     return this;
1678   };
1680   /**
1681    * Add or remove a CSS class name from the component's element.
1682    * - `classToToggle` gets added when {@link Component#hasClass} would return false.
1683    * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
1684    *
1685    * @param  {string} classToToggle
1686    *         The class to add or remove based on (@link Component#hasClass}
1687    *
1688    * @param  {boolean|Dom~predicate} [predicate]
1689    *         An {@link Dom~predicate} function or a boolean
1690    *
1691    * @return {Component}
1692    *         Returns itself; method can be chained.
1693    */
1696   Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
1697     Dom.toggleElClass(this.el_, classToToggle, predicate);
1698     return this;
1699   };
1701   /**
1702    * Show the `Component`s element if it is hidden by removing the
1703    * 'vjs-hidden' class name from it.
1704    *
1705    * @return {Component}
1706    *         Returns itself; method can be chained.
1707    */
1710   Component.prototype.show = function show() {
1711     this.removeClass('vjs-hidden');
1712     return this;
1713   };
1715   /**
1716    * Hide the `Component`s element if it is currently showing by adding the
1717    * 'vjs-hidden` class name to it.
1718    *
1719    * @return {Component}
1720    *         Returns itself; method can be chained.
1721    */
1724   Component.prototype.hide = function hide() {
1725     this.addClass('vjs-hidden');
1726     return this;
1727   };
1729   /**
1730    * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
1731    * class name to it. Used during fadeIn/fadeOut.
1732    *
1733    * @return {Component}
1734    *         Returns itself; method can be chained.
1735    *
1736    * @private
1737    */
1740   Component.prototype.lockShowing = function lockShowing() {
1741     this.addClass('vjs-lock-showing');
1742     return this;
1743   };
1745   /**
1746    * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
1747    * class name from it. Used during fadeIn/fadeOut.
1748    *
1749    * @return {Component}
1750    *         Returns itself; method can be chained.
1751    *
1752    * @private
1753    */
1756   Component.prototype.unlockShowing = function unlockShowing() {
1757     this.removeClass('vjs-lock-showing');
1758     return this;
1759   };
1761   /**
1762    * Get the value of an attribute on the `Component`s element.
1763    *
1764    * @param {string} attribute
1765    *        Name of the attribute to get the value from.
1766    *
1767    * @return {string|null}
1768    *         - The value of the attribute that was asked for.
1769    *         - Can be an empty string on some browsers if the attribute does not exist
1770    *           or has no value
1771    *         - Most browsers will return null if the attribute does not exist or has
1772    *           no value.
1773    *
1774    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
1775    */
1778   Component.prototype.getAttribute = function getAttribute(attribute) {
1779     return Dom.getAttribute(this.el_, attribute);
1780   };
1782   /**
1783    * Set the value of an attribute on the `Component`'s element
1784    *
1785    * @param {string} attribute
1786    *        Name of the attribute to set.
1787    *
1788    * @param {string} value
1789    *        Value to set the attribute to.
1790    *
1791    * @return {Component}
1792    *         Returns itself; method can be chained.
1793    *
1794    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
1795    */
1798   Component.prototype.setAttribute = function setAttribute(attribute, value) {
1799     Dom.setAttribute(this.el_, attribute, value);
1800     return this;
1801   };
1803   /**
1804    * Remove an attribute from the `Component`s element.
1805    *
1806    * @param {string} attribute
1807    *        Name of the attribute to remove.
1808    *
1809    * @return {Component}
1810    *         Returns itself; method can be chained.
1811    *
1812    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
1813    */
1816   Component.prototype.removeAttribute = function removeAttribute(attribute) {
1817     Dom.removeAttribute(this.el_, attribute);
1818     return this;
1819   };
1821   /**
1822    * Get or set the width of the component based upon the CSS styles.
1823    * See {@link Component#dimension} for more detailed information.
1824    *
1825    * @param {number|string} [num]
1826    *        The width that you want to set postfixed with '%', 'px' or nothing.
1827    *
1828    * @param {boolean} [skipListeners]
1829    *        Skip the resize event trigger
1830    *
1831    * @return {Component|number|string}
1832    *         - The width when getting, zero if there is no width. Can be a string
1833    *           postpixed with '%' or 'px'.
1834    *         - Returns itself when setting; method can be chained.
1835    */
1838   Component.prototype.width = function width(num, skipListeners) {
1839     return this.dimension('width', num, skipListeners);
1840   };
1842   /**
1843    * Get or set the height of the component based upon the CSS styles.
1844    * See {@link Component#dimension} for more detailed information.
1845    *
1846    * @param {number|string} [num]
1847    *        The height that you want to set postfixed with '%', 'px' or nothing.
1848    *
1849    * @param {boolean} [skipListeners]
1850    *        Skip the resize event trigger
1851    *
1852    * @return {Component|number|string}
1853    *         - The width when getting, zero if there is no width. Can be a string
1854    *           postpixed with '%' or 'px'.
1855    *         - Returns itself when setting; method can be chained.
1856    */
1859   Component.prototype.height = function height(num, skipListeners) {
1860     return this.dimension('height', num, skipListeners);
1861   };
1863   /**
1864    * Set both the width and height of the `Component` element at the same time.
1865    *
1866    * @param  {number|string} width
1867    *         Width to set the `Component`s element to.
1868    *
1869    * @param  {number|string} height
1870    *         Height to set the `Component`s element to.
1871    *
1872    * @return {Component}
1873    *         Returns itself; method can be chained.
1874    */
1877   Component.prototype.dimensions = function dimensions(width, height) {
1878     // Skip resize listeners on width for optimization
1879     return this.width(width, true).height(height);
1880   };
1882   /**
1883    * Get or set width or height of the `Component` element. This is the shared code
1884    * for the {@link Component#width} and {@link Component#height}.
1885    *
1886    * Things to know:
1887    * - If the width or height in an number this will return the number postfixed with 'px'.
1888    * - If the width/height is a percent this will return the percent postfixed with '%'
1889    * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
1890    *   defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
1891    *   See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
1892    *   for more information
1893    * - If you want the computed style of the component, use {@link Component#currentWidth}
1894    *   and {@link {Component#currentHeight}
1895    *
1896    * @fires Component#resize
1897    *
1898    * @param {string} widthOrHeight
1899    8        'width' or 'height'
1900    *
1901    * @param  {number|string} [num]
1902    8         New dimension
1903    *
1904    * @param  {boolean} [skipListeners]
1905    *         Skip resize event trigger
1906    *
1907    * @return {Component}
1908    *         - the dimension when getting or 0 if unset
1909    *         - Returns itself when setting; method can be chained.
1910    */
1913   Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
1914     if (num !== undefined) {
1915       // Set to zero if null or literally NaN (NaN !== NaN)
1916       if (num === null || num !== num) {
1917         num = 0;
1918       }
1920       // Check if using css width/height (% or px) and adjust
1921       if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
1922         this.el_.style[widthOrHeight] = num;
1923       } else if (num === 'auto') {
1924         this.el_.style[widthOrHeight] = '';
1925       } else {
1926         this.el_.style[widthOrHeight] = num + 'px';
1927       }
1929       // skipListeners allows us to avoid triggering the resize event when setting both width and height
1930       if (!skipListeners) {
1931         /**
1932          * Triggered when a component is resized.
1933          *
1934          * @event Component#resize
1935          * @type {EventTarget~Event}
1936          */
1937         this.trigger('resize');
1938       }
1940       // Return component
1941       return this;
1942     }
1944     // Not setting a value, so getting it
1945     // Make sure element exists
1946     if (!this.el_) {
1947       return 0;
1948     }
1950     // Get dimension value from style
1951     var val = this.el_.style[widthOrHeight];
1952     var pxIndex = val.indexOf('px');
1954     if (pxIndex !== -1) {
1955       // Return the pixel value with no 'px'
1956       return parseInt(val.slice(0, pxIndex), 10);
1957     }
1959     // No px so using % or no style was set, so falling back to offsetWidth/height
1960     // If component has display:none, offset will return 0
1961     // TODO: handle display:none and no dimension style using px
1962     return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
1963   };
1965   /**
1966    * Get the width or the height of the `Component` elements computed style. Uses
1967    * `window.getComputedStyle`.
1968    *
1969    * @param {string} widthOrHeight
1970    *        A string containing 'width' or 'height'. Whichever one you want to get.
1971    *
1972    * @return {number}
1973    *         The dimension that gets asked for or 0 if nothing was set
1974    *         for that dimension.
1975    */
1978   Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
1979     var computedWidthOrHeight = 0;
1981     if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
1982       throw new Error('currentDimension only accepts width or height value');
1983     }
1985     if (typeof _window2['default'].getComputedStyle === 'function') {
1986       var computedStyle = _window2['default'].getComputedStyle(this.el_);
1988       computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
1989     }
1991     // remove 'px' from variable and parse as integer
1992     computedWidthOrHeight = parseFloat(computedWidthOrHeight);
1994     // if the computed value is still 0, it's possible that the browser is lying
1995     // and we want to check the offset values.
1996     // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
1997     if (computedWidthOrHeight === 0) {
1998       var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
2000       computedWidthOrHeight = this.el_[rule];
2001     }
2003     return computedWidthOrHeight;
2004   };
2006   /**
2007    * An object that contains width and height values of the `Component`s
2008    * computed style. Uses `window.getComputedStyle`.
2009    *
2010    * @typedef {Object} Component~DimensionObject
2011    *
2012    * @property {number} width
2013    *           The width of the `Component`s computed style.
2014    *
2015    * @property {number} height
2016    *           The height of the `Component`s computed style.
2017    */
2019   /**
2020    * Get an object that contains width and height values of the `Component`s
2021    * computed style.
2022    *
2023    * @return {Component~DimensionObject}
2024    *         The dimensions of the components element
2025    */
2028   Component.prototype.currentDimensions = function currentDimensions() {
2029     return {
2030       width: this.currentDimension('width'),
2031       height: this.currentDimension('height')
2032     };
2033   };
2035   /**
2036    * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
2037    *
2038    * @return {number} width
2039    *           The width of the `Component`s computed style.
2040    */
2043   Component.prototype.currentWidth = function currentWidth() {
2044     return this.currentDimension('width');
2045   };
2047   /**
2048    * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
2049    *
2050    * @return {number} height
2051    *           The height of the `Component`s computed style.
2052    */
2055   Component.prototype.currentHeight = function currentHeight() {
2056     return this.currentDimension('height');
2057   };
2059   /**
2060    * Emit a 'tap' events when touch event support gets detected. This gets used to
2061    * support toggling the controls through a tap on the video. They get enabled
2062    * because every sub-component would have extra overhead otherwise.
2063    *
2064    * @private
2065    * @fires Component#tap
2066    * @listens Component#touchstart
2067    * @listens Component#touchmove
2068    * @listens Component#touchleave
2069    * @listens Component#touchcancel
2070    * @listens Component#touchend
2071     */
2074   Component.prototype.emitTapEvents = function emitTapEvents() {
2075     // Track the start time so we can determine how long the touch lasted
2076     var touchStart = 0;
2077     var firstTouch = null;
2079     // Maximum movement allowed during a touch event to still be considered a tap
2080     // Other popular libs use anywhere from 2 (hammer.js) to 15,
2081     // so 10 seems like a nice, round number.
2082     var tapMovementThreshold = 10;
2084     // The maximum length a touch can be while still being considered a tap
2085     var touchTimeThreshold = 200;
2087     var couldBeTap = void 0;
2089     this.on('touchstart', function (event) {
2090       // If more than one finger, don't consider treating this as a click
2091       if (event.touches.length === 1) {
2092         // Copy pageX/pageY from the object
2093         firstTouch = {
2094           pageX: event.touches[0].pageX,
2095           pageY: event.touches[0].pageY
2096         };
2097         // Record start time so we can detect a tap vs. "touch and hold"
2098         touchStart = new Date().getTime();
2099         // Reset couldBeTap tracking
2100         couldBeTap = true;
2101       }
2102     });
2104     this.on('touchmove', function (event) {
2105       // If more than one finger, don't consider treating this as a click
2106       if (event.touches.length > 1) {
2107         couldBeTap = false;
2108       } else if (firstTouch) {
2109         // Some devices will throw touchmoves for all but the slightest of taps.
2110         // So, if we moved only a small distance, this could still be a tap
2111         var xdiff = event.touches[0].pageX - firstTouch.pageX;
2112         var ydiff = event.touches[0].pageY - firstTouch.pageY;
2113         var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
2115         if (touchDistance > tapMovementThreshold) {
2116           couldBeTap = false;
2117         }
2118       }
2119     });
2121     var noTap = function noTap() {
2122       couldBeTap = false;
2123     };
2125     // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
2126     this.on('touchleave', noTap);
2127     this.on('touchcancel', noTap);
2129     // When the touch ends, measure how long it took and trigger the appropriate
2130     // event
2131     this.on('touchend', function (event) {
2132       firstTouch = null;
2133       // Proceed only if the touchmove/leave/cancel event didn't happen
2134       if (couldBeTap === true) {
2135         // Measure how long the touch lasted
2136         var touchTime = new Date().getTime() - touchStart;
2138         // Make sure the touch was less than the threshold to be considered a tap
2139         if (touchTime < touchTimeThreshold) {
2140           // Don't let browser turn this into a click
2141           event.preventDefault();
2142           /**
2143            * Triggered when a `Component` is tapped.
2144            *
2145            * @event Component#tap
2146            * @type {EventTarget~Event}
2147            */
2148           this.trigger('tap');
2149           // It may be good to copy the touchend event object and change the
2150           // type to tap, if the other event properties aren't exact after
2151           // Events.fixEvent runs (e.g. event.target)
2152         }
2153       }
2154     });
2155   };
2157   /**
2158    * This function reports user activity whenever touch events happen. This can get
2159    * turned off by any sub-components that wants touch events to act another way.
2160    *
2161    * Report user touch activity when touch events occur. User activity gets used to
2162    * determine when controls should show/hide. It is simple when it comes to mouse
2163    * events, because any mouse event should show the controls. So we capture mouse
2164    * events that bubble up to the player and report activity when that happens.
2165    * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
2166    * controls. So touch events can't help us at the player level either.
2167    *
2168    * User activity gets checked asynchronously. So what could happen is a tap event
2169    * on the video turns the controls off. Then the `touchend` event bubbles up to
2170    * the player. Which, if it reported user activity, would turn the controls right
2171    * back on. We also don't want to completely block touch events from bubbling up.
2172    * Furthermore a `touchmove` event and anything other than a tap, should not turn
2173    * controls back on.
2174    *
2175    * @listens Component#touchstart
2176    * @listens Component#touchmove
2177    * @listens Component#touchend
2178    * @listens Component#touchcancel
2179    */
2182   Component.prototype.enableTouchActivity = function enableTouchActivity() {
2183     // Don't continue if the root player doesn't support reporting user activity
2184     if (!this.player() || !this.player().reportUserActivity) {
2185       return;
2186     }
2188     // listener for reporting that the user is active
2189     var report = Fn.bind(this.player(), this.player().reportUserActivity);
2191     var touchHolding = void 0;
2193     this.on('touchstart', function () {
2194       report();
2195       // For as long as the they are touching the device or have their mouse down,
2196       // we consider them active even if they're not moving their finger or mouse.
2197       // So we want to continue to update that they are active
2198       this.clearInterval(touchHolding);
2199       // report at the same interval as activityCheck
2200       touchHolding = this.setInterval(report, 250);
2201     });
2203     var touchEnd = function touchEnd(event) {
2204       report();
2205       // stop the interval that maintains activity if the touch is holding
2206       this.clearInterval(touchHolding);
2207     };
2209     this.on('touchmove', report);
2210     this.on('touchend', touchEnd);
2211     this.on('touchcancel', touchEnd);
2212   };
2214   /**
2215    * A callback that has no parameters and is bound into `Component`s context.
2216    *
2217    * @callback Component~GenericCallback
2218    * @this Component
2219    */
2221   /**
2222    * Creates a function that runs after an `x` millisecond timeout. This function is a
2223    * wrapper around `window.setTimeout`. There are a few reasons to use this one
2224    * instead though:
2225    * 1. It gets cleared via  {@link Component#clearTimeout} when
2226    *    {@link Component#dispose} gets called.
2227    * 2. The function callback will gets turned into a {@link Component~GenericCallback}
2228    *
2229    * > Note: You can use `window.clearTimeout` on the id returned by this function. This
2230    *         will cause its dispose listener not to get cleaned up! Please use
2231    *         {@link Component#clearTimeout} or {@link Component#dispose}.
2232    *
2233    * @param {Component~GenericCallback} fn
2234    *        The function that will be run after `timeout`.
2235    *
2236    * @param {number} timeout
2237    *        Timeout in milliseconds to delay before executing the specified function.
2238    *
2239    * @return {number}
2240    *         Returns a timeout ID that gets used to identify the timeout. It can also
2241    *         get used in {@link Component#clearTimeout} to clear the timeout that
2242    *         was set.
2243    *
2244    * @listens Component#dispose
2245    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
2246    */
2249   Component.prototype.setTimeout = function setTimeout(fn, timeout) {
2250     fn = Fn.bind(this, fn);
2252     var timeoutId = _window2['default'].setTimeout(fn, timeout);
2253     var disposeFn = function disposeFn() {
2254       this.clearTimeout(timeoutId);
2255     };
2257     disposeFn.guid = 'vjs-timeout-' + timeoutId;
2259     this.on('dispose', disposeFn);
2261     return timeoutId;
2262   };
2264   /**
2265    * Clears a timeout that gets created via `window.setTimeout` or
2266    * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
2267    * use this function instead of `window.clearTimeout`. If you don't your dispose
2268    * listener will not get cleaned up until {@link Component#dispose}!
2269    *
2270    * @param {number} timeoutId
2271    *        The id of the timeout to clear. The return value of
2272    *        {@link Component#setTimeout} or `window.setTimeout`.
2273    *
2274    * @return {number}
2275    *         Returns the timeout id that was cleared.
2276    *
2277    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
2278    */
2281   Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
2282     _window2['default'].clearTimeout(timeoutId);
2284     var disposeFn = function disposeFn() {};
2286     disposeFn.guid = 'vjs-timeout-' + timeoutId;
2288     this.off('dispose', disposeFn);
2290     return timeoutId;
2291   };
2293   /**
2294    * Creates a function that gets run every `x` milliseconds. This function is a wrapper
2295    * around `window.setInterval`. There are a few reasons to use this one instead though.
2296    * 1. It gets cleared via  {@link Component#clearInterval} when
2297    *    {@link Component#dispose} gets called.
2298    * 2. The function callback will be a {@link Component~GenericCallback}
2299    *
2300    * @param {Component~GenericCallback} fn
2301    *        The function to run every `x` seconds.
2302    *
2303    * @param {number} interval
2304    *        Execute the specified function every `x` milliseconds.
2305    *
2306    * @return {number}
2307    *         Returns an id that can be used to identify the interval. It can also be be used in
2308    *         {@link Component#clearInterval} to clear the interval.
2309    *
2310    * @listens Component#dispose
2311    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
2312    */
2315   Component.prototype.setInterval = function setInterval(fn, interval) {
2316     fn = Fn.bind(this, fn);
2318     var intervalId = _window2['default'].setInterval(fn, interval);
2320     var disposeFn = function disposeFn() {
2321       this.clearInterval(intervalId);
2322     };
2324     disposeFn.guid = 'vjs-interval-' + intervalId;
2326     this.on('dispose', disposeFn);
2328     return intervalId;
2329   };
2331   /**
2332    * Clears an interval that gets created via `window.setInterval` or
2333    * {@link Component#setInterval}. If you set an interval via {@link Component#setInterval}
2334    * use this function instead of `window.clearInterval`. If you don't your dispose
2335    * listener will not get cleaned up until {@link Component#dispose}!
2336    *
2337    * @param {number} intervalId
2338    *        The id of the interval to clear. The return value of
2339    *        {@link Component#setInterval} or `window.setInterval`.
2340    *
2341    * @return {number}
2342    *         Returns the interval id that was cleared.
2343    *
2344    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
2345    */
2348   Component.prototype.clearInterval = function clearInterval(intervalId) {
2349     _window2['default'].clearInterval(intervalId);
2351     var disposeFn = function disposeFn() {};
2353     disposeFn.guid = 'vjs-interval-' + intervalId;
2355     this.off('dispose', disposeFn);
2357     return intervalId;
2358   };
2360   /**
2361    * Register a `Component` with `videojs` given the name and the component.
2362    *
2363    * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
2364    *         should be registered using {@link Tech.registerTech} or
2365    *         {@link videojs:videojs.registerTech}.
2366    *
2367    * > NOTE: This function can also be seen on videojs as
2368    *         {@link videojs:videojs.registerComponent}.
2369    *
2370    * @param {string} name
2371    *        The name of the `Component` to register.
2372    *
2373    * @param {Component} comp
2374    *        The `Component` class to register.
2375    *
2376    * @return {Component}
2377    *         The `Component` that was registered.
2378    */
2381   Component.registerComponent = function registerComponent(name, comp) {
2382     if (!name) {
2383       return;
2384     }
2386     name = (0, _toTitleCase2['default'])(name);
2388     if (!Component.components_) {
2389       Component.components_ = {};
2390     }
2392     if (name === 'Player' && Component.components_[name]) {
2393       (function () {
2394         var Player = Component.components_[name];
2396         // If we have players that were disposed, then their name will still be
2397         // in Players.players. So, we must loop through and verify that the value
2398         // for each item is not null. This allows registration of the Player component
2399         // after all players have been disposed or before any were created.
2400         if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) {
2401           return Player.players[playerName];
2402         }).every(Boolean)) {
2403           throw new Error('Can not register Player component after player has been created');
2404         }
2405       })();
2406     }
2408     Component.components_[name] = comp;
2410     return comp;
2411   };
2413   /**
2414    * Get a `Component` based on the name it was registered with.
2415    *
2416    * @param {string} name
2417    *        The Name of the component to get.
2418    *
2419    * @return {Component}
2420    *         The `Component` that got registered under the given name.
2421    *
2422    * @deprecated In `videojs` 6 this will not return `Component`s that were not
2423    *             registered using {@link Component.registerComponent}. Currently we
2424    *             check the global `videojs` object for a `Component` name and
2425    *             return that if it exists.
2426    */
2429   Component.getComponent = function getComponent(name) {
2430     if (!name) {
2431       return;
2432     }
2434     name = (0, _toTitleCase2['default'])(name);
2436     if (Component.components_ && Component.components_[name]) {
2437       return Component.components_[name];
2438     }
2440     if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
2441       _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
2443       return _window2['default'].videojs[name];
2444     }
2445   };
2447   /**
2448    * Sets up the constructor using the supplied init method or uses the init of the
2449    * parent object.
2450    *
2451    * @param {Object} [props={}]
2452    *        An object of properties.
2453    *
2454    * @return {Object}
2455    *         the extended object.
2456    *
2457    * @deprecated since version 5
2458    */
2461   Component.extend = function extend(props) {
2462     props = props || {};
2464     _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead');
2466     // Set up the constructor using the supplied init method
2467     // or using the init of the parent object
2468     // Make sure to check the unobfuscated version for external libs
2469     var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
2470     // In Resig's simple class inheritance (previously used) the constructor
2471     //  is a function that calls `this.init.apply(arguments)`
2472     // However that would prevent us from using `ParentObject.call(this);`
2473     //  in a Child constructor because the `this` in `this.init`
2474     //  would still refer to the Child and cause an infinite loop.
2475     // We would instead have to do
2476     //    `ParentObject.prototype.init.apply(this, arguments);`
2477     //  Bleh. We're not creating a _super() function, so it's good to keep
2478     //  the parent constructor reference simple.
2479     var subObj = function subObj() {
2480       init.apply(this, arguments);
2481     };
2483     // Inherit from this object's prototype
2484     subObj.prototype = Object.create(this.prototype);
2485     // Reset the constructor property for subObj otherwise
2486     // instances of subObj would have the constructor of the parent Object
2487     subObj.prototype.constructor = subObj;
2489     // Make the class extendable
2490     subObj.extend = Component.extend;
2492     // Extend subObj's prototype with functions and other properties from props
2493     for (var name in props) {
2494       if (props.hasOwnProperty(name)) {
2495         subObj.prototype[name] = props[name];
2496       }
2497     }
2499     return subObj;
2500   };
2502   return Component;
2503 }();
2505 Component.registerComponent('Component', Component);
2506 exports['default'] = Component;
2508 },{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){
2509 'use strict';
2511 exports.__esModule = true;
2513 var _trackButton = _dereq_(36);
2515 var _trackButton2 = _interopRequireDefault(_trackButton);
2517 var _component = _dereq_(5);
2519 var _component2 = _interopRequireDefault(_component);
2521 var _audioTrackMenuItem = _dereq_(7);
2523 var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
2525 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2527 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2529 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2531 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2532                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-button.js
2533                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2537  * The base class for buttons that toggle specific {@link AudioTrack} types.
2539  * @extends TrackButton
2540  */
2541 var AudioTrackButton = function (_TrackButton) {
2542   _inherits(AudioTrackButton, _TrackButton);
2544   /**
2545    * Creates an instance of this class.
2546    *
2547    * @param {Player} player
2548    *        The `Player` that this class should be attached to.
2549    *
2550    * @param {Object} [options={}]
2551    *        The key/value store of player options.
2552    */
2553   function AudioTrackButton(player) {
2554     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2556     _classCallCheck(this, AudioTrackButton);
2558     options.tracks = player.audioTracks && player.audioTracks();
2560     var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
2562     _this.el_.setAttribute('aria-label', 'Audio Menu');
2563     return _this;
2564   }
2566   /**
2567    * Builds the default DOM `className`.
2568    *
2569    * @return {string}
2570    *         The DOM `className` for this object.
2571    */
2574   AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
2575     return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
2576   };
2578   /**
2579    * Create a menu item for each audio track
2580    *
2581    * @param {AudioTrackMenuItem[]} [items=[]]
2582    *        An array of existing menu items to use.
2583    *
2584    * @return {AudioTrackMenuItem[]}
2585    *         An array of menu items
2586    */
2589   AudioTrackButton.prototype.createItems = function createItems() {
2590     var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
2592     var tracks = this.player_.audioTracks && this.player_.audioTracks();
2594     if (!tracks) {
2595       return items;
2596     }
2598     for (var i = 0; i < tracks.length; i++) {
2599       var track = tracks[i];
2601       items.push(new _audioTrackMenuItem2['default'](this.player_, {
2602         track: track,
2603         // MenuItem is selectable
2604         selectable: true
2605       }));
2606     }
2608     return items;
2609   };
2611   return AudioTrackButton;
2612 }(_trackButton2['default']);
2615  * The text that should display over the `AudioTrackButton`s controls. Added for localization.
2617  * @type {string}
2618  * @private
2619  */
2622 AudioTrackButton.prototype.controlText_ = 'Audio Track';
2623 _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
2624 exports['default'] = AudioTrackButton;
2626 },{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){
2627 'use strict';
2629 exports.__esModule = true;
2631 var _menuItem = _dereq_(48);
2633 var _menuItem2 = _interopRequireDefault(_menuItem);
2635 var _component = _dereq_(5);
2637 var _component2 = _interopRequireDefault(_component);
2639 var _fn = _dereq_(83);
2641 var Fn = _interopRequireWildcard(_fn);
2643 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
2645 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2647 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2649 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2651 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2652                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-menu-item.js
2653                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2657  * An {@link AudioTrack} {@link MenuItem}
2659  * @extends MenuItem
2660  */
2661 var AudioTrackMenuItem = function (_MenuItem) {
2662   _inherits(AudioTrackMenuItem, _MenuItem);
2664   /**
2665    * Creates an instance of this class.
2666    *
2667    * @param {Player} player
2668    *        The `Player` that this class should be attached to.
2669    *
2670    * @param {Object} [options]
2671    *        The key/value store of player options.
2672    */
2673   function AudioTrackMenuItem(player, options) {
2674     _classCallCheck(this, AudioTrackMenuItem);
2676     var track = options.track;
2677     var tracks = player.audioTracks();
2679     // Modify options for parent MenuItem class's init.
2680     options.label = track.label || track.language || 'Unknown';
2681     options.selected = track.enabled;
2683     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
2685     _this.track = track;
2687     if (tracks) {
2688       (function () {
2689         var changeHandler = Fn.bind(_this, _this.handleTracksChange);
2691         tracks.addEventListener('change', changeHandler);
2692         _this.on('dispose', function () {
2693           tracks.removeEventListener('change', changeHandler);
2694         });
2695       })();
2696     }
2697     return _this;
2698   }
2700   /**
2701    * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
2702    * for more detailed information on what a click can be.
2703    *
2704    * @param {EventTarget~Event} [event]
2705    *        The `keydown`, `tap`, or `click` event that caused this function to be
2706    *        called.
2707    *
2708    * @listens tap
2709    * @listens click
2710    */
2713   AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
2714     var tracks = this.player_.audioTracks();
2716     _MenuItem.prototype.handleClick.call(this, event);
2718     if (!tracks) {
2719       return;
2720     }
2722     for (var i = 0; i < tracks.length; i++) {
2723       var track = tracks[i];
2725       track.enabled = track === this.track;
2726     }
2727   };
2729   /**
2730    * Handle any {@link AudioTrack} change.
2731    *
2732    * @param {EventTarget~Event} [event]
2733    *        The {@link AudioTrackList#change} event that caused this to run.
2734    *
2735    * @listens AudioTrackList#change
2736    */
2739   AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
2740     this.selected(this.track.enabled);
2741   };
2743   return AudioTrackMenuItem;
2744 }(_menuItem2['default']);
2746 _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
2747 exports['default'] = AudioTrackMenuItem;
2749 },{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){
2750 'use strict';
2752 exports.__esModule = true;
2754 var _component = _dereq_(5);
2756 var _component2 = _interopRequireDefault(_component);
2758 _dereq_(12);
2760 _dereq_(32);
2762 _dereq_(33);
2764 _dereq_(35);
2766 _dereq_(34);
2768 _dereq_(10);
2770 _dereq_(18);
2772 _dereq_(9);
2774 _dereq_(38);
2776 _dereq_(40);
2778 _dereq_(11);
2780 _dereq_(25);
2782 _dereq_(27);
2784 _dereq_(29);
2786 _dereq_(24);
2788 _dereq_(6);
2790 _dereq_(13);
2792 _dereq_(21);
2794 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2796 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2798 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2800 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2801                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file control-bar.js
2802                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2805 // Required children
2809  * Container of main controls.
2811  * @extends Component
2812  */
2813 var ControlBar = function (_Component) {
2814   _inherits(ControlBar, _Component);
2816   function ControlBar() {
2817     _classCallCheck(this, ControlBar);
2819     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
2820   }
2822   /**
2823    * Create the `Component`'s DOM element
2824    *
2825    * @return {Element}
2826    *         The element that was created.
2827    */
2828   ControlBar.prototype.createEl = function createEl() {
2829     return _Component.prototype.createEl.call(this, 'div', {
2830       className: 'vjs-control-bar',
2831       dir: 'ltr'
2832     }, {
2833       // The control bar is a group, so it can contain menuitems
2834       role: 'group'
2835     });
2836   };
2838   return ControlBar;
2839 }(_component2['default']);
2842  * Default options for `ControlBar`
2844  * @type {Object}
2845  * @private
2846  */
2849 ControlBar.prototype.options_ = {
2850   children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
2853 _component2['default'].registerComponent('ControlBar', ControlBar);
2854 exports['default'] = ControlBar;
2856 },{"10":10,"11":11,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"32":32,"33":33,"34":34,"35":35,"38":38,"40":40,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){
2857 'use strict';
2859 exports.__esModule = true;
2861 var _button = _dereq_(2);
2863 var _button2 = _interopRequireDefault(_button);
2865 var _component = _dereq_(5);
2867 var _component2 = _interopRequireDefault(_component);
2869 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2871 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2873 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2875 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2876                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file fullscreen-toggle.js
2877                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2881  * Toggle fullscreen video
2883  * @extends Button
2884  */
2885 var FullscreenToggle = function (_Button) {
2886   _inherits(FullscreenToggle, _Button);
2888   /**
2889    * Creates an instance of this class.
2890    *
2891    * @param {Player} player
2892    *        The `Player` that this class should be attached to.
2893    *
2894    * @param {Object} [options]
2895    *        The key/value store of player options.
2896    */
2897   function FullscreenToggle(player, options) {
2898     _classCallCheck(this, FullscreenToggle);
2900     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
2902     _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
2903     return _this;
2904   }
2906   /**
2907    * Builds the default DOM `className`.
2908    *
2909    * @return {string}
2910    *         The DOM `className` for this object.
2911    */
2914   FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
2915     return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
2916   };
2918   /**
2919    * Handles fullscreenchange on the player and change control text accordingly.
2920    *
2921    * @param {EventTarget~Event} [event]
2922    *        The {@link Player#fullscreenchange} event that caused this function to be
2923    *        called.
2924    *
2925    * @listens Player#fullscreenchange
2926    */
2929   FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
2930     if (this.player_.isFullscreen()) {
2931       this.controlText('Non-Fullscreen');
2932     } else {
2933       this.controlText('Fullscreen');
2934     }
2935   };
2937   /**
2938    * This gets called when an `FullscreenToggle` is "clicked". See
2939    * {@link ClickableComponent} for more detailed information on what a click can be.
2940    *
2941    * @param {EventTarget~Event} [event]
2942    *        The `keydown`, `tap`, or `click` event that caused this function to be
2943    *        called.
2944    *
2945    * @listens tap
2946    * @listens click
2947    */
2950   FullscreenToggle.prototype.handleClick = function handleClick(event) {
2951     if (!this.player_.isFullscreen()) {
2952       this.player_.requestFullscreen();
2953     } else {
2954       this.player_.exitFullscreen();
2955     }
2956   };
2958   return FullscreenToggle;
2959 }(_button2['default']);
2962  * The text that should display over the `FullscreenToggle`s controls. Added for localization.
2964  * @type {string}
2965  * @private
2966  */
2969 FullscreenToggle.prototype.controlText_ = 'Fullscreen';
2971 _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
2972 exports['default'] = FullscreenToggle;
2974 },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
2975 'use strict';
2977 exports.__esModule = true;
2979 var _component = _dereq_(5);
2981 var _component2 = _interopRequireDefault(_component);
2983 var _dom = _dereq_(81);
2985 var Dom = _interopRequireWildcard(_dom);
2987 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
2989 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2991 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2993 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2995 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2996                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file live-display.js
2997                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3000 // TODO - Future make it click to snap to live
3003  * Displays the live indicator when duration is Infinity.
3005  * @extends Component
3006  */
3007 var LiveDisplay = function (_Component) {
3008   _inherits(LiveDisplay, _Component);
3010   /**
3011    * Creates an instance of this class.
3012    *
3013    * @param {Player} player
3014    *        The `Player` that this class should be attached to.
3015    *
3016    * @param {Object} [options]
3017    *        The key/value store of player options.
3018    */
3019   function LiveDisplay(player, options) {
3020     _classCallCheck(this, LiveDisplay);
3022     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3024     _this.updateShowing();
3025     _this.on(_this.player(), 'durationchange', _this.updateShowing);
3026     return _this;
3027   }
3029   /**
3030    * Create the `Component`'s DOM element
3031    *
3032    * @return {Element}
3033    *         The element that was created.
3034    */
3037   LiveDisplay.prototype.createEl = function createEl() {
3038     var el = _Component.prototype.createEl.call(this, 'div', {
3039       className: 'vjs-live-control vjs-control'
3040     });
3042     this.contentEl_ = Dom.createEl('div', {
3043       className: 'vjs-live-display',
3044       innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
3045     }, {
3046       'aria-live': 'off'
3047     });
3049     el.appendChild(this.contentEl_);
3050     return el;
3051   };
3053   /**
3054    * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
3055    * it accordingly
3056    *
3057    * @param {EventTarget~Event} [event]
3058    *        The {@link Player#durationchange} event that caused this function to run.
3059    *
3060    * @listens Player#durationchange
3061    */
3064   LiveDisplay.prototype.updateShowing = function updateShowing(event) {
3065     if (this.player().duration() === Infinity) {
3066       this.show();
3067     } else {
3068       this.hide();
3069     }
3070   };
3072   return LiveDisplay;
3073 }(_component2['default']);
3075 _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
3076 exports['default'] = LiveDisplay;
3078 },{"5":5,"81":81}],11:[function(_dereq_,module,exports){
3079 'use strict';
3081 exports.__esModule = true;
3083 var _button = _dereq_(2);
3085 var _button2 = _interopRequireDefault(_button);
3087 var _component = _dereq_(5);
3089 var _component2 = _interopRequireDefault(_component);
3091 var _dom = _dereq_(81);
3093 var Dom = _interopRequireWildcard(_dom);
3095 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3097 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3099 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3101 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3103 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3104                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file mute-toggle.js
3105                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3109  * A button component for muting the audio.
3111  * @extends Button
3112  */
3113 var MuteToggle = function (_Button) {
3114   _inherits(MuteToggle, _Button);
3116   /**
3117    * Creates an instance of this class.
3118    *
3119    * @param {Player} player
3120    *        The `Player` that this class should be attached to.
3121    *
3122    * @param {Object} [options]
3123    *        The key/value store of player options.
3124    */
3125   function MuteToggle(player, options) {
3126     _classCallCheck(this, MuteToggle);
3128     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3130     _this.on(player, 'volumechange', _this.update);
3132     // hide mute toggle if the current tech doesn't support volume control
3133     if (player.tech_ && player.tech_.featuresVolumeControl === false) {
3134       _this.addClass('vjs-hidden');
3135     }
3137     _this.on(player, 'loadstart', function () {
3138       // We need to update the button to account for a default muted state.
3139       this.update();
3141       if (player.tech_.featuresVolumeControl === false) {
3142         this.addClass('vjs-hidden');
3143       } else {
3144         this.removeClass('vjs-hidden');
3145       }
3146     });
3147     return _this;
3148   }
3150   /**
3151    * Builds the default DOM `className`.
3152    *
3153    * @return {string}
3154    *         The DOM `className` for this object.
3155    */
3158   MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
3159     return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
3160   };
3162   /**
3163    * This gets called when an `MuteToggle` is "clicked". See
3164    * {@link ClickableComponent} for more detailed information on what a click can be.
3165    *
3166    * @param {EventTarget~Event} [event]
3167    *        The `keydown`, `tap`, or `click` event that caused this function to be
3168    *        called.
3169    *
3170    * @listens tap
3171    * @listens click
3172    */
3175   MuteToggle.prototype.handleClick = function handleClick(event) {
3176     this.player_.muted(this.player_.muted() ? false : true);
3177   };
3179   /**
3180    * Update the state of volume.
3181    *
3182    * @param {EventTarget~Event} [event]
3183    *        The {@link Player#loadstart} event if this function was called through an
3184    *        event.
3185    *
3186    * @listens Player#loadstart
3187    */
3190   MuteToggle.prototype.update = function update(event) {
3191     var vol = this.player_.volume();
3192     var level = 3;
3194     if (vol === 0 || this.player_.muted()) {
3195       level = 0;
3196     } else if (vol < 0.33) {
3197       level = 1;
3198     } else if (vol < 0.67) {
3199       level = 2;
3200     }
3202     // Don't rewrite the button text if the actual text doesn't change.
3203     // This causes unnecessary and confusing information for screen reader users.
3204     // This check is needed because this function gets called every time the volume level is changed.
3205     var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
3207     if (this.controlText() !== toMute) {
3208       this.controlText(toMute);
3209     }
3211     // TODO improve muted icon classes
3212     for (var i = 0; i < 4; i++) {
3213       Dom.removeElClass(this.el_, 'vjs-vol-' + i);
3214     }
3215     Dom.addElClass(this.el_, 'vjs-vol-' + level);
3216   };
3218   return MuteToggle;
3219 }(_button2['default']);
3222  * The text that should display over the `MuteToggle`s controls. Added for localization.
3224  * @type {string}
3225  * @private
3226  */
3229 MuteToggle.prototype.controlText_ = 'Mute';
3231 _component2['default'].registerComponent('MuteToggle', MuteToggle);
3232 exports['default'] = MuteToggle;
3234 },{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){
3235 'use strict';
3237 exports.__esModule = true;
3239 var _button = _dereq_(2);
3241 var _button2 = _interopRequireDefault(_button);
3243 var _component = _dereq_(5);
3245 var _component2 = _interopRequireDefault(_component);
3247 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3249 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3251 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3253 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3254                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-toggle.js
3255                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3259  * Button to toggle between play and pause.
3261  * @extends Button
3262  */
3263 var PlayToggle = function (_Button) {
3264   _inherits(PlayToggle, _Button);
3266   /**
3267    * Creates an instance of this class.
3268    *
3269    * @param {Player} player
3270    *        The `Player` that this class should be attached to.
3271    *
3272    * @param {Object} [options]
3273    *        The key/value store of player options.
3274    */
3275   function PlayToggle(player, options) {
3276     _classCallCheck(this, PlayToggle);
3278     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3280     _this.on(player, 'play', _this.handlePlay);
3281     _this.on(player, 'pause', _this.handlePause);
3282     return _this;
3283   }
3285   /**
3286    * Builds the default DOM `className`.
3287    *
3288    * @return {string}
3289    *         The DOM `className` for this object.
3290    */
3293   PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
3294     return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
3295   };
3297   /**
3298    * This gets called when an `PlayToggle` is "clicked". See
3299    * {@link ClickableComponent} for more detailed information on what a click can be.
3300    *
3301    * @param {EventTarget~Event} [event]
3302    *        The `keydown`, `tap`, or `click` event that caused this function to be
3303    *        called.
3304    *
3305    * @listens tap
3306    * @listens click
3307    */
3310   PlayToggle.prototype.handleClick = function handleClick(event) {
3311     if (this.player_.paused()) {
3312       this.player_.play();
3313     } else {
3314       this.player_.pause();
3315     }
3316   };
3318   /**
3319    * Add the vjs-playing class to the element so it can change appearance.
3320    *
3321    * @param {EventTarget~Event} [event]
3322    *        The event that caused this function to run.
3323    *
3324    * @listens Player#play
3325    */
3328   PlayToggle.prototype.handlePlay = function handlePlay(event) {
3329     this.removeClass('vjs-paused');
3330     this.addClass('vjs-playing');
3331     // change the button text to "Pause"
3332     this.controlText('Pause');
3333   };
3335   /**
3336    * Add the vjs-paused class to the element so it can change appearance.
3337    *
3338    * @param {EventTarget~Event} [event]
3339    *        The event that caused this function to run.
3340    *
3341    * @listens Player#pause
3342    */
3345   PlayToggle.prototype.handlePause = function handlePause(event) {
3346     this.removeClass('vjs-playing');
3347     this.addClass('vjs-paused');
3348     // change the button text to "Play"
3349     this.controlText('Play');
3350   };
3352   return PlayToggle;
3353 }(_button2['default']);
3356  * The text that should display over the `PlayToggle`s controls. Added for localization.
3358  * @type {string}
3359  * @private
3360  */
3363 PlayToggle.prototype.controlText_ = 'Play';
3365 _component2['default'].registerComponent('PlayToggle', PlayToggle);
3366 exports['default'] = PlayToggle;
3368 },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
3369 'use strict';
3371 exports.__esModule = true;
3373 var _menuButton = _dereq_(47);
3375 var _menuButton2 = _interopRequireDefault(_menuButton);
3377 var _menu = _dereq_(49);
3379 var _menu2 = _interopRequireDefault(_menu);
3381 var _playbackRateMenuItem = _dereq_(14);
3383 var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
3385 var _component = _dereq_(5);
3387 var _component2 = _interopRequireDefault(_component);
3389 var _dom = _dereq_(81);
3391 var Dom = _interopRequireWildcard(_dom);
3393 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3395 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3397 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3399 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3401 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3402                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file playback-rate-menu-button.js
3403                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3407  * The component for controlling the playback rate.
3409  * @extends MenuButton
3410  */
3411 var PlaybackRateMenuButton = function (_MenuButton) {
3412   _inherits(PlaybackRateMenuButton, _MenuButton);
3414   /**
3415    * Creates an instance of this class.
3416    *
3417    * @param {Player} player
3418    *        The `Player` that this class should be attached to.
3419    *
3420    * @param {Object} [options]
3421    *        The key/value store of player options.
3422    */
3423   function PlaybackRateMenuButton(player, options) {
3424     _classCallCheck(this, PlaybackRateMenuButton);
3426     var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
3428     _this.updateVisibility();
3429     _this.updateLabel();
3431     _this.on(player, 'loadstart', _this.updateVisibility);
3432     _this.on(player, 'ratechange', _this.updateLabel);
3433     return _this;
3434   }
3436   /**
3437    * Create the `Component`'s DOM element
3438    *
3439    * @return {Element}
3440    *         The element that was created.
3441    */
3444   PlaybackRateMenuButton.prototype.createEl = function createEl() {
3445     var el = _MenuButton.prototype.createEl.call(this);
3447     this.labelEl_ = Dom.createEl('div', {
3448       className: 'vjs-playback-rate-value',
3449       innerHTML: 1.0
3450     });
3452     el.appendChild(this.labelEl_);
3454     return el;
3455   };
3457   /**
3458    * Builds the default DOM `className`.
3459    *
3460    * @return {string}
3461    *         The DOM `className` for this object.
3462    */
3465   PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
3466     return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
3467   };
3469   /**
3470    * Create the playback rate menu
3471    *
3472    * @return {Menu}
3473    *         Menu object populated with {@link PlaybackRateMenuItem}s
3474    */
3477   PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
3478     var menu = new _menu2['default'](this.player());
3479     var rates = this.playbackRates();
3481     if (rates) {
3482       for (var i = rates.length - 1; i >= 0; i--) {
3483         menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
3484       }
3485     }
3487     return menu;
3488   };
3490   /**
3491    * Updates ARIA accessibility attributes
3492    */
3495   PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
3496     // Current playback rate
3497     this.el().setAttribute('aria-valuenow', this.player().playbackRate());
3498   };
3500   /**
3501    * This gets called when an `PlaybackRateMenuButton` is "clicked". See
3502    * {@link ClickableComponent} for more detailed information on what a click can be.
3503    *
3504    * @param {EventTarget~Event} [event]
3505    *        The `keydown`, `tap`, or `click` event that caused this function to be
3506    *        called.
3507    *
3508    * @listens tap
3509    * @listens click
3510    */
3513   PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
3514     // select next rate option
3515     var currentRate = this.player().playbackRate();
3516     var rates = this.playbackRates();
3518     // this will select first one if the last one currently selected
3519     var newRate = rates[0];
3521     for (var i = 0; i < rates.length; i++) {
3522       if (rates[i] > currentRate) {
3523         newRate = rates[i];
3524         break;
3525       }
3526     }
3527     this.player().playbackRate(newRate);
3528   };
3530   /**
3531    * Get possible playback rates
3532    *
3533    * @return {Array}
3534    *         All possible playback rates
3535    */
3538   PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
3539     return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
3540   };
3542   /**
3543    * Get whether playback rates is supported by the tech
3544    * and an array of playback rates exists
3545    *
3546    * @return {boolean}
3547    *         Whether changing playback rate is supported
3548    */
3551   PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
3552     return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
3553   };
3555   /**
3556    * Hide playback rate controls when they're no playback rate options to select
3557    *
3558    * @param {EventTarget~Event} [event]
3559    *        The event that caused this function to run.
3560    *
3561    * @listens Player#loadstart
3562    */
3565   PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
3566     if (this.playbackRateSupported()) {
3567       this.removeClass('vjs-hidden');
3568     } else {
3569       this.addClass('vjs-hidden');
3570     }
3571   };
3573   /**
3574    * Update button label when rate changed
3575    *
3576    * @param {EventTarget~Event} [event]
3577    *        The event that caused this function to run.
3578    *
3579    * @listens Player#ratechange
3580    */
3583   PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
3584     if (this.playbackRateSupported()) {
3585       this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
3586     }
3587   };
3589   return PlaybackRateMenuButton;
3590 }(_menuButton2['default']);
3593  * The text that should display over the `FullscreenToggle`s controls. Added for localization.
3595  * @type {string}
3596  * @private
3597  */
3600 PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
3602 _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
3603 exports['default'] = PlaybackRateMenuButton;
3605 },{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){
3606 'use strict';
3608 exports.__esModule = true;
3610 var _menuItem = _dereq_(48);
3612 var _menuItem2 = _interopRequireDefault(_menuItem);
3614 var _component = _dereq_(5);
3616 var _component2 = _interopRequireDefault(_component);
3618 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3620 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3622 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3624 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3625                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file playback-rate-menu-item.js
3626                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3630  * The specific menu item type for selecting a playback rate.
3632  * @extends MenuItem
3633  */
3634 var PlaybackRateMenuItem = function (_MenuItem) {
3635   _inherits(PlaybackRateMenuItem, _MenuItem);
3637   /**
3638    * Creates an instance of this class.
3639    *
3640    * @param {Player} player
3641    *        The `Player` that this class should be attached to.
3642    *
3643    * @param {Object} [options]
3644    *        The key/value store of player options.
3645    */
3646   function PlaybackRateMenuItem(player, options) {
3647     _classCallCheck(this, PlaybackRateMenuItem);
3649     var label = options.rate;
3650     var rate = parseFloat(label, 10);
3652     // Modify options for parent MenuItem class's init.
3653     options.label = label;
3654     options.selected = rate === 1;
3656     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
3658     _this.label = label;
3659     _this.rate = rate;
3661     _this.on(player, 'ratechange', _this.update);
3662     return _this;
3663   }
3665   /**
3666    * This gets called when an `PlaybackRateMenuItem` is "clicked". See
3667    * {@link ClickableComponent} for more detailed information on what a click can be.
3668    *
3669    * @param {EventTarget~Event} [event]
3670    *        The `keydown`, `tap`, or `click` event that caused this function to be
3671    *        called.
3672    *
3673    * @listens tap
3674    * @listens click
3675    */
3678   PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
3679     _MenuItem.prototype.handleClick.call(this);
3680     this.player().playbackRate(this.rate);
3681   };
3683   /**
3684    * Update the PlaybackRateMenuItem when the playbackrate changes.
3685    *
3686    * @param {EventTarget~Event} [event]
3687    *        The `ratechange` event that caused this function to run.
3688    *
3689    * @listens Player#ratechange
3690    */
3693   PlaybackRateMenuItem.prototype.update = function update(event) {
3694     this.selected(this.player().playbackRate() === this.rate);
3695   };
3697   return PlaybackRateMenuItem;
3698 }(_menuItem2['default']);
3701  * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
3703  * @type {string}
3704  * @private
3705  */
3708 PlaybackRateMenuItem.prototype.contentElType = 'button';
3710 _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
3711 exports['default'] = PlaybackRateMenuItem;
3713 },{"48":48,"5":5}],15:[function(_dereq_,module,exports){
3714 'use strict';
3716 exports.__esModule = true;
3718 var _component = _dereq_(5);
3720 var _component2 = _interopRequireDefault(_component);
3722 var _dom = _dereq_(81);
3724 var Dom = _interopRequireWildcard(_dom);
3726 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3728 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3730 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3732 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3734 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3735                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file load-progress-bar.js
3736                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3740  * Shows loading progress
3742  * @extends Component
3743  */
3744 var LoadProgressBar = function (_Component) {
3745   _inherits(LoadProgressBar, _Component);
3747   /**
3748    * Creates an instance of this class.
3749    *
3750    * @param {Player} player
3751    *        The `Player` that this class should be attached to.
3752    *
3753    * @param {Object} [options]
3754    *        The key/value store of player options.
3755    */
3756   function LoadProgressBar(player, options) {
3757     _classCallCheck(this, LoadProgressBar);
3759     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3761     _this.partEls_ = [];
3762     _this.on(player, 'progress', _this.update);
3763     return _this;
3764   }
3766   /**
3767    * Create the `Component`'s DOM element
3768    *
3769    * @return {Element}
3770    *         The element that was created.
3771    */
3774   LoadProgressBar.prototype.createEl = function createEl() {
3775     return _Component.prototype.createEl.call(this, 'div', {
3776       className: 'vjs-load-progress',
3777       innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
3778     });
3779   };
3781   /**
3782    * Update progress bar
3783    *
3784    * @param {EventTarget~Event} [event]
3785    *        The `progress` event that caused this function to run.
3786    *
3787    * @listens Player#progress
3788    */
3791   LoadProgressBar.prototype.update = function update(event) {
3792     var buffered = this.player_.buffered();
3793     var duration = this.player_.duration();
3794     var bufferedEnd = this.player_.bufferedEnd();
3795     var children = this.partEls_;
3797     // get the percent width of a time compared to the total end
3798     var percentify = function percentify(time, end) {
3799       // no NaN
3800       var percent = time / end || 0;
3802       return (percent >= 1 ? 1 : percent) * 100 + '%';
3803     };
3805     // update the width of the progress bar
3806     this.el_.style.width = percentify(bufferedEnd, duration);
3808     // add child elements to represent the individual buffered time ranges
3809     for (var i = 0; i < buffered.length; i++) {
3810       var start = buffered.start(i);
3811       var end = buffered.end(i);
3812       var part = children[i];
3814       if (!part) {
3815         part = this.el_.appendChild(Dom.createEl());
3816         children[i] = part;
3817       }
3819       // set the percent based on the width of the progress bar (bufferedEnd)
3820       part.style.left = percentify(start, bufferedEnd);
3821       part.style.width = percentify(end - start, bufferedEnd);
3822     }
3824     // remove unused buffered range elements
3825     for (var _i = children.length; _i > buffered.length; _i--) {
3826       this.el_.removeChild(children[_i - 1]);
3827     }
3828     children.length = buffered.length;
3829   };
3831   return LoadProgressBar;
3832 }(_component2['default']);
3834 _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
3835 exports['default'] = LoadProgressBar;
3837 },{"5":5,"81":81}],16:[function(_dereq_,module,exports){
3838 'use strict';
3840 exports.__esModule = true;
3842 var _component = _dereq_(5);
3844 var _component2 = _interopRequireDefault(_component);
3846 var _dom = _dereq_(81);
3848 var Dom = _interopRequireWildcard(_dom);
3850 var _fn = _dereq_(83);
3852 var Fn = _interopRequireWildcard(_fn);
3854 var _formatTime = _dereq_(84);
3856 var _formatTime2 = _interopRequireDefault(_formatTime);
3858 var _computedStyle = _dereq_(80);
3860 var _computedStyle2 = _interopRequireDefault(_computedStyle);
3862 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3864 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3866 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3868 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3870 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3871                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file mouse-time-display.js
3872                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3876  * The Mouse Time Display component shows the time you will seek to
3877  * when hovering over the progress bar
3879  * @extends Component
3880  */
3881 var MouseTimeDisplay = function (_Component) {
3882   _inherits(MouseTimeDisplay, _Component);
3884   /**
3885    * Creates an instance of this class.
3886    *
3887    * @param {Player} player
3888    *        The `Player` that this class should be attached to.
3889    *
3890    * @param {Object} [options]
3891    *        The key/value store of player options.
3892    */
3893   function MouseTimeDisplay(player, options) {
3894     _classCallCheck(this, MouseTimeDisplay);
3896     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3898     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
3899       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
3900     }
3902     if (_this.keepTooltipsInside) {
3903       _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
3904       _this.el().appendChild(_this.tooltip);
3905       _this.addClass('vjs-keep-tooltips-inside');
3906     }
3908     _this.update(0, 0);
3910     player.on('ready', function () {
3911       _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
3912     });
3913     return _this;
3914   }
3916   /**
3917    * Create the `Component`'s DOM element
3918    *
3919    * @return {Element}
3920    *         The element that was created.
3921    */
3924   MouseTimeDisplay.prototype.createEl = function createEl() {
3925     return _Component.prototype.createEl.call(this, 'div', {
3926       className: 'vjs-mouse-display'
3927     });
3928   };
3930   /**
3931    * Handle the mouse move event on the `MouseTimeDisplay`.
3932    *
3933    * @param {EventTarget~Event} event
3934    *        The `mousemove` event that caused this to event to run.
3935    *
3936    * @listen mousemove
3937    */
3940   MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
3941     var duration = this.player_.duration();
3942     var newTime = this.calculateDistance(event) * duration;
3943     var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
3945     this.update(newTime, position);
3946   };
3948   /**
3949    * Update the time and position of the `MouseTimeDisplay`.
3950    *
3951    * @param {number} newTime
3952    *        Time to change the `MouseTimeDisplay` to.
3953    *
3954    * @param {number} position
3955    *        Position from the left of the in pixels.
3956    */
3959   MouseTimeDisplay.prototype.update = function update(newTime, position) {
3960     var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
3962     this.el().style.left = position + 'px';
3963     this.el().setAttribute('data-current-time', time);
3965     if (this.keepTooltipsInside) {
3966       var clampedPosition = this.clampPosition_(position);
3967       var difference = position - clampedPosition + 1;
3968       var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
3969       var tooltipWidthHalf = tooltipWidth / 2;
3971       this.tooltip.innerHTML = time;
3972       this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
3973     }
3974   };
3976   /**
3977    * Get the mouse pointers x coordinate in pixels.
3978    *
3979    * @param {EventTarget~Event} [event]
3980    *        The `mousemove` event that was passed to this function by
3981    *        {@link MouseTimeDisplay#handleMouseMove}
3982    *
3983    * @return {number}
3984    *         THe x position in pixels of the mouse pointer.
3985    */
3988   MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
3989     return Dom.getPointerPosition(this.el().parentNode, event).x;
3990   };
3992   /**
3993    * This takes in a horizontal position for the bar and returns a clamped position.
3994    * Clamped position means that it will keep the position greater than half the width
3995    * of the tooltip and smaller than the player width minus half the width o the tooltip.
3996    * It will only clamp the position if `keepTooltipsInside` option is set.
3997    *
3998    * @param {number} position
3999    *        The position the bar wants to be
4000    *
4001    * @return {number}
4002    *         The (potentially) new clamped position.
4003    *
4004    * @private
4005    */
4008   MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
4009     if (!this.keepTooltipsInside) {
4010       return position;
4011     }
4013     var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4014     var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
4015     var tooltipWidthHalf = tooltipWidth / 2;
4016     var actualPosition = position;
4018     if (position < tooltipWidthHalf) {
4019       actualPosition = Math.ceil(tooltipWidthHalf);
4020     } else if (position > playerWidth - tooltipWidthHalf) {
4021       actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
4022     }
4024     return actualPosition;
4025   };
4027   return MouseTimeDisplay;
4028 }(_component2['default']);
4030 _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
4031 exports['default'] = MouseTimeDisplay;
4033 },{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){
4034 'use strict';
4036 exports.__esModule = true;
4038 var _component = _dereq_(5);
4040 var _component2 = _interopRequireDefault(_component);
4042 var _fn = _dereq_(83);
4044 var Fn = _interopRequireWildcard(_fn);
4046 var _formatTime = _dereq_(84);
4048 var _formatTime2 = _interopRequireDefault(_formatTime);
4050 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4052 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4054 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4056 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4058 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4059                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-progress-bar.js
4060                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4064  * Shows play progress
4066  * @extends Component
4067  */
4068 var PlayProgressBar = function (_Component) {
4069   _inherits(PlayProgressBar, _Component);
4071   /**
4072    * Creates an instance of this class.
4073    *
4074    * @param {Player} player
4075    *        The `Player` that this class should be attached to.
4076    *
4077    * @param {Object} [options]
4078    *        The key/value store of player options.
4079    */
4080   function PlayProgressBar(player, options) {
4081     _classCallCheck(this, PlayProgressBar);
4083     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4085     _this.updateDataAttr();
4086     _this.on(player, 'timeupdate', _this.updateDataAttr);
4087     player.ready(Fn.bind(_this, _this.updateDataAttr));
4089     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4090       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4091     }
4093     if (_this.keepTooltipsInside) {
4094       _this.addClass('vjs-keep-tooltips-inside');
4095     }
4096     return _this;
4097   }
4099   /**
4100    * Create the `Component`'s DOM element
4101    *
4102    * @return {Element}
4103    *         The element that was created.
4104    */
4107   PlayProgressBar.prototype.createEl = function createEl() {
4108     return _Component.prototype.createEl.call(this, 'div', {
4109       className: 'vjs-play-progress vjs-slider-bar',
4110       innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4111     });
4112   };
4114   /**
4115    * Update the data-current-time attribute on the `PlayProgressBar`.
4116    *
4117    * @param {EventTarget~Event} [event]
4118    *        The `timeupdate` event that caused this to run.
4119    *
4120    * @listens Player#timeupdate
4121    */
4124   PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4125     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4127     this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
4128   };
4130   return PlayProgressBar;
4131 }(_component2['default']);
4133 _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
4134 exports['default'] = PlayProgressBar;
4136 },{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){
4137 'use strict';
4139 exports.__esModule = true;
4141 var _component = _dereq_(5);
4143 var _component2 = _interopRequireDefault(_component);
4145 _dereq_(19);
4147 _dereq_(16);
4149 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4151 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4153 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4155 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4156                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file progress-control.js
4157                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4161  * The Progress Control component contains the seek bar, load progress,
4162  * and play progress.
4164  * @extends Component
4165  */
4166 var ProgressControl = function (_Component) {
4167   _inherits(ProgressControl, _Component);
4169   function ProgressControl() {
4170     _classCallCheck(this, ProgressControl);
4172     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4173   }
4175   /**
4176    * Create the `Component`'s DOM element
4177    *
4178    * @return {Element}
4179    *         The element that was created.
4180    */
4181   ProgressControl.prototype.createEl = function createEl() {
4182     return _Component.prototype.createEl.call(this, 'div', {
4183       className: 'vjs-progress-control vjs-control'
4184     });
4185   };
4187   return ProgressControl;
4188 }(_component2['default']);
4191  * Default options for `ProgressControl`
4193  * @type {Object}
4194  * @private
4195  */
4198 ProgressControl.prototype.options_ = {
4199   children: ['seekBar']
4202 _component2['default'].registerComponent('ProgressControl', ProgressControl);
4203 exports['default'] = ProgressControl;
4205 },{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){
4206 'use strict';
4208 exports.__esModule = true;
4210 var _slider = _dereq_(57);
4212 var _slider2 = _interopRequireDefault(_slider);
4214 var _component = _dereq_(5);
4216 var _component2 = _interopRequireDefault(_component);
4218 var _fn = _dereq_(83);
4220 var Fn = _interopRequireWildcard(_fn);
4222 var _formatTime = _dereq_(84);
4224 var _formatTime2 = _interopRequireDefault(_formatTime);
4226 var _computedStyle = _dereq_(80);
4228 var _computedStyle2 = _interopRequireDefault(_computedStyle);
4230 _dereq_(15);
4232 _dereq_(17);
4234 _dereq_(20);
4236 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4238 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4240 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4242 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4244 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4245                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file seek-bar.js
4246                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4250  * Seek Bar and holder for the progress bars
4252  * @extends Slider
4253  */
4254 var SeekBar = function (_Slider) {
4255   _inherits(SeekBar, _Slider);
4257   /**
4258    * Creates an instance of this class.
4259    *
4260    * @param {Player} player
4261    *        The `Player` that this class should be attached to.
4262    *
4263    * @param {Object} [options]
4264    *        The key/value store of player options.
4265    */
4266   function SeekBar(player, options) {
4267     _classCallCheck(this, SeekBar);
4269     var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
4271     _this.on(player, 'timeupdate', _this.updateProgress);
4272     _this.on(player, 'ended', _this.updateProgress);
4273     player.ready(Fn.bind(_this, _this.updateProgress));
4275     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4276       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4277     }
4279     if (_this.keepTooltipsInside) {
4280       _this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
4281     }
4282     return _this;
4283   }
4285   /**
4286    * Create the `Component`'s DOM element
4287    *
4288    * @return {Element}
4289    *         The element that was created.
4290    */
4293   SeekBar.prototype.createEl = function createEl() {
4294     return _Slider.prototype.createEl.call(this, 'div', {
4295       className: 'vjs-progress-holder'
4296     }, {
4297       'aria-label': 'progress bar'
4298     });
4299   };
4301   /**
4302    * Update the seek bars tooltip and width.
4303    *
4304    * @param {EventTarget~Event} [event]
4305    *        The `timeupdate` or `ended` event that caused this to run.
4306    *
4307    * @listens Player#timeupdate
4308    * @listens Player#ended
4309    */
4312   SeekBar.prototype.updateProgress = function updateProgress(event) {
4313     this.updateAriaAttributes(this.el_);
4315     if (this.keepTooltipsInside) {
4316       this.updateAriaAttributes(this.tooltipProgressBar.el_);
4317       this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
4319       var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4320       var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
4321       var tooltipStyle = this.tooltipProgressBar.el().style;
4323       tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
4324       tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
4325       tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
4326     }
4327   };
4329   /**
4330    * Update ARIA accessibility attributes
4331    *
4332    * @param {Element} el
4333    *        The element to update with aria accessibility attributes.
4334    */
4337   SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
4338     // Allows for smooth scrubbing, when player can't keep up.
4339     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4341     // machine readable value of progress bar (percentage complete)
4342     el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
4343     // human readable value of progress bar (time complete)
4344     el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
4345   };
4347   /**
4348    * Get percentage of video played
4349    *
4350    * @return {number}
4351    *         The percentage played
4352    */
4355   SeekBar.prototype.getPercent = function getPercent() {
4356     var percent = this.player_.currentTime() / this.player_.duration();
4358     return percent >= 1 ? 1 : percent;
4359   };
4361   /**
4362    * Handle mouse down on seek bar
4363    *
4364    * @param {EventTarget~Event} event
4365    *        The `mousedown` event that caused this to run.
4366    *
4367    * @listens mousedown
4368    */
4371   SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
4372     _Slider.prototype.handleMouseDown.call(this, event);
4374     this.player_.scrubbing(true);
4376     this.videoWasPlaying = !this.player_.paused();
4378     this.pauseTimer_ = this.setTimeout(function () {
4379       this.player_.pause();
4380     }, 100);
4381   };
4383   /**
4384    * Handle mouse move on seek bar
4385    *
4386    * @param {EventTarget~Event} event
4387    *        The `mousemove` event that caused this to run.
4388    *
4389    * @listens mousemove
4390    */
4393   SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
4394     var newTime = this.calculateDistance(event) * this.player_.duration();
4396     // Don't let video end while scrubbing.
4397     if (newTime === this.player_.duration()) {
4398       newTime = newTime - 0.1;
4399     }
4401     // Set new time (tell player to seek to new time)
4402     this.player_.currentTime(newTime);
4404     if (event.type === 'mousemove') {
4405       this.clearTimeout(this.pauseTimer_);
4406       this.player_.pause();
4407     }
4408   };
4410   /**
4411    * Handle mouse up on seek bar
4412    *
4413    * @param {EventTarget~Event} event
4414    *        The `mouseup` event that caused this to run.
4415    *
4416    * @listens mouseup
4417    */
4420   SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
4421     _Slider.prototype.handleMouseUp.call(this, event);
4423     this.clearTimeout(this.pauseTimer_);
4425     this.player_.scrubbing(false);
4426     if (this.videoWasPlaying) {
4427       this.player_.play();
4428     }
4429   };
4431   /**
4432    * Move more quickly fast forward for keyboard-only users
4433    */
4436   SeekBar.prototype.stepForward = function stepForward() {
4437     // more quickly fast forward for keyboard-only users
4438     this.player_.currentTime(this.player_.currentTime() + 5);
4439   };
4441   /**
4442    * Move more quickly rewind for keyboard-only users
4443    */
4446   SeekBar.prototype.stepBack = function stepBack() {
4447     // more quickly rewind for keyboard-only users
4448     this.player_.currentTime(this.player_.currentTime() - 5);
4449   };
4451   return SeekBar;
4452 }(_slider2['default']);
4455  * Default options for the `SeekBar`
4457  * @type {Object}
4458  * @private
4459  */
4462 SeekBar.prototype.options_ = {
4463   children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
4464   barName: 'playProgressBar'
4468  * Call the update event for this Slider when this event happens on the player.
4470  * @type {string}
4471  */
4472 SeekBar.prototype.playerEvent = 'timeupdate';
4474 _component2['default'].registerComponent('SeekBar', SeekBar);
4475 exports['default'] = SeekBar;
4477 },{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){
4478 'use strict';
4480 exports.__esModule = true;
4482 var _component = _dereq_(5);
4484 var _component2 = _interopRequireDefault(_component);
4486 var _fn = _dereq_(83);
4488 var Fn = _interopRequireWildcard(_fn);
4490 var _formatTime = _dereq_(84);
4492 var _formatTime2 = _interopRequireDefault(_formatTime);
4494 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4496 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4498 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4500 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4502 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4503                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-progress-bar.js
4504                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4508  * Shows play progress
4510  * @extends Component
4511  */
4512 var TooltipProgressBar = function (_Component) {
4513   _inherits(TooltipProgressBar, _Component);
4515   /**
4516    * Creates an instance of this class.
4517    *
4518    * @param {Player} player
4519    *        The `Player` that this class should be attached to.
4520    *
4521    * @param {Object} [options]
4522    *        The key/value store of player options.
4523    */
4524   function TooltipProgressBar(player, options) {
4525     _classCallCheck(this, TooltipProgressBar);
4527     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4529     _this.updateDataAttr();
4530     _this.on(player, 'timeupdate', _this.updateDataAttr);
4531     player.ready(Fn.bind(_this, _this.updateDataAttr));
4532     return _this;
4533   }
4535   /**
4536    * Create the `Component`'s DOM element
4537    *
4538    * @return {Element}
4539    *         The element that was created.
4540    */
4543   TooltipProgressBar.prototype.createEl = function createEl() {
4544     var el = _Component.prototype.createEl.call(this, 'div', {
4545       className: 'vjs-tooltip-progress-bar vjs-slider-bar',
4546       innerHTML: '<div class="vjs-time-tooltip"></div>\n        <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4547     });
4549     this.tooltip = el.querySelector('.vjs-time-tooltip');
4551     return el;
4552   };
4554   /**
4555    * Updatet the data-current-time attribute for TooltipProgressBar
4556    *
4557    * @param {EventTarget~Event} [event]
4558    *        The `timeupdate` event that caused this function to run.
4559    *
4560    * @listens Player#timeupdate
4561    */
4564   TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4565     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4566     var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
4568     this.el_.setAttribute('data-current-time', formattedTime);
4569     this.tooltip.innerHTML = formattedTime;
4570   };
4572   return TooltipProgressBar;
4573 }(_component2['default']);
4575 _component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
4576 exports['default'] = TooltipProgressBar;
4578 },{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){
4579 'use strict';
4581 exports.__esModule = true;
4583 var _spacer = _dereq_(22);
4585 var _spacer2 = _interopRequireDefault(_spacer);
4587 var _component = _dereq_(5);
4589 var _component2 = _interopRequireDefault(_component);
4591 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4593 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4595 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4597 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4598                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file custom-control-spacer.js
4599                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4603  * Spacer specifically meant to be used as an insertion point for new plugins, etc.
4605  * @extends Spacer
4606  */
4607 var CustomControlSpacer = function (_Spacer) {
4608   _inherits(CustomControlSpacer, _Spacer);
4610   function CustomControlSpacer() {
4611     _classCallCheck(this, CustomControlSpacer);
4613     return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
4614   }
4616   /**
4617    * Builds the default DOM `className`.
4618    *
4619    * @return {string}
4620    *         The DOM `className` for this object.
4621    */
4622   CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
4623     return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
4624   };
4626   /**
4627    * Create the `Component`'s DOM element
4628    *
4629    * @return {Element}
4630    *         The element that was created.
4631    */
4634   CustomControlSpacer.prototype.createEl = function createEl() {
4635     var el = _Spacer.prototype.createEl.call(this, {
4636       className: this.buildCSSClass()
4637     });
4639     // No-flex/table-cell mode requires there be some content
4640     // in the cell to fill the remaining space of the table.
4641     el.innerHTML = '&nbsp;';
4642     return el;
4643   };
4645   return CustomControlSpacer;
4646 }(_spacer2['default']);
4648 _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
4649 exports['default'] = CustomControlSpacer;
4651 },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
4652 'use strict';
4654 exports.__esModule = true;
4656 var _component = _dereq_(5);
4658 var _component2 = _interopRequireDefault(_component);
4660 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4662 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4664 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4666 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4667                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file spacer.js
4668                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4672  * Just an empty spacer element that can be used as an append point for plugins, etc.
4673  * Also can be used to create space between elements when necessary.
4675  * @extends Component
4676  */
4677 var Spacer = function (_Component) {
4678   _inherits(Spacer, _Component);
4680   function Spacer() {
4681     _classCallCheck(this, Spacer);
4683     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4684   }
4686   /**
4687    * Builds the default DOM `className`.
4688    *
4689    * @return {string}
4690    *         The DOM `className` for this object.
4691    */
4692   Spacer.prototype.buildCSSClass = function buildCSSClass() {
4693     return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
4694   };
4696   /**
4697    * Create the `Component`'s DOM element
4698    *
4699    * @return {Element}
4700    *         The element that was created.
4701    */
4704   Spacer.prototype.createEl = function createEl() {
4705     return _Component.prototype.createEl.call(this, 'div', {
4706       className: this.buildCSSClass()
4707     });
4708   };
4710   return Spacer;
4711 }(_component2['default']);
4713 _component2['default'].registerComponent('Spacer', Spacer);
4715 exports['default'] = Spacer;
4717 },{"5":5}],23:[function(_dereq_,module,exports){
4718 'use strict';
4720 exports.__esModule = true;
4722 var _textTrackMenuItem = _dereq_(31);
4724 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
4726 var _component = _dereq_(5);
4728 var _component2 = _interopRequireDefault(_component);
4730 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4732 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4734 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4736 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4737                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file caption-settings-menu-item.js
4738                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4742  * The menu item for caption track settings menu
4744  * @extends TextTrackMenuItem
4745  */
4746 var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
4747   _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
4749   /**
4750    * Creates an instance of this class.
4751    *
4752    * @param {Player} player
4753    *        The `Player` that this class should be attached to.
4754    *
4755    * @param {Object} [options]
4756    *        The key/value store of player options.
4757    */
4758   function CaptionSettingsMenuItem(player, options) {
4759     _classCallCheck(this, CaptionSettingsMenuItem);
4761     options.track = {
4762       player: player,
4763       kind: options.kind,
4764       label: options.kind + ' settings',
4765       selectable: false,
4766       'default': false,
4767       mode: 'disabled'
4768     };
4770     // CaptionSettingsMenuItem has no concept of 'selected'
4771     options.selectable = false;
4773     var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
4775     _this.addClass('vjs-texttrack-settings');
4776     _this.controlText(', opens ' + options.kind + ' settings dialog');
4777     return _this;
4778   }
4780   /**
4781    * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
4782    * {@link ClickableComponent} for more detailed information on what a click can be.
4783    *
4784    * @param {EventTarget~Event} [event]
4785    *        The `keydown`, `tap`, or `click` event that caused this function to be
4786    *        called.
4787    *
4788    * @listens tap
4789    * @listens click
4790    */
4793   CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
4794     this.player().getChild('textTrackSettings').show();
4795     this.player().getChild('textTrackSettings').el_.focus();
4796   };
4798   return CaptionSettingsMenuItem;
4799 }(_textTrackMenuItem2['default']);
4801 _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
4802 exports['default'] = CaptionSettingsMenuItem;
4804 },{"31":31,"5":5}],24:[function(_dereq_,module,exports){
4805 'use strict';
4807 exports.__esModule = true;
4809 var _textTrackButton = _dereq_(30);
4811 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4813 var _component = _dereq_(5);
4815 var _component2 = _interopRequireDefault(_component);
4817 var _captionSettingsMenuItem = _dereq_(23);
4819 var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
4821 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4823 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4825 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4827 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4828                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file captions-button.js
4829                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4833  * The button component for toggling and selecting captions
4835  * @extends TextTrackButton
4836  */
4837 var CaptionsButton = function (_TextTrackButton) {
4838   _inherits(CaptionsButton, _TextTrackButton);
4840   /**
4841    * Creates an instance of this class.
4842    *
4843    * @param {Player} player
4844    *        The `Player` that this class should be attached to.
4845    *
4846    * @param {Object} [options]
4847    *        The key/value store of player options.
4848    *
4849    * @param {Component~ReadyCallback} [ready]
4850    *        The function to call when this component is ready.
4851    */
4852   function CaptionsButton(player, options, ready) {
4853     _classCallCheck(this, CaptionsButton);
4855     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4857     _this.el_.setAttribute('aria-label', 'Captions Menu');
4858     return _this;
4859   }
4861   /**
4862    * Builds the default DOM `className`.
4863    *
4864    * @return {string}
4865    *         The DOM `className` for this object.
4866    */
4869   CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
4870     return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
4871   };
4873   /**
4874    * Update caption menu items
4875    *
4876    * @param {EventTarget~Event} [event]
4877    *        The `addtrack` or `removetrack` event that caused this function to be
4878    *        called.
4879    *
4880    * @listens TextTrackList#addtrack
4881    * @listens TextTrackList#removetrack
4882    */
4885   CaptionsButton.prototype.update = function update(event) {
4886     var threshold = 2;
4888     _TextTrackButton.prototype.update.call(this);
4890     // if native, then threshold is 1 because no settings button
4891     if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) {
4892       threshold = 1;
4893     }
4895     if (this.items && this.items.length > threshold) {
4896       this.show();
4897     } else {
4898       this.hide();
4899     }
4900   };
4902   /**
4903    * Create caption menu items
4904    *
4905    * @return {CaptionSettingsMenuItem[]}
4906    *         The array of current menu items.
4907    */
4910   CaptionsButton.prototype.createItems = function createItems() {
4911     var items = [];
4913     if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
4914       items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
4915     }
4917     return _TextTrackButton.prototype.createItems.call(this, items);
4918   };
4920   return CaptionsButton;
4921 }(_textTrackButton2['default']);
4924  * `kind` of TextTrack to look for to associate it with this menu.
4926  * @type {string}
4927  * @private
4928  */
4931 CaptionsButton.prototype.kind_ = 'captions';
4934  * The text that should display over the `CaptionsButton`s controls. Added for localization.
4936  * @type {string}
4937  * @private
4938  */
4939 CaptionsButton.prototype.controlText_ = 'Captions';
4941 _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
4942 exports['default'] = CaptionsButton;
4944 },{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){
4945 'use strict';
4947 exports.__esModule = true;
4949 var _textTrackButton = _dereq_(30);
4951 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4953 var _component = _dereq_(5);
4955 var _component2 = _interopRequireDefault(_component);
4957 var _chaptersTrackMenuItem = _dereq_(26);
4959 var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
4961 var _toTitleCase = _dereq_(91);
4963 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
4965 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4967 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4969 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4971 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4972                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file chapters-button.js
4973                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4977  * The button component for toggling and selecting chapters
4978  * Chapters act much differently than other text tracks
4979  * Cues are navigation vs. other tracks of alternative languages
4981  * @extends TextTrackButton
4982  */
4983 var ChaptersButton = function (_TextTrackButton) {
4984   _inherits(ChaptersButton, _TextTrackButton);
4986   /**
4987    * Creates an instance of this class.
4988    *
4989    * @param {Player} player
4990    *        The `Player` that this class should be attached to.
4991    *
4992    * @param {Object} [options]
4993    *        The key/value store of player options.
4994    *
4995    * @param {Component~ReadyCallback} [ready]
4996    *        The function to call when this function is ready.
4997    */
4998   function ChaptersButton(player, options, ready) {
4999     _classCallCheck(this, ChaptersButton);
5001     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5003     _this.el_.setAttribute('aria-label', 'Chapters Menu');
5004     return _this;
5005   }
5007   /**
5008    * Builds the default DOM `className`.
5009    *
5010    * @return {string}
5011    *         The DOM `className` for this object.
5012    */
5015   ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
5016     return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5017   };
5019   /**
5020    * Update the menu based on the current state of its items.
5021    *
5022    * @param {EventTarget~Event} [event]
5023    *        An event that triggered this function to run.
5024    *
5025    * @listens TextTrackList#addtrack
5026    * @listens TextTrackList#removetrack
5027    * @listens TextTrackList#change
5028    */
5031   ChaptersButton.prototype.update = function update(event) {
5032     if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
5033       this.setTrack(this.findChaptersTrack());
5034     }
5035     _TextTrackButton.prototype.update.call(this);
5036   };
5038   /**
5039    * Set the currently selected track for the chapters button.
5040    *
5041    * @param {TextTrack} track
5042    *        The new track to select. Nothing will change if this is the currently selected
5043    *        track.
5044    */
5047   ChaptersButton.prototype.setTrack = function setTrack(track) {
5048     if (this.track_ === track) {
5049       return;
5050     }
5052     if (!this.updateHandler_) {
5053       this.updateHandler_ = this.update.bind(this);
5054     }
5056     // here this.track_ refers to the old track instance
5057     if (this.track_) {
5058       var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5060       if (remoteTextTrackEl) {
5061         remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
5062       }
5064       this.track_ = null;
5065     }
5067     this.track_ = track;
5069     // here this.track_ refers to the new track instance
5070     if (this.track_) {
5071       this.track_.mode = 'hidden';
5073       var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5075       if (_remoteTextTrackEl) {
5076         _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
5077       }
5078     }
5079   };
5081   /**
5082    * Find the track object that is currently in use by this ChaptersButton
5083    *
5084    * @return {TextTrack|undefined}
5085    *         The current track or undefined if none was found.
5086    */
5089   ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
5090     var tracks = this.player_.textTracks() || [];
5092     for (var i = tracks.length - 1; i >= 0; i--) {
5093       // We will always choose the last track as our chaptersTrack
5094       var track = tracks[i];
5096       if (track.kind === this.kind_) {
5097         return track;
5098       }
5099     }
5100   };
5102   /**
5103    * Get the caption for the ChaptersButton based on the track label. This will also
5104    * use the current tracks localized kind as a fallback if a label does not exist.
5105    *
5106    * @return {string}
5107    *         The tracks current label or the localized track kind.
5108    */
5111   ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
5112     if (this.track_ && this.track_.label) {
5113       return this.track_.label;
5114     }
5115     return this.localize((0, _toTitleCase2['default'])(this.kind_));
5116   };
5118   /**
5119    * Create menu from chapter track
5120    *
5121    * @return {Menu}
5122    *         New menu for the chapter buttons
5123    */
5126   ChaptersButton.prototype.createMenu = function createMenu() {
5127     this.options_.title = this.getMenuCaption();
5128     return _TextTrackButton.prototype.createMenu.call(this);
5129   };
5131   /**
5132    * Create a menu item for each text track
5133    *
5134    * @return {TextTrackMenuItem[]}
5135    *         Array of menu items
5136    */
5139   ChaptersButton.prototype.createItems = function createItems() {
5140     var items = [];
5142     if (!this.track_) {
5143       return items;
5144     }
5146     var cues = this.track_.cues;
5148     if (!cues) {
5149       return items;
5150     }
5152     for (var i = 0, l = cues.length; i < l; i++) {
5153       var cue = cues[i];
5154       var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
5156       items.push(mi);
5157     }
5159     return items;
5160   };
5162   return ChaptersButton;
5163 }(_textTrackButton2['default']);
5166  * `kind` of TextTrack to look for to associate it with this menu.
5168  * @type {string}
5169  * @private
5170  */
5173 ChaptersButton.prototype.kind_ = 'chapters';
5176  * The text that should display over the `ChaptersButton`s controls. Added for localization.
5178  * @type {string}
5179  * @private
5180  */
5181 ChaptersButton.prototype.controlText_ = 'Chapters';
5183 _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
5184 exports['default'] = ChaptersButton;
5186 },{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){
5187 'use strict';
5189 exports.__esModule = true;
5191 var _menuItem = _dereq_(48);
5193 var _menuItem2 = _interopRequireDefault(_menuItem);
5195 var _component = _dereq_(5);
5197 var _component2 = _interopRequireDefault(_component);
5199 var _fn = _dereq_(83);
5201 var Fn = _interopRequireWildcard(_fn);
5203 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5205 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5207 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5209 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5211 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5212                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file chapters-track-menu-item.js
5213                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5217  * The chapter track menu item
5219  * @extends MenuItem
5220  */
5221 var ChaptersTrackMenuItem = function (_MenuItem) {
5222   _inherits(ChaptersTrackMenuItem, _MenuItem);
5224   /**
5225    * Creates an instance of this class.
5226    *
5227    * @param {Player} player
5228    *        The `Player` that this class should be attached to.
5229    *
5230    * @param {Object} [options]
5231    *        The key/value store of player options.
5232    */
5233   function ChaptersTrackMenuItem(player, options) {
5234     _classCallCheck(this, ChaptersTrackMenuItem);
5236     var track = options.track;
5237     var cue = options.cue;
5238     var currentTime = player.currentTime();
5240     // Modify options for parent MenuItem class's init.
5241     options.selectable = true;
5242     options.label = cue.text;
5243     options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
5245     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5247     _this.track = track;
5248     _this.cue = cue;
5249     track.addEventListener('cuechange', Fn.bind(_this, _this.update));
5250     return _this;
5251   }
5253   /**
5254    * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
5255    * {@link ClickableComponent} for more detailed information on what a click can be.
5256    *
5257    * @param {EventTarget~Event} [event]
5258    *        The `keydown`, `tap`, or `click` event that caused this function to be
5259    *        called.
5260    *
5261    * @listens tap
5262    * @listens click
5263    */
5266   ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
5267     _MenuItem.prototype.handleClick.call(this);
5268     this.player_.currentTime(this.cue.startTime);
5269     this.update(this.cue.startTime);
5270   };
5272   /**
5273    * Update chapter menu item
5274    *
5275    * @param {EventTarget~Event} [event]
5276    *        The `cuechange` event that caused this function to run.
5277    *
5278    * @listens TextTrack#cuechange
5279    */
5282   ChaptersTrackMenuItem.prototype.update = function update(event) {
5283     var cue = this.cue;
5284     var currentTime = this.player_.currentTime();
5286     // vjs.log(currentTime, cue.startTime);
5287     this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
5288   };
5290   return ChaptersTrackMenuItem;
5291 }(_menuItem2['default']);
5293 _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
5294 exports['default'] = ChaptersTrackMenuItem;
5296 },{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){
5297 'use strict';
5299 exports.__esModule = true;
5301 var _textTrackButton = _dereq_(30);
5303 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5305 var _component = _dereq_(5);
5307 var _component2 = _interopRequireDefault(_component);
5309 var _fn = _dereq_(83);
5311 var Fn = _interopRequireWildcard(_fn);
5313 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5315 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5317 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5319 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5321 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5322                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file descriptions-button.js
5323                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5327  * The button component for toggling and selecting descriptions
5329  * @extends TextTrackButton
5330  */
5331 var DescriptionsButton = function (_TextTrackButton) {
5332   _inherits(DescriptionsButton, _TextTrackButton);
5334   /**
5335    * Creates an instance of this class.
5336    *
5337    * @param {Player} player
5338    *        The `Player` that this class should be attached to.
5339    *
5340    * @param {Object} [options]
5341    *        The key/value store of player options.
5342    *
5343    * @param {Component~ReadyCallback} [ready]
5344    *        The function to call when this component is ready.
5345    */
5346   function DescriptionsButton(player, options, ready) {
5347     _classCallCheck(this, DescriptionsButton);
5349     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5351     _this.el_.setAttribute('aria-label', 'Descriptions Menu');
5353     var tracks = player.textTracks();
5355     if (tracks) {
5356       (function () {
5357         var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5359         tracks.addEventListener('change', changeHandler);
5360         _this.on('dispose', function () {
5361           tracks.removeEventListener('change', changeHandler);
5362         });
5363       })();
5364     }
5365     return _this;
5366   }
5368   /**
5369    * Handle text track change
5370    *
5371    * @param {EventTarget~Event} event
5372    *        The event that caused this function to run
5373    *
5374    * @listens TextTrackList#change
5375    */
5378   DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
5379     var tracks = this.player().textTracks();
5380     var disabled = false;
5382     // Check whether a track of a different kind is showing
5383     for (var i = 0, l = tracks.length; i < l; i++) {
5384       var track = tracks[i];
5386       if (track.kind !== this.kind_ && track.mode === 'showing') {
5387         disabled = true;
5388         break;
5389       }
5390     }
5392     // If another track is showing, disable this menu button
5393     if (disabled) {
5394       this.disable();
5395     } else {
5396       this.enable();
5397     }
5398   };
5400   /**
5401    * Builds the default DOM `className`.
5402    *
5403    * @return {string}
5404    *         The DOM `className` for this object.
5405    */
5408   DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
5409     return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5410   };
5412   return DescriptionsButton;
5413 }(_textTrackButton2['default']);
5416  * `kind` of TextTrack to look for to associate it with this menu.
5418  * @type {string}
5419  * @private
5420  */
5423 DescriptionsButton.prototype.kind_ = 'descriptions';
5426  * The text that should display over the `DescriptionsButton`s controls. Added for localization.
5428  * @type {string}
5429  * @private
5430  */
5431 DescriptionsButton.prototype.controlText_ = 'Descriptions';
5433 _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
5434 exports['default'] = DescriptionsButton;
5436 },{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){
5437 'use strict';
5439 exports.__esModule = true;
5441 var _textTrackMenuItem = _dereq_(31);
5443 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5445 var _component = _dereq_(5);
5447 var _component2 = _interopRequireDefault(_component);
5449 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5451 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5453 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5455 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5456                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file off-text-track-menu-item.js
5457                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5461  * A special menu item for turning of a specific type of text track
5463  * @extends TextTrackMenuItem
5464  */
5465 var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
5466   _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
5468   /**
5469    * Creates an instance of this class.
5470    *
5471    * @param {Player} player
5472    *        The `Player` that this class should be attached to.
5473    *
5474    * @param {Object} [options]
5475    *        The key/value store of player options.
5476    */
5477   function OffTextTrackMenuItem(player, options) {
5478     _classCallCheck(this, OffTextTrackMenuItem);
5480     // Create pseudo track info
5481     // Requires options['kind']
5482     options.track = {
5483       player: player,
5484       kind: options.kind,
5485       label: options.kind + ' off',
5486       'default': false,
5487       mode: 'disabled'
5488     };
5490     // MenuItem is selectable
5491     options.selectable = true;
5493     var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
5495     _this.selected(true);
5496     return _this;
5497   }
5499   /**
5500    * Handle text track change
5501    *
5502    * @param {EventTarget~Event} event
5503    *        The event that caused this function to run
5504    */
5507   OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5508     var tracks = this.player().textTracks();
5509     var selected = true;
5511     for (var i = 0, l = tracks.length; i < l; i++) {
5512       var track = tracks[i];
5514       if (track.kind === this.track.kind && track.mode === 'showing') {
5515         selected = false;
5516         break;
5517       }
5518     }
5520     this.selected(selected);
5521   };
5523   return OffTextTrackMenuItem;
5524 }(_textTrackMenuItem2['default']);
5526 _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
5527 exports['default'] = OffTextTrackMenuItem;
5529 },{"31":31,"5":5}],29:[function(_dereq_,module,exports){
5530 'use strict';
5532 exports.__esModule = true;
5534 var _textTrackButton = _dereq_(30);
5536 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5538 var _component = _dereq_(5);
5540 var _component2 = _interopRequireDefault(_component);
5542 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5544 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5546 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5548 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5549                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file subtitles-button.js
5550                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5554  * The button component for toggling and selecting subtitles
5556  * @extends TextTrackButton
5557  */
5558 var SubtitlesButton = function (_TextTrackButton) {
5559   _inherits(SubtitlesButton, _TextTrackButton);
5561   /**
5562    * Creates an instance of this class.
5563    *
5564    * @param {Player} player
5565    *        The `Player` that this class should be attached to.
5566    *
5567    * @param {Object} [options]
5568    *        The key/value store of player options.
5569    *
5570    * @param {Component~ReadyCallback} [ready]
5571    *        The function to call when this component is ready.
5572    */
5573   function SubtitlesButton(player, options, ready) {
5574     _classCallCheck(this, SubtitlesButton);
5576     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5578     _this.el_.setAttribute('aria-label', 'Subtitles Menu');
5579     return _this;
5580   }
5582   /**
5583    * Builds the default DOM `className`.
5584    *
5585    * @return {string}
5586    *         The DOM `className` for this object.
5587    */
5590   SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
5591     return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5592   };
5594   return SubtitlesButton;
5595 }(_textTrackButton2['default']);
5598  * `kind` of TextTrack to look for to associate it with this menu.
5600  * @type {string}
5601  * @private
5602  */
5605 SubtitlesButton.prototype.kind_ = 'subtitles';
5608  * The text that should display over the `SubtitlesButton`s controls. Added for localization.
5610  * @type {string}
5611  * @private
5612  */
5613 SubtitlesButton.prototype.controlText_ = 'Subtitles';
5615 _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
5616 exports['default'] = SubtitlesButton;
5618 },{"30":30,"5":5}],30:[function(_dereq_,module,exports){
5619 'use strict';
5621 exports.__esModule = true;
5623 var _trackButton = _dereq_(36);
5625 var _trackButton2 = _interopRequireDefault(_trackButton);
5627 var _component = _dereq_(5);
5629 var _component2 = _interopRequireDefault(_component);
5631 var _textTrackMenuItem = _dereq_(31);
5633 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5635 var _offTextTrackMenuItem = _dereq_(28);
5637 var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
5639 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5641 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5643 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5645 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5646                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-button.js
5647                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5651  * The base class for buttons that toggle specific text track types (e.g. subtitles)
5653  * @extends MenuButton
5654  */
5655 var TextTrackButton = function (_TrackButton) {
5656   _inherits(TextTrackButton, _TrackButton);
5658   /**
5659    * Creates an instance of this class.
5660    *
5661    * @param {Player} player
5662    *        The `Player` that this class should be attached to.
5663    *
5664    * @param {Object} [options={}]
5665    *        The key/value store of player options.
5666    */
5667   function TextTrackButton(player) {
5668     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5670     _classCallCheck(this, TextTrackButton);
5672     options.tracks = player.textTracks();
5674     return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
5675   }
5677   /**
5678    * Create a menu item for each text track
5679    *
5680    * @param {TextTrackMenuItem[]} [items=[]]
5681    *        Existing array of items to use during creation
5682    *
5683    * @return {TextTrackMenuItem[]}
5684    *         Array of menu items that were created
5685    */
5688   TextTrackButton.prototype.createItems = function createItems() {
5689     var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5691     // Add an OFF menu item to turn all tracks off
5692     items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
5694     var tracks = this.player_.textTracks();
5696     if (!tracks) {
5697       return items;
5698     }
5700     for (var i = 0; i < tracks.length; i++) {
5701       var track = tracks[i];
5703       // only add tracks that are of the appropriate kind and have a label
5704       if (track.kind === this.kind_) {
5705         items.push(new _textTrackMenuItem2['default'](this.player_, {
5706           track: track,
5707           // MenuItem is selectable
5708           selectable: true
5709         }));
5710       }
5711     }
5713     return items;
5714   };
5716   return TextTrackButton;
5717 }(_trackButton2['default']);
5719 _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
5720 exports['default'] = TextTrackButton;
5722 },{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){
5723 'use strict';
5725 exports.__esModule = true;
5727 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
5729 var _menuItem = _dereq_(48);
5731 var _menuItem2 = _interopRequireDefault(_menuItem);
5733 var _component = _dereq_(5);
5735 var _component2 = _interopRequireDefault(_component);
5737 var _fn = _dereq_(83);
5739 var Fn = _interopRequireWildcard(_fn);
5741 var _window = _dereq_(95);
5743 var _window2 = _interopRequireDefault(_window);
5745 var _document = _dereq_(94);
5747 var _document2 = _interopRequireDefault(_document);
5749 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5751 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5753 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5755 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5757 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5758                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-menu-item.js
5759                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5763  * The specific menu item type for selecting a language within a text track kind
5765  * @extends MenuItem
5766  */
5767 var TextTrackMenuItem = function (_MenuItem) {
5768   _inherits(TextTrackMenuItem, _MenuItem);
5770   /**
5771    * Creates an instance of this class.
5772    *
5773    * @param {Player} player
5774    *        The `Player` that this class should be attached to.
5775    *
5776    * @param {Object} [options]
5777    *        The key/value store of player options.
5778    */
5779   function TextTrackMenuItem(player, options) {
5780     _classCallCheck(this, TextTrackMenuItem);
5782     var track = options.track;
5783     var tracks = player.textTracks();
5785     // Modify options for parent MenuItem class's init.
5786     options.label = track.label || track.language || 'Unknown';
5787     options.selected = track['default'] || track.mode === 'showing';
5789     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5791     _this.track = track;
5793     if (tracks) {
5794       (function () {
5795         var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5797         tracks.addEventListener('change', changeHandler);
5798         _this.on('dispose', function () {
5799           tracks.removeEventListener('change', changeHandler);
5800         });
5801       })();
5802     }
5804     // iOS7 doesn't dispatch change events to TextTrackLists when an
5805     // associated track's mode changes. Without something like
5806     // Object.observe() (also not present on iOS7), it's not
5807     // possible to detect changes to the mode attribute and polyfill
5808     // the change event. As a poor substitute, we manually dispatch
5809     // change events whenever the controls modify the mode.
5810     if (tracks && tracks.onchange === undefined) {
5811       (function () {
5812         var event = void 0;
5814         _this.on(['tap', 'click'], function () {
5815           if (_typeof(_window2['default'].Event) !== 'object') {
5816             // Android 2.3 throws an Illegal Constructor error for window.Event
5817             try {
5818               event = new _window2['default'].Event('change');
5819             } catch (err) {
5820               // continue regardless of error
5821             }
5822           }
5824           if (!event) {
5825             event = _document2['default'].createEvent('Event');
5826             event.initEvent('change', true, true);
5827           }
5829           tracks.dispatchEvent(event);
5830         });
5831       })();
5832     }
5833     return _this;
5834   }
5836   /**
5837    * This gets called when an `TextTrackMenuItem` is "clicked". See
5838    * {@link ClickableComponent} for more detailed information on what a click can be.
5839    *
5840    * @param {EventTarget~Event} event
5841    *        The `keydown`, `tap`, or `click` event that caused this function to be
5842    *        called.
5843    *
5844    * @listens tap
5845    * @listens click
5846    */
5849   TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
5850     var kind = this.track.kind;
5851     var tracks = this.player_.textTracks();
5853     _MenuItem.prototype.handleClick.call(this, event);
5855     if (!tracks) {
5856       return;
5857     }
5859     for (var i = 0; i < tracks.length; i++) {
5860       var track = tracks[i];
5862       if (track.kind !== kind) {
5863         continue;
5864       }
5866       if (track === this.track) {
5867         track.mode = 'showing';
5868       } else {
5869         track.mode = 'disabled';
5870       }
5871     }
5872   };
5874   /**
5875    * Handle text track list change
5876    *
5877    * @param {EventTarget~Event} event
5878    *        The `change` event that caused this function to be called.
5879    *
5880    * @listens TextTrackList#change
5881    */
5884   TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5885     this.selected(this.track.mode === 'showing');
5886   };
5888   return TextTrackMenuItem;
5889 }(_menuItem2['default']);
5891 _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
5892 exports['default'] = TextTrackMenuItem;
5894 },{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){
5895 'use strict';
5897 exports.__esModule = true;
5899 var _component = _dereq_(5);
5901 var _component2 = _interopRequireDefault(_component);
5903 var _dom = _dereq_(81);
5905 var Dom = _interopRequireWildcard(_dom);
5907 var _formatTime = _dereq_(84);
5909 var _formatTime2 = _interopRequireDefault(_formatTime);
5911 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5913 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5915 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5917 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5919 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5920                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file current-time-display.js
5921                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5925  * Displays the current time
5927  * @extends Component
5928  */
5929 var CurrentTimeDisplay = function (_Component) {
5930   _inherits(CurrentTimeDisplay, _Component);
5932   /**
5933    * Creates an instance of this class.
5934    *
5935    * @param {Player} player
5936    *        The `Player` that this class should be attached to.
5937    *
5938    * @param {Object} [options]
5939    *        The key/value store of player options.
5940    */
5941   function CurrentTimeDisplay(player, options) {
5942     _classCallCheck(this, CurrentTimeDisplay);
5944     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
5946     _this.on(player, 'timeupdate', _this.updateContent);
5947     return _this;
5948   }
5950   /**
5951    * Create the `Component`'s DOM element
5952    *
5953    * @return {Element}
5954    *         The element that was created.
5955    */
5958   CurrentTimeDisplay.prototype.createEl = function createEl() {
5959     var el = _Component.prototype.createEl.call(this, 'div', {
5960       className: 'vjs-current-time vjs-time-control vjs-control'
5961     });
5963     this.contentEl_ = Dom.createEl('div', {
5964       className: 'vjs-current-time-display',
5965       // label the current time for screen reader users
5966       innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
5967     }, {
5968       // tell screen readers not to automatically read the time as it changes
5969       'aria-live': 'off'
5970     });
5972     el.appendChild(this.contentEl_);
5973     return el;
5974   };
5976   /**
5977    * Update current time display
5978    *
5979    * @param {EventTarget~Event} [event]
5980    *        The `timeupdate` event that caused this function to run.
5981    *
5982    * @listens Player#timeupdate
5983    */
5986   CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
5987     // Allows for smooth scrubbing, when player can't keep up.
5988     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5989     var localizedText = this.localize('Current Time');
5990     var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
5992     if (formattedTime !== this.formattedTime_) {
5993       this.formattedTime_ = formattedTime;
5994       this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
5995     }
5996   };
5998   return CurrentTimeDisplay;
5999 }(_component2['default']);
6001 _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
6002 exports['default'] = CurrentTimeDisplay;
6004 },{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){
6005 'use strict';
6007 exports.__esModule = true;
6009 var _component = _dereq_(5);
6011 var _component2 = _interopRequireDefault(_component);
6013 var _dom = _dereq_(81);
6015 var Dom = _interopRequireWildcard(_dom);
6017 var _formatTime = _dereq_(84);
6019 var _formatTime2 = _interopRequireDefault(_formatTime);
6021 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6023 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6025 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6027 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6029 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6030                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file duration-display.js
6031                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6035  * Displays the duration
6037  * @extends Component
6038  */
6039 var DurationDisplay = function (_Component) {
6040   _inherits(DurationDisplay, _Component);
6042   /**
6043    * Creates an instance of this class.
6044    *
6045    * @param {Player} player
6046    *        The `Player` that this class should be attached to.
6047    *
6048    * @param {Object} [options]
6049    *        The key/value store of player options.
6050    */
6051   function DurationDisplay(player, options) {
6052     _classCallCheck(this, DurationDisplay);
6054     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6056     _this.on(player, 'durationchange', _this.updateContent);
6058     // Also listen for timeupdate and loadedmetadata because removing those
6059     // listeners could have broken dependent applications/libraries. These
6060     // can likely be removed for 6.0.
6061     _this.on(player, 'timeupdate', _this.updateContent);
6062     _this.on(player, 'loadedmetadata', _this.updateContent);
6063     return _this;
6064   }
6066   /**
6067    * Create the `Component`'s DOM element
6068    *
6069    * @return {Element}
6070    *         The element that was created.
6071    */
6074   DurationDisplay.prototype.createEl = function createEl() {
6075     var el = _Component.prototype.createEl.call(this, 'div', {
6076       className: 'vjs-duration vjs-time-control vjs-control'
6077     });
6079     this.contentEl_ = Dom.createEl('div', {
6080       className: 'vjs-duration-display',
6081       // label the duration time for screen reader users
6082       innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
6083     }, {
6084       // tell screen readers not to automatically read the time as it changes
6085       'aria-live': 'off'
6086     });
6088     el.appendChild(this.contentEl_);
6089     return el;
6090   };
6092   /**
6093    * Update duration time display.
6094    *
6095    * @param {EventTarget~Event} [event]
6096    *        The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
6097    *        this function to be called.
6098    *
6099    * @listens Player#durationchange
6100    * @listens Player#timeupdate
6101    * @listens Player#loadedmetadata
6102    */
6105   DurationDisplay.prototype.updateContent = function updateContent(event) {
6106     var duration = this.player_.duration();
6108     if (duration && this.duration_ !== duration) {
6109       this.duration_ = duration;
6110       var localizedText = this.localize('Duration Time');
6111       var formattedTime = (0, _formatTime2['default'])(duration);
6113       // label the duration time for screen reader users
6114       this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
6115     }
6116   };
6118   return DurationDisplay;
6119 }(_component2['default']);
6121 _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
6122 exports['default'] = DurationDisplay;
6124 },{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){
6125 'use strict';
6127 exports.__esModule = true;
6129 var _component = _dereq_(5);
6131 var _component2 = _interopRequireDefault(_component);
6133 var _dom = _dereq_(81);
6135 var Dom = _interopRequireWildcard(_dom);
6137 var _formatTime = _dereq_(84);
6139 var _formatTime2 = _interopRequireDefault(_formatTime);
6141 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6143 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6145 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6147 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6149 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6150                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file remaining-time-display.js
6151                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6155  * Displays the time left in the video
6157  * @extends Component
6158  */
6159 var RemainingTimeDisplay = function (_Component) {
6160   _inherits(RemainingTimeDisplay, _Component);
6162   /**
6163    * Creates an instance of this class.
6164    *
6165    * @param {Player} player
6166    *        The `Player` that this class should be attached to.
6167    *
6168    * @param {Object} [options]
6169    *        The key/value store of player options.
6170    */
6171   function RemainingTimeDisplay(player, options) {
6172     _classCallCheck(this, RemainingTimeDisplay);
6174     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6176     _this.on(player, 'timeupdate', _this.updateContent);
6177     _this.on(player, 'durationchange', _this.updateContent);
6178     return _this;
6179   }
6181   /**
6182    * Create the `Component`'s DOM element
6183    *
6184    * @return {Element}
6185    *         The element that was created.
6186    */
6189   RemainingTimeDisplay.prototype.createEl = function createEl() {
6190     var el = _Component.prototype.createEl.call(this, 'div', {
6191       className: 'vjs-remaining-time vjs-time-control vjs-control'
6192     });
6194     this.contentEl_ = Dom.createEl('div', {
6195       className: 'vjs-remaining-time-display',
6196       // label the remaining time for screen reader users
6197       innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
6198     }, {
6199       // tell screen readers not to automatically read the time as it changes
6200       'aria-live': 'off'
6201     });
6203     el.appendChild(this.contentEl_);
6204     return el;
6205   };
6207   /**
6208    * Update remaining time display.
6209    *
6210    * @param {EventTarget~Event} [event]
6211    *        The `timeupdate` or `durationchange` event that caused this to run.
6212    *
6213    * @listens Player#timeupdate
6214    * @listens Player#durationchange
6215    */
6218   RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
6219     if (this.player_.duration()) {
6220       var localizedText = this.localize('Remaining Time');
6221       var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
6223       if (formattedTime !== this.formattedTime_) {
6224         this.formattedTime_ = formattedTime;
6225         this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
6226       }
6227     }
6229     // Allows for smooth scrubbing, when player can't keep up.
6230     // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
6231     // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
6232   };
6234   return RemainingTimeDisplay;
6235 }(_component2['default']);
6237 _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
6238 exports['default'] = RemainingTimeDisplay;
6240 },{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){
6241 'use strict';
6243 exports.__esModule = true;
6245 var _component = _dereq_(5);
6247 var _component2 = _interopRequireDefault(_component);
6249 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6251 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6253 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6255 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6256                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file time-divider.js
6257                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6261  * The separator between the current time and duration.
6262  * Can be hidden if it's not needed in the design.
6264  * @extends Component
6265  */
6266 var TimeDivider = function (_Component) {
6267   _inherits(TimeDivider, _Component);
6269   function TimeDivider() {
6270     _classCallCheck(this, TimeDivider);
6272     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6273   }
6275   /**
6276    * Create the component's DOM element
6277    *
6278    * @return {Element}
6279    *         The element that was created.
6280    */
6281   TimeDivider.prototype.createEl = function createEl() {
6282     return _Component.prototype.createEl.call(this, 'div', {
6283       className: 'vjs-time-control vjs-time-divider',
6284       innerHTML: '<div><span>/</span></div>'
6285     });
6286   };
6288   return TimeDivider;
6289 }(_component2['default']);
6291 _component2['default'].registerComponent('TimeDivider', TimeDivider);
6292 exports['default'] = TimeDivider;
6294 },{"5":5}],36:[function(_dereq_,module,exports){
6295 'use strict';
6297 exports.__esModule = true;
6299 var _menuButton = _dereq_(47);
6301 var _menuButton2 = _interopRequireDefault(_menuButton);
6303 var _component = _dereq_(5);
6305 var _component2 = _interopRequireDefault(_component);
6307 var _fn = _dereq_(83);
6309 var Fn = _interopRequireWildcard(_fn);
6311 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6313 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6315 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6317 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6319 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6320                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track-button.js
6321                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6325  * The base class for buttons that toggle specific  track types (e.g. subtitles).
6327  * @extends MenuButton
6328  */
6329 var TrackButton = function (_MenuButton) {
6330   _inherits(TrackButton, _MenuButton);
6332   /**
6333    * Creates an instance of this class.
6334    *
6335    * @param {Player} player
6336    *        The `Player` that this class should be attached to.
6337    *
6338    * @param {Object} [options]
6339    *        The key/value store of player options.
6340    */
6341   function TrackButton(player, options) {
6342     _classCallCheck(this, TrackButton);
6344     var tracks = options.tracks;
6346     var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
6348     if (_this.items.length <= 1) {
6349       _this.hide();
6350     }
6352     if (!tracks) {
6353       return _possibleConstructorReturn(_this);
6354     }
6356     var updateHandler = Fn.bind(_this, _this.update);
6358     tracks.addEventListener('removetrack', updateHandler);
6359     tracks.addEventListener('addtrack', updateHandler);
6361     _this.player_.on('dispose', function () {
6362       tracks.removeEventListener('removetrack', updateHandler);
6363       tracks.removeEventListener('addtrack', updateHandler);
6364     });
6365     return _this;
6366   }
6368   return TrackButton;
6369 }(_menuButton2['default']);
6371 _component2['default'].registerComponent('TrackButton', TrackButton);
6372 exports['default'] = TrackButton;
6374 },{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){
6375 'use strict';
6377 exports.__esModule = true;
6379 var _slider = _dereq_(57);
6381 var _slider2 = _interopRequireDefault(_slider);
6383 var _component = _dereq_(5);
6385 var _component2 = _interopRequireDefault(_component);
6387 var _fn = _dereq_(83);
6389 var Fn = _interopRequireWildcard(_fn);
6391 _dereq_(39);
6393 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6395 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6397 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6399 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6401 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6402                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-bar.js
6403                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6406 // Required children
6410  * The bar that contains the volume level and can be clicked on to adjust the level
6412  * @extends Slider
6413  */
6414 var VolumeBar = function (_Slider) {
6415   _inherits(VolumeBar, _Slider);
6417   /**
6418    * Creates an instance of this class.
6419    *
6420    * @param {Player} player
6421    *        The `Player` that this class should be attached to.
6422    *
6423    * @param {Object} [options]
6424    *        The key/value store of player options.
6425    */
6426   function VolumeBar(player, options) {
6427     _classCallCheck(this, VolumeBar);
6429     var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
6431     _this.on(player, 'volumechange', _this.updateARIAAttributes);
6432     player.ready(Fn.bind(_this, _this.updateARIAAttributes));
6433     return _this;
6434   }
6436   /**
6437    * Create the `Component`'s DOM element
6438    *
6439    * @return {Element}
6440    *         The element that was created.
6441    */
6444   VolumeBar.prototype.createEl = function createEl() {
6445     return _Slider.prototype.createEl.call(this, 'div', {
6446       className: 'vjs-volume-bar vjs-slider-bar'
6447     }, {
6448       'aria-label': 'volume level'
6449     });
6450   };
6452   /**
6453    * Handle movement events on the {@link VolumeMenuButton}.
6454    *
6455    * @param {EventTarget~Event} event
6456    *        The event that caused this function to run.
6457    *
6458    * @listens mousemove
6459    */
6462   VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
6463     this.checkMuted();
6464     this.player_.volume(this.calculateDistance(event));
6465   };
6467   /**
6468    * If the player is muted unmute it.
6469    */
6472   VolumeBar.prototype.checkMuted = function checkMuted() {
6473     if (this.player_.muted()) {
6474       this.player_.muted(false);
6475     }
6476   };
6478   /**
6479    * Get percent of volume level
6480    *
6481    * @return {number}
6482    *         Volume level percent as a decimal number.
6483    */
6486   VolumeBar.prototype.getPercent = function getPercent() {
6487     if (this.player_.muted()) {
6488       return 0;
6489     }
6490     return this.player_.volume();
6491   };
6493   /**
6494    * Increase volume level for keyboard users
6495    */
6498   VolumeBar.prototype.stepForward = function stepForward() {
6499     this.checkMuted();
6500     this.player_.volume(this.player_.volume() + 0.1);
6501   };
6503   /**
6504    * Decrease volume level for keyboard users
6505    */
6508   VolumeBar.prototype.stepBack = function stepBack() {
6509     this.checkMuted();
6510     this.player_.volume(this.player_.volume() - 0.1);
6511   };
6513   /**
6514    * Update ARIA accessibility attributes
6515    *
6516    * @param {EventTarget~Event} [event]
6517    *        The `volumechange` event that caused this function to run.
6518    *
6519    * @listens Player#volumechange
6520    */
6523   VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
6524     // Current value of volume bar as a percentage
6525     var volume = (this.player_.volume() * 100).toFixed(2);
6527     this.el_.setAttribute('aria-valuenow', volume);
6528     this.el_.setAttribute('aria-valuetext', volume + '%');
6529   };
6531   return VolumeBar;
6532 }(_slider2['default']);
6535  * Default options for the `VolumeBar`
6537  * @type {Object}
6538  * @private
6539  */
6542 VolumeBar.prototype.options_ = {
6543   children: ['volumeLevel'],
6544   barName: 'volumeLevel'
6548  * Call the update event for this Slider when this event happens on the player.
6550  * @type {string}
6551  */
6552 VolumeBar.prototype.playerEvent = 'volumechange';
6554 _component2['default'].registerComponent('VolumeBar', VolumeBar);
6555 exports['default'] = VolumeBar;
6557 },{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){
6558 'use strict';
6560 exports.__esModule = true;
6562 var _component = _dereq_(5);
6564 var _component2 = _interopRequireDefault(_component);
6566 _dereq_(37);
6568 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6570 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6572 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6574 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6575                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-control.js
6576                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6579 // Required children
6583  * The component for controlling the volume level
6585  * @extends Component
6586  */
6587 var VolumeControl = function (_Component) {
6588   _inherits(VolumeControl, _Component);
6590   /**
6591    * Creates an instance of this class.
6592    *
6593    * @param {Player} player
6594    *        The `Player` that this class should be attached to.
6595    *
6596    * @param {Object} [options={}]
6597    *        The key/value store of player options.
6598    */
6599   function VolumeControl(player, options) {
6600     _classCallCheck(this, VolumeControl);
6602     // hide volume controls when they're not supported by the current tech
6603     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6605     if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6606       _this.addClass('vjs-hidden');
6607     }
6608     _this.on(player, 'loadstart', function () {
6609       if (player.tech_.featuresVolumeControl === false) {
6610         this.addClass('vjs-hidden');
6611       } else {
6612         this.removeClass('vjs-hidden');
6613       }
6614     });
6615     return _this;
6616   }
6618   /**
6619    * Create the `Component`'s DOM element
6620    *
6621    * @return {Element}
6622    *         The element that was created.
6623    */
6626   VolumeControl.prototype.createEl = function createEl() {
6627     return _Component.prototype.createEl.call(this, 'div', {
6628       className: 'vjs-volume-control vjs-control'
6629     });
6630   };
6632   return VolumeControl;
6633 }(_component2['default']);
6636  * Default options for the `VolumeControl`
6638  * @type {Object}
6639  * @private
6640  */
6643 VolumeControl.prototype.options_ = {
6644   children: ['volumeBar']
6647 _component2['default'].registerComponent('VolumeControl', VolumeControl);
6648 exports['default'] = VolumeControl;
6650 },{"37":37,"5":5}],39:[function(_dereq_,module,exports){
6651 'use strict';
6653 exports.__esModule = true;
6655 var _component = _dereq_(5);
6657 var _component2 = _interopRequireDefault(_component);
6659 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6661 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6663 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6665 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6666                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-level.js
6667                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6671  * Shows volume level
6673  * @extends Component
6674  */
6675 var VolumeLevel = function (_Component) {
6676   _inherits(VolumeLevel, _Component);
6678   function VolumeLevel() {
6679     _classCallCheck(this, VolumeLevel);
6681     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6682   }
6684   /**
6685    * Create the `Component`'s DOM element
6686    *
6687    * @return {Element}
6688    *         The element that was created.
6689    */
6690   VolumeLevel.prototype.createEl = function createEl() {
6691     return _Component.prototype.createEl.call(this, 'div', {
6692       className: 'vjs-volume-level',
6693       innerHTML: '<span class="vjs-control-text"></span>'
6694     });
6695   };
6697   return VolumeLevel;
6698 }(_component2['default']);
6700 _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
6701 exports['default'] = VolumeLevel;
6703 },{"5":5}],40:[function(_dereq_,module,exports){
6704 'use strict';
6706 exports.__esModule = true;
6708 var _fn = _dereq_(83);
6710 var Fn = _interopRequireWildcard(_fn);
6712 var _component = _dereq_(5);
6714 var _component2 = _interopRequireDefault(_component);
6716 var _popup = _dereq_(54);
6718 var _popup2 = _interopRequireDefault(_popup);
6720 var _popupButton = _dereq_(53);
6722 var _popupButton2 = _interopRequireDefault(_popupButton);
6724 var _muteToggle = _dereq_(11);
6726 var _muteToggle2 = _interopRequireDefault(_muteToggle);
6728 var _volumeBar = _dereq_(37);
6730 var _volumeBar2 = _interopRequireDefault(_volumeBar);
6732 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6734 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6736 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6738 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6740 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6741                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-menu-button.js
6742                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6746  * Button for volume popup
6748  * @extends PopupButton
6749  */
6750 var VolumeMenuButton = function (_PopupButton) {
6751   _inherits(VolumeMenuButton, _PopupButton);
6753   /**
6754    * Creates an instance of this class.
6755    *
6756    * @param {Player} player
6757    *        The `Player` that this class should be attached to.
6758    *
6759    * @param {Object} [options={}]
6760    *        The key/value store of player options.
6761    */
6762   function VolumeMenuButton(player) {
6763     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6765     _classCallCheck(this, VolumeMenuButton);
6767     // Default to inline
6768     if (options.inline === undefined) {
6769       options.inline = true;
6770     }
6772     // If the vertical option isn't passed at all, default to true.
6773     if (options.vertical === undefined) {
6774       // If an inline volumeMenuButton is used, we should default to using
6775       // a horizontal slider for obvious reasons.
6776       if (options.inline) {
6777         options.vertical = false;
6778       } else {
6779         options.vertical = true;
6780       }
6781     }
6783     // The vertical option needs to be set on the volumeBar as well,
6784     // since that will need to be passed along to the VolumeBar constructor
6785     options.volumeBar = options.volumeBar || {};
6786     options.volumeBar.vertical = !!options.vertical;
6788     // Same listeners as MuteToggle
6789     var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
6791     _this.on(player, 'volumechange', _this.volumeUpdate);
6792     _this.on(player, 'loadstart', _this.volumeUpdate);
6794     // hide mute toggle if the current tech doesn't support volume control
6795     function updateVisibility() {
6796       if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6797         this.addClass('vjs-hidden');
6798       } else {
6799         this.removeClass('vjs-hidden');
6800       }
6801     }
6803     updateVisibility.call(_this);
6804     _this.on(player, 'loadstart', updateVisibility);
6806     _this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
6807       this.addClass('vjs-slider-active');
6808     });
6810     _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
6811       this.removeClass('vjs-slider-active');
6812     });
6814     _this.on(_this.volumeBar, ['focus'], function () {
6815       this.addClass('vjs-lock-showing');
6816     });
6818     _this.on(_this.volumeBar, ['blur'], function () {
6819       this.removeClass('vjs-lock-showing');
6820     });
6821     return _this;
6822   }
6824   /**
6825    * Builds the default DOM `className`.
6826    *
6827    * @return {string}
6828    *         The DOM `className` for this object.
6829    */
6832   VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
6833     var orientationClass = '';
6835     if (this.options_.vertical) {
6836       orientationClass = 'vjs-volume-menu-button-vertical';
6837     } else {
6838       orientationClass = 'vjs-volume-menu-button-horizontal';
6839     }
6841     return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
6842   };
6844   /**
6845    * Create the VolumeMenuButton popup
6846    *
6847    * @return {Popup}
6848    *         The popup that was created
6849    */
6852   VolumeMenuButton.prototype.createPopup = function createPopup() {
6853     var popup = new _popup2['default'](this.player_, {
6854       contentElType: 'div'
6855     });
6857     var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
6859     popup.addChild(vb);
6861     this.menuContent = popup;
6862     this.volumeBar = vb;
6864     this.attachVolumeBarEvents();
6866     return popup;
6867   };
6869   /**
6870    * This gets called when an `VolumeMenuButton` is "clicked". See
6871    * {@link ClickableComponent} for more detailed information on what a click can be.
6872    *
6873    * @param {EventTarget~Event} [event]
6874    *        The `keydown`, `tap`, or `click` event that caused this function to be
6875    *        called.
6876    *
6877    * @listens tap
6878    * @listens click
6879    */
6882   VolumeMenuButton.prototype.handleClick = function handleClick(event) {
6883     _muteToggle2['default'].prototype.handleClick.call(this);
6884     _PopupButton.prototype.handleClick.call(this);
6885   };
6887   /**
6888    * Add events listeners to the created `VolumeBar`.
6889    */
6892   VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
6893     this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
6894   };
6896   /**
6897    * Handle the `mousedown` and `touchdown` events on the `VolumeBar`
6898    *
6899    * @param {EventTarget~Event} [event]
6900    *        The `mousedown` or `touchdown` event that caused this to run.
6901    *
6902    * @listens mousedown
6903    * @listens touchdown
6904    */
6907   VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
6908     this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6909     this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
6910   };
6912   /**
6913    * Handle the `mouseup` and `touchend` events on the `VolumeBar`
6914    *
6915    * @param {EventTarget~Event} [event]
6916    *        The `mouseup` or `touchend` event that caused this to run.
6917    *
6918    * @listens mouseup
6919    * @listens touchend
6920    */
6923   VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
6924     this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6925   };
6927   return VolumeMenuButton;
6928 }(_popupButton2['default']);
6931  * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
6932  */
6935 VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
6938  * The text that should display over the `VolumeMenuButton`s controls. Added for localization.
6940  * @type {string}
6941  * @private
6942  */
6943 VolumeMenuButton.prototype.controlText_ = 'Mute';
6945 _component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
6946 exports['default'] = VolumeMenuButton;
6948 },{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){
6949 'use strict';
6951 exports.__esModule = true;
6953 var _component = _dereq_(5);
6955 var _component2 = _interopRequireDefault(_component);
6957 var _modalDialog = _dereq_(50);
6959 var _modalDialog2 = _interopRequireDefault(_modalDialog);
6961 var _mergeOptions = _dereq_(87);
6963 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
6965 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6967 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6969 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6971 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6972                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file error-display.js
6973                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6977  * A display that indicates an error has occurred. This means that the video
6978  * is unplayable.
6980  * @extends ModalDialog
6981  */
6982 var ErrorDisplay = function (_ModalDialog) {
6983   _inherits(ErrorDisplay, _ModalDialog);
6985   /**
6986    * Creates an instance of this class.
6987    *
6988    * @param  {Player} player
6989    *         The `Player` that this class should be attached to.
6990    *
6991    * @param  {Object} [options]
6992    *         The key/value store of player options.
6993    */
6994   function ErrorDisplay(player, options) {
6995     _classCallCheck(this, ErrorDisplay);
6997     var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
6999     _this.on(player, 'error', _this.open);
7000     return _this;
7001   }
7003   /**
7004    * Builds the default DOM `className`.
7005    *
7006    * @return {string}
7007    *         The DOM `className` for this object.
7008    *
7009    * @deprecated Since version 5.
7010    */
7013   ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
7014     return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
7015   };
7017   /**
7018    * Gets the localized error message based on the `Player`s error.
7019    *
7020    * @return {string}
7021    *         The `Player`s error message localized or an empty string.
7022    */
7025   ErrorDisplay.prototype.content = function content() {
7026     var error = this.player().error();
7028     return error ? this.localize(error.message) : '';
7029   };
7031   return ErrorDisplay;
7032 }(_modalDialog2['default']);
7035  * The default options for an `ErrorDisplay`.
7037  * @private
7038  */
7041 ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
7042   fillAlways: true,
7043   temporary: false,
7044   uncloseable: true
7047 _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
7048 exports['default'] = ErrorDisplay;
7050 },{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){
7051 'use strict';
7053 exports.__esModule = true;
7055 var _events = _dereq_(82);
7057 var Events = _interopRequireWildcard(_events);
7059 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
7062  * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
7063  * adds shorthand functions that wrap around lengthy functions. For example:
7064  * the `on` function is a wrapper around `addEventListener`.
7066  * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
7067  * @class EventTarget
7068  */
7069 var EventTarget = function EventTarget() {};
7072  * A Custom DOM event.
7074  * @typedef {Object} EventTarget~Event
7075  * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
7076  */
7079  * All event listeners should follow the following format.
7081  * @callback EventTarget~EventListener
7082  * @this {EventTarget}
7084  * @param {EventTarget~Event} event
7085  *        the event that triggered this function
7087  * @param {Object} [hash]
7088  *        hash of data sent during the event
7089  */
7092  * An object containing event names as keys and booleans as values.
7094  * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
7095  *         will have extra functionality. See that function for more information.
7097  * @property EventTarget.prototype.allowedEvents_
7098  * @private
7099  */
7101  * @file src/js/event-target.js
7102  */
7103 EventTarget.prototype.allowedEvents_ = {};
7106  * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
7107  * function that will get called when an event with a certain name gets triggered.
7109  * @param {string|string[]} type
7110  *        An event name or an array of event names.
7112  * @param {EventTarget~EventListener} fn
7113  *        The function to call with `EventTarget`s
7114  */
7115 EventTarget.prototype.on = function (type, fn) {
7116   // Remove the addEventListener alias before calling Events.on
7117   // so we don't get into an infinite type loop
7118   var ael = this.addEventListener;
7120   this.addEventListener = function () {};
7121   Events.on(this, type, fn);
7122   this.addEventListener = ael;
7126  * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
7127  * the standard DOM API.
7129  * @function
7130  * @see {@link EventTarget#on}
7131  */
7132 EventTarget.prototype.addEventListener = EventTarget.prototype.on;
7135  * Removes an `event listener` for a specific event from an instance of `EventTarget`.
7136  * This makes it so that the `event listener` will no longer get called when the
7137  * named event happens.
7139  * @param {string|string[]} type
7140  *        An event name or an array of event names.
7142  * @param {EventTarget~EventListener} fn
7143  *        The function to remove.
7144  */
7145 EventTarget.prototype.off = function (type, fn) {
7146   Events.off(this, type, fn);
7150  * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
7151  * the standard DOM API.
7153  * @function
7154  * @see {@link EventTarget#off}
7155  */
7156 EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
7159  * This function will add an `event listener` that gets triggered only once. After the
7160  * first trigger it will get removed. This is like adding an `event listener`
7161  * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
7163  * @param {string|string[]} type
7164  *        An event name or an array of event names.
7166  * @param {EventTarget~EventListener} fn
7167  *        The function to be called once for each event name.
7168  */
7169 EventTarget.prototype.one = function (type, fn) {
7170   // Remove the addEventListener alialing Events.on
7171   // so we don't get into an infinite type loop
7172   var ael = this.addEventListener;
7174   this.addEventListener = function () {};
7175   Events.one(this, type, fn);
7176   this.addEventListener = ael;
7180  * This function causes an event to happen. This will then cause any `event listeners`
7181  * that are waiting for that event, to get called. If there are no `event listeners`
7182  * for an event then nothing will happen.
7184  * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
7185  * Trigger will also call the `on` + `uppercaseEventName` function.
7187  * Example:
7188  * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
7189  * `onClick` if it exists.
7191  * @param {string|EventTarget~Event|Object} event
7192  *        The name of the event, an `Event`, or an object with a key of type set to
7193  *        an event name.
7194  */
7195 EventTarget.prototype.trigger = function (event) {
7196   var type = event.type || event;
7198   if (typeof event === 'string') {
7199     event = { type: type };
7200   }
7201   event = Events.fixEvent(event);
7203   if (this.allowedEvents_[type] && this['on' + type]) {
7204     this['on' + type](event);
7205   }
7207   Events.trigger(this, event);
7211  * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
7212  * the standard DOM API.
7214  * @function
7215  * @see {@link EventTarget#trigger}
7216  */
7217 EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
7219 exports['default'] = EventTarget;
7221 },{"82":82}],43:[function(_dereq_,module,exports){
7222 'use strict';
7224 exports.__esModule = true;
7226 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
7228 var _log = _dereq_(86);
7230 var _log2 = _interopRequireDefault(_log);
7232 var _obj = _dereq_(88);
7234 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7237  * @file extend.js
7238  * @module extend
7239  */
7242  * A combination of node inherits and babel's inherits (after transpile).
7243  * Both work the same but node adds `super_` to the subClass
7244  * and Babel adds the superClass as __proto__. Both seem useful.
7246  * @param {Object} subClass
7247  *        The class to inherit to
7249  * @param {Object} superClass
7250  *        The class to inherit from
7252  * @private
7253  */
7254 var _inherits = function _inherits(subClass, superClass) {
7255   if (typeof superClass !== 'function' && superClass !== null) {
7256     throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
7257   }
7259   subClass.prototype = Object.create(superClass && superClass.prototype, {
7260     constructor: {
7261       value: subClass,
7262       enumerable: false,
7263       writable: true,
7264       configurable: true
7265     }
7266   });
7268   if (superClass) {
7269     // node
7270     subClass.super_ = superClass;
7271   }
7275  * Function for subclassing using the same inheritance that
7276  * videojs uses internally
7278  * @param {Object} superClass
7279  *        The class to inherit from
7281  * @param {Object} [subClassMethods={}]
7282  *        The class to inherit to
7284  * @return {Object}
7285  *         The new object with subClassMethods that inherited superClass.
7286  */
7287 var extendFn = function extendFn(superClass) {
7288   var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7290   var subClass = function subClass() {
7291     superClass.apply(this, arguments);
7292   };
7294   var methods = {};
7296   if ((0, _obj.isObject)(subClassMethods)) {
7297     if (typeof subClassMethods.init === 'function') {
7298       _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
7299       subClassMethods.constructor = subClassMethods.init;
7300     }
7301     if (subClassMethods.constructor !== Object.prototype.constructor) {
7302       subClass = subClassMethods.constructor;
7303     }
7304     methods = subClassMethods;
7305   } else if (typeof subClassMethods === 'function') {
7306     subClass = subClassMethods;
7307   }
7309   _inherits(subClass, superClass);
7311   // Extend subObj's prototype with functions and other properties from props
7312   for (var name in methods) {
7313     if (methods.hasOwnProperty(name)) {
7314       subClass.prototype[name] = methods[name];
7315     }
7316   }
7318   return subClass;
7321 exports['default'] = extendFn;
7323 },{"86":86,"88":88}],44:[function(_dereq_,module,exports){
7324 'use strict';
7326 exports.__esModule = true;
7328 var _document = _dereq_(94);
7330 var _document2 = _interopRequireDefault(_document);
7332 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7335  * Store the browser-specific methods for the fullscreen API.
7337  * @type {Object}
7338  * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
7339  * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
7340  */
7341 var FullscreenApi = {};
7343 // browser API methods
7345  * @file fullscreen-api.js
7346  * @module fullscreen-api
7347  * @private
7348  */
7349 var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
7350 // WebKit
7351 ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7352 // Old WebKit (Safari 5.1)
7353 ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7354 // Mozilla
7355 ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
7356 // Microsoft
7357 ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
7359 var specApi = apiMap[0];
7360 var browserApi = void 0;
7362 // determine the supported set of functions
7363 for (var i = 0; i < apiMap.length; i++) {
7364   // check for exitFullscreen function
7365   if (apiMap[i][1] in _document2['default']) {
7366     browserApi = apiMap[i];
7367     break;
7368   }
7371 // map the browser API names to the spec API names
7372 if (browserApi) {
7373   for (var _i = 0; _i < browserApi.length; _i++) {
7374     FullscreenApi[specApi[_i]] = browserApi[_i];
7375   }
7378 exports['default'] = FullscreenApi;
7380 },{"94":94}],45:[function(_dereq_,module,exports){
7381 'use strict';
7383 exports.__esModule = true;
7385 var _component = _dereq_(5);
7387 var _component2 = _interopRequireDefault(_component);
7389 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7391 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7393 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7395 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
7396                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file loading-spinner.js
7397                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
7401  * A loading spinner for use during waiting/loading events.
7403  * @extends Component
7404  */
7405 var LoadingSpinner = function (_Component) {
7406   _inherits(LoadingSpinner, _Component);
7408   function LoadingSpinner() {
7409     _classCallCheck(this, LoadingSpinner);
7411     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
7412   }
7414   /**
7415    * Create the `LoadingSpinner`s DOM element.
7416    *
7417    * @return {Element}
7418    *         The dom element that gets created.
7419    */
7420   LoadingSpinner.prototype.createEl = function createEl() {
7421     return _Component.prototype.createEl.call(this, 'div', {
7422       className: 'vjs-loading-spinner',
7423       dir: 'ltr'
7424     });
7425   };
7427   return LoadingSpinner;
7428 }(_component2['default']);
7430 _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
7431 exports['default'] = LoadingSpinner;
7433 },{"5":5}],46:[function(_dereq_,module,exports){
7434 'use strict';
7436 exports.__esModule = true;
7438 var _obj = _dereq_(88);
7441  * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
7443  * @param {number|string|Object|MediaError} value
7444  *        This can be of multiple types:
7445  *        - number: should be a standard error code
7446  *        - string: an error message (the code will be 0)
7447  *        - Object: arbitrary properties
7448  *        - `MediaError` (native): used to populate a video.js `MediaError` object
7449  *        - `MediaError` (video.js): will return itself if it's already a
7450  *          video.js `MediaError` object.
7452  * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
7453  * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
7455  * @class MediaError
7456  */
7457 function MediaError(value) {
7459   // Allow redundant calls to this constructor to avoid having `instanceof`
7460   // checks peppered around the code.
7461   if (value instanceof MediaError) {
7462     return value;
7463   }
7465   if (typeof value === 'number') {
7466     this.code = value;
7467   } else if (typeof value === 'string') {
7468     // default code is zero, so this is a custom error
7469     this.message = value;
7470   } else if ((0, _obj.isObject)(value)) {
7472     // We assign the `code` property manually because native `MediaError` objects
7473     // do not expose it as an own/enumerable property of the object.
7474     if (typeof value.code === 'number') {
7475       this.code = value.code;
7476     }
7478     (0, _obj.assign)(this, value);
7479   }
7481   if (!this.message) {
7482     this.message = MediaError.defaultMessages[this.code] || '';
7483   }
7487  * The error code that refers two one of the defined `MediaError` types
7489  * @type {Number}
7490  */
7492  * @file media-error.js
7493  */
7494 MediaError.prototype.code = 0;
7497  * An optional message that to show with the error. Message is not part of the HTML5
7498  * video spec but allows for more informative custom errors.
7500  * @type {String}
7501  */
7502 MediaError.prototype.message = '';
7505  * An optional status code that can be set by plugins to allow even more detail about
7506  * the error. For example a plugin might provide a specific HTTP status code and an
7507  * error message for that code. Then when the plugin gets that error this class will
7508  * know how to display an error message for it. This allows a custom message to show
7509  * up on the `Player` error overlay.
7511  * @type {Array}
7512  */
7513 MediaError.prototype.status = null;
7516  * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
7517  * specification listed under {@link MediaError} for more information.
7519  * @enum {array}
7520  * @readonly
7521  * @property {string} 0 - MEDIA_ERR_CUSTOM
7522  * @property {string} 1 - MEDIA_ERR_CUSTOM
7523  * @property {string} 2 - MEDIA_ERR_ABORTED
7524  * @property {string} 3 - MEDIA_ERR_NETWORK
7525  * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
7526  * @property {string} 5 - MEDIA_ERR_ENCRYPTED
7527  */
7528 MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
7531  * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
7533  * @type {Array}
7534  * @constant
7535  */
7536 MediaError.defaultMessages = {
7537   1: 'You aborted the media playback',
7538   2: 'A network error caused the media download to fail part-way.',
7539   3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
7540   4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
7541   5: 'The media is encrypted and we do not have the keys to decrypt it.'
7544 // Add types as properties on MediaError
7545 // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
7546 for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
7547   MediaError[MediaError.errorTypes[errNum]] = errNum;
7548   // values should be accessible on both the class and instance
7549   MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
7552 // jsdocs for instance/static members added above
7553 // instance methods use `#` and static methods use `.`
7555  * W3C error code for any custom error.
7557  * @member MediaError#MEDIA_ERR_CUSTOM
7558  * @constant {number}
7559  * @default 0
7560  */
7562  * W3C error code for any custom error.
7564  * @member MediaError.MEDIA_ERR_CUSTOM
7565  * @constant {number}
7566  * @default 0
7567  */
7570  * W3C error code for media error aborted.
7572  * @member MediaError#MEDIA_ERR_ABORTED
7573  * @constant {number}
7574  * @default 1
7575  */
7577  * W3C error code for media error aborted.
7579  * @member MediaError.MEDIA_ERR_ABORTED
7580  * @constant {number}
7581  * @default 1
7582  */
7585  * W3C error code for any network error.
7587  * @member MediaError#MEDIA_ERR_NETWORK
7588  * @constant {number}
7589  * @default 2
7590  */
7592  * W3C error code for any network error.
7594  * @member MediaError.MEDIA_ERR_NETWORK
7595  * @constant {number}
7596  * @default 2
7597  */
7600  * W3C error code for any decoding error.
7602  * @member MediaError#MEDIA_ERR_DECODE
7603  * @constant {number}
7604  * @default 3
7605  */
7607  * W3C error code for any decoding error.
7609  * @member MediaError.MEDIA_ERR_DECODE
7610  * @constant {number}
7611  * @default 3
7612  */
7615  * W3C error code for any time that a source is not supported.
7617  * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
7618  * @constant {number}
7619  * @default 4
7620  */
7622  * W3C error code for any time that a source is not supported.
7624  * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
7625  * @constant {number}
7626  * @default 4
7627  */
7630  * W3C error code for any time that a source is encrypted.
7632  * @member MediaError#MEDIA_ERR_ENCRYPTED
7633  * @constant {number}
7634  * @default 5
7635  */
7637  * W3C error code for any time that a source is encrypted.
7639  * @member MediaError.MEDIA_ERR_ENCRYPTED
7640  * @constant {number}
7641  * @default 5
7642  */
7644 exports['default'] = MediaError;
7646 },{"88":88}],47:[function(_dereq_,module,exports){
7647 'use strict';
7649 exports.__esModule = true;
7651 var _clickableComponent = _dereq_(3);
7653 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7655 var _component = _dereq_(5);
7657 var _component2 = _interopRequireDefault(_component);
7659 var _menu = _dereq_(49);
7661 var _menu2 = _interopRequireDefault(_menu);
7663 var _dom = _dereq_(81);
7665 var Dom = _interopRequireWildcard(_dom);
7667 var _fn = _dereq_(83);
7669 var Fn = _interopRequireWildcard(_fn);
7671 var _toTitleCase = _dereq_(91);
7673 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
7675 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
7677 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7679 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7681 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7683 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
7684                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file menu-button.js
7685                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
7689  * A `MenuButton` class for any popup {@link Menu}.
7691  * @extends ClickableComponent
7692  */
7693 var MenuButton = function (_ClickableComponent) {
7694   _inherits(MenuButton, _ClickableComponent);
7696   /**
7697    * Creates an instance of this class.
7698    *
7699    * @param {Player} player
7700    *        The `Player` that this class should be attached to.
7701    *
7702    * @param {Object} [options={}]
7703    *        The key/value store of player options.
7704    */
7705   function MenuButton(player) {
7706     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7708     _classCallCheck(this, MenuButton);
7710     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
7712     _this.update();
7714     _this.enabled_ = true;
7716     _this.el_.setAttribute('aria-haspopup', 'true');
7717     _this.el_.setAttribute('role', 'menuitem');
7718     _this.on('keydown', _this.handleSubmenuKeyPress);
7719     return _this;
7720   }
7722   /**
7723    * Update the menu based on the current state of its items.
7724    */
7727   MenuButton.prototype.update = function update() {
7728     var menu = this.createMenu();
7730     if (this.menu) {
7731       this.removeChild(this.menu);
7732     }
7734     this.menu = menu;
7735     this.addChild(menu);
7737     /**
7738      * Track the state of the menu button
7739      *
7740      * @type {Boolean}
7741      * @private
7742      */
7743     this.buttonPressed_ = false;
7744     this.el_.setAttribute('aria-expanded', 'false');
7746     if (this.items && this.items.length === 0) {
7747       this.hide();
7748     } else if (this.items && this.items.length > 1) {
7749       this.show();
7750     }
7751   };
7753   /**
7754    * Create the menu and add all items to it.
7755    *
7756    * @return {Menu}
7757    *         The constructed menu
7758    */
7761   MenuButton.prototype.createMenu = function createMenu() {
7762     var menu = new _menu2['default'](this.player_);
7764     // Add a title list item to the top
7765     if (this.options_.title) {
7766       var title = Dom.createEl('li', {
7767         className: 'vjs-menu-title',
7768         innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
7769         tabIndex: -1
7770       });
7772       menu.children_.unshift(title);
7773       Dom.insertElFirst(title, menu.contentEl());
7774     }
7776     this.items = this.createItems();
7778     if (this.items) {
7779       // Add menu items to the menu
7780       for (var i = 0; i < this.items.length; i++) {
7781         menu.addItem(this.items[i]);
7782       }
7783     }
7785     return menu;
7786   };
7788   /**
7789    * Create the list of menu items. Specific to each subclass.
7790    *
7791    * @abstract
7792    */
7795   MenuButton.prototype.createItems = function createItems() {};
7797   /**
7798    * Create the `MenuButtons`s DOM element.
7799    *
7800    * @return {Element}
7801    *         The element that gets created.
7802    */
7805   MenuButton.prototype.createEl = function createEl() {
7806     return _ClickableComponent.prototype.createEl.call(this, 'div', {
7807       className: this.buildCSSClass()
7808     });
7809   };
7811   /**
7812    * Builds the default DOM `className`.
7813    *
7814    * @return {string}
7815    *         The DOM `className` for this object.
7816    */
7819   MenuButton.prototype.buildCSSClass = function buildCSSClass() {
7820     var menuButtonClass = 'vjs-menu-button';
7822     // If the inline option is passed, we want to use different styles altogether.
7823     if (this.options_.inline === true) {
7824       menuButtonClass += '-inline';
7825     } else {
7826       menuButtonClass += '-popup';
7827     }
7829     return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
7830   };
7832   /**
7833    * Handle a click on a `MenuButton`.
7834    * See {@link ClickableComponent#handleClick} for instances where this is called.
7835    *
7836    * @param {EventTarget~Event} event
7837    *        The `keydown`, `tap`, or `click` event that caused this function to be
7838    *        called.
7839    *
7840    * @listens tap
7841    * @listens click
7842    */
7845   MenuButton.prototype.handleClick = function handleClick(event) {
7846     // When you click the button it adds focus, which will show the menu.
7847     // So we'll remove focus when the mouse leaves the button. Focus is needed
7848     // for tab navigation.
7850     this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
7851       this.unpressButton();
7852       this.el_.blur();
7853     }));
7854     if (this.buttonPressed_) {
7855       this.unpressButton();
7856     } else {
7857       this.pressButton();
7858     }
7859   };
7861   /**
7862    * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
7863    * {@link ClickableComponent#handleKeyPress} for instances where this is called.
7864    *
7865    * @param {EventTarget~Event} event
7866    *        The `keydown` event that caused this function to be called.
7867    *
7868    * @listens keydown
7869    */
7872   MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
7874     // Escape (27) key or Tab (9) key unpress the 'button'
7875     if (event.which === 27 || event.which === 9) {
7876       if (this.buttonPressed_) {
7877         this.unpressButton();
7878       }
7879       // Don't preventDefault for Tab key - we still want to lose focus
7880       if (event.which !== 9) {
7881         event.preventDefault();
7882       }
7883       // Up (38) key or Down (40) key press the 'button'
7884     } else if (event.which === 38 || event.which === 40) {
7885       if (!this.buttonPressed_) {
7886         this.pressButton();
7887         event.preventDefault();
7888       }
7889     } else {
7890       _ClickableComponent.prototype.handleKeyPress.call(this, event);
7891     }
7892   };
7894   /**
7895    * Handle a `keydown` event on a sub-menu. The listener for this is added in
7896    * the constructor.
7897    *
7898    * @param {EventTarget~Event} event
7899    *        Key press event
7900    *
7901    * @listens keydown
7902    */
7905   MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
7907     // Escape (27) key or Tab (9) key unpress the 'button'
7908     if (event.which === 27 || event.which === 9) {
7909       if (this.buttonPressed_) {
7910         this.unpressButton();
7911       }
7912       // Don't preventDefault for Tab key - we still want to lose focus
7913       if (event.which !== 9) {
7914         event.preventDefault();
7915       }
7916     }
7917   };
7919   /**
7920    * Put the current `MenuButton` into a pressed state.
7921    */
7924   MenuButton.prototype.pressButton = function pressButton() {
7925     if (this.enabled_) {
7926       this.buttonPressed_ = true;
7927       this.menu.lockShowing();
7928       this.el_.setAttribute('aria-expanded', 'true');
7929       // set the focus into the submenu
7930       this.menu.focus();
7931     }
7932   };
7934   /**
7935    * Take the current `MenuButton` out of a pressed state.
7936    */
7939   MenuButton.prototype.unpressButton = function unpressButton() {
7940     if (this.enabled_) {
7941       this.buttonPressed_ = false;
7942       this.menu.unlockShowing();
7943       this.el_.setAttribute('aria-expanded', 'false');
7944       // Set focus back to this menu button
7945       this.el_.focus();
7946     }
7947   };
7949   /**
7950    * Disable the `MenuButton`. Don't allow it to be clicked.
7951    *
7952    * @return {MenuButton}
7953    *         Returns itself; method can be chained.
7954    */
7957   MenuButton.prototype.disable = function disable() {
7958     // Unpress, but don't force focus on this button
7959     this.buttonPressed_ = false;
7960     this.menu.unlockShowing();
7961     this.el_.setAttribute('aria-expanded', 'false');
7963     this.enabled_ = false;
7965     return _ClickableComponent.prototype.disable.call(this);
7966   };
7968   /**
7969    * Enable the `MenuButton`. Allow it to be clicked.
7970    *
7971    * @return {MenuButton}
7972    *         Returns itself; method can be chained.
7973    */
7976   MenuButton.prototype.enable = function enable() {
7977     this.enabled_ = true;
7979     return _ClickableComponent.prototype.enable.call(this);
7980   };
7982   return MenuButton;
7983 }(_clickableComponent2['default']);
7985 _component2['default'].registerComponent('MenuButton', MenuButton);
7986 exports['default'] = MenuButton;
7988 },{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){
7989 'use strict';
7991 exports.__esModule = true;
7993 var _clickableComponent = _dereq_(3);
7995 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7997 var _component = _dereq_(5);
7999 var _component2 = _interopRequireDefault(_component);
8001 var _obj = _dereq_(88);
8003 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8005 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8007 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8009 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8010                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file menu-item.js
8011                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8015  * The component for a menu item. `<li>`
8017  * @extends ClickableComponent
8018  */
8019 var MenuItem = function (_ClickableComponent) {
8020   _inherits(MenuItem, _ClickableComponent);
8022   /**
8023    * Creates an instance of the this class.
8024    *
8025    * @param {Player} player
8026    *        The `Player` that this class should be attached to.
8027    *
8028    * @param {Object} [options={}]
8029    *        The key/value store of player options.
8030    *
8031    */
8032   function MenuItem(player, options) {
8033     _classCallCheck(this, MenuItem);
8035     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
8037     _this.selectable = options.selectable;
8039     _this.selected(options.selected);
8041     if (_this.selectable) {
8042       // TODO: May need to be either menuitemcheckbox or menuitemradio,
8043       //       and may need logical grouping of menu items.
8044       _this.el_.setAttribute('role', 'menuitemcheckbox');
8045     } else {
8046       _this.el_.setAttribute('role', 'menuitem');
8047     }
8048     return _this;
8049   }
8051   /**
8052    * Create the `MenuItem's DOM element
8053    *
8054    * @param {string} [type=li]
8055    *        Element's node type, not actually used, always set to `li`.
8056    *
8057    * @param {Object} [props={}]
8058    *        An object of properties that should be set on the element
8059    *
8060    * @param {Object} [attrs={}]
8061    *        An object of attributes that should be set on the element
8062    *
8063    * @return {Element}
8064    *         The element that gets created.
8065    */
8068   MenuItem.prototype.createEl = function createEl(type, props, attrs) {
8069     return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
8070       className: 'vjs-menu-item',
8071       innerHTML: this.localize(this.options_.label),
8072       tabIndex: -1
8073     }, props), attrs);
8074   };
8076   /**
8077    * Any click on a `MenuItem` puts int into the selected state.
8078    * See {@link ClickableComponent#handleClick} for instances where this is called.
8079    *
8080    * @param {EventTarget~Event} event
8081    *        The `keydown`, `tap`, or `click` event that caused this function to be
8082    *        called.
8083    *
8084    * @listens tap
8085    * @listens click
8086    */
8089   MenuItem.prototype.handleClick = function handleClick(event) {
8090     this.selected(true);
8091   };
8093   /**
8094    * Set the state for this menu item as selected or not.
8095    *
8096    * @param {boolean} selected
8097    *        if the menu item is selected or not
8098    */
8101   MenuItem.prototype.selected = function selected(_selected) {
8102     if (this.selectable) {
8103       if (_selected) {
8104         this.addClass('vjs-selected');
8105         this.el_.setAttribute('aria-checked', 'true');
8106         // aria-checked isn't fully supported by browsers/screen readers,
8107         // so indicate selected state to screen reader in the control text.
8108         this.controlText(', selected');
8109       } else {
8110         this.removeClass('vjs-selected');
8111         this.el_.setAttribute('aria-checked', 'false');
8112         // Indicate un-selected state to screen reader
8113         // Note that a space clears out the selected state text
8114         this.controlText(' ');
8115       }
8116     }
8117   };
8119   return MenuItem;
8120 }(_clickableComponent2['default']);
8122 _component2['default'].registerComponent('MenuItem', MenuItem);
8123 exports['default'] = MenuItem;
8125 },{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){
8126 'use strict';
8128 exports.__esModule = true;
8130 var _component = _dereq_(5);
8132 var _component2 = _interopRequireDefault(_component);
8134 var _dom = _dereq_(81);
8136 var Dom = _interopRequireWildcard(_dom);
8138 var _fn = _dereq_(83);
8140 var Fn = _interopRequireWildcard(_fn);
8142 var _events = _dereq_(82);
8144 var Events = _interopRequireWildcard(_events);
8146 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8148 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8150 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8152 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8154 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8155                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file menu.js
8156                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8160  * The Menu component is used to build popup menus, including subtitle and
8161  * captions selection menus.
8163  * @extends Component
8164  */
8165 var Menu = function (_Component) {
8166   _inherits(Menu, _Component);
8168   /**
8169    * Create an instance of this class.
8170    *
8171    * @param {Player} player
8172    *        the player that this component should attach to
8173    *
8174    * @param {Object} [options]
8175    *        Object of option names and values
8176    *
8177    */
8178   function Menu(player, options) {
8179     _classCallCheck(this, Menu);
8181     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8183     _this.focusedChild_ = -1;
8185     _this.on('keydown', _this.handleKeyPress);
8186     return _this;
8187   }
8189   /**
8190    * Add a {@link MenuItem} to the menu.
8191    *
8192    * @param {Object|string} component
8193    *        The name or instance of the `MenuItem` to add.
8194    *
8195    */
8198   Menu.prototype.addItem = function addItem(component) {
8199     this.addChild(component);
8200     component.on('click', Fn.bind(this, function (event) {
8201       this.unlockShowing();
8202       // TODO: Need to set keyboard focus back to the menuButton
8203     }));
8204   };
8206   /**
8207    * Create the `Menu`s DOM element.
8208    *
8209    * @return {Element}
8210    *         the element that was created
8211    */
8214   Menu.prototype.createEl = function createEl() {
8215     var contentElType = this.options_.contentElType || 'ul';
8217     this.contentEl_ = Dom.createEl(contentElType, {
8218       className: 'vjs-menu-content'
8219     });
8221     this.contentEl_.setAttribute('role', 'menu');
8223     var el = _Component.prototype.createEl.call(this, 'div', {
8224       append: this.contentEl_,
8225       className: 'vjs-menu'
8226     });
8228     el.setAttribute('role', 'presentation');
8229     el.appendChild(this.contentEl_);
8231     // Prevent clicks from bubbling up. Needed for Menu Buttons,
8232     // where a click on the parent is significant
8233     Events.on(el, 'click', function (event) {
8234       event.preventDefault();
8235       event.stopImmediatePropagation();
8236     });
8238     return el;
8239   };
8241   /**
8242    * Handle a `keydown` event on this menu. This listener is added in the constructor.
8243    *
8244    * @param {EventTarget~Event} event
8245    *        A `keydown` event that happened on the menu.
8246    *
8247    * @listens keydown
8248    */
8251   Menu.prototype.handleKeyPress = function handleKeyPress(event) {
8252     // Left and Down Arrows
8253     if (event.which === 37 || event.which === 40) {
8254       event.preventDefault();
8255       this.stepForward();
8257       // Up and Right Arrows
8258     } else if (event.which === 38 || event.which === 39) {
8259       event.preventDefault();
8260       this.stepBack();
8261     }
8262   };
8264   /**
8265    * Move to next (lower) menu item for keyboard users.
8266    */
8269   Menu.prototype.stepForward = function stepForward() {
8270     var stepChild = 0;
8272     if (this.focusedChild_ !== undefined) {
8273       stepChild = this.focusedChild_ + 1;
8274     }
8275     this.focus(stepChild);
8276   };
8278   /**
8279    * Move to previous (higher) menu item for keyboard users.
8280    */
8283   Menu.prototype.stepBack = function stepBack() {
8284     var stepChild = 0;
8286     if (this.focusedChild_ !== undefined) {
8287       stepChild = this.focusedChild_ - 1;
8288     }
8289     this.focus(stepChild);
8290   };
8292   /**
8293    * Set focus on a {@link MenuItem} in the `Menu`.
8294    *
8295    * @param {Object|string} [item=0]
8296    *        Index of child item set focus on.
8297    */
8300   Menu.prototype.focus = function focus() {
8301     var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8303     var children = this.children().slice();
8304     var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
8306     if (haveTitle) {
8307       children.shift();
8308     }
8310     if (children.length > 0) {
8311       if (item < 0) {
8312         item = 0;
8313       } else if (item >= children.length) {
8314         item = children.length - 1;
8315       }
8317       this.focusedChild_ = item;
8319       children[item].el_.focus();
8320     }
8321   };
8323   return Menu;
8324 }(_component2['default']);
8326 _component2['default'].registerComponent('Menu', Menu);
8327 exports['default'] = Menu;
8329 },{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){
8330 'use strict';
8332 exports.__esModule = true;
8334 var _dom = _dereq_(81);
8336 var Dom = _interopRequireWildcard(_dom);
8338 var _fn = _dereq_(83);
8340 var Fn = _interopRequireWildcard(_fn);
8342 var _component = _dereq_(5);
8344 var _component2 = _interopRequireDefault(_component);
8346 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8348 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8350 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8352 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8354 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8355                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file modal-dialog.js
8356                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8359 var MODAL_CLASS_NAME = 'vjs-modal-dialog';
8360 var ESC = 27;
8363  * The `ModalDialog` displays over the video and its controls, which blocks
8364  * interaction with the player until it is closed.
8366  * Modal dialogs include a "Close" button and will close when that button
8367  * is activated - or when ESC is pressed anywhere.
8369  * @extends Component
8370  */
8372 var ModalDialog = function (_Component) {
8373   _inherits(ModalDialog, _Component);
8375   /**
8376    * Create an instance of this class.
8377    *
8378    * @param {Player} player
8379    *        The `Player` that this class should be attached to.
8380    *
8381    * @param {Object} [options]
8382    *        The key/value store of player options.
8383    *
8384    * @param {Mixed} [options.content=undefined]
8385    *        Provide customized content for this modal.
8386    *
8387    * @param {string} [options.description]
8388    *        A text description for the modal, primarily for accessibility.
8389    *
8390    * @param {boolean} [options.fillAlways=false]
8391    *        Normally, modals are automatically filled only the first time
8392    *        they open. This tells the modal to refresh its content
8393    *        every time it opens.
8394    *
8395    * @param {string} [options.label]
8396    *        A text label for the modal, primarily for accessibility.
8397    *
8398    * @param {boolean} [options.temporary=true]
8399    *        If `true`, the modal can only be opened once; it will be
8400    *        disposed as soon as it's closed.
8401    *
8402    * @param {boolean} [options.uncloseable=false]
8403    *        If `true`, the user will not be able to close the modal
8404    *        through the UI in the normal ways. Programmatic closing is
8405    *        still possible.
8406    */
8407   function ModalDialog(player, options) {
8408     _classCallCheck(this, ModalDialog);
8410     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8412     _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
8414     _this.closeable(!_this.options_.uncloseable);
8415     _this.content(_this.options_.content);
8417     // Make sure the contentEl is defined AFTER any children are initialized
8418     // because we only want the contents of the modal in the contentEl
8419     // (not the UI elements like the close button).
8420     _this.contentEl_ = Dom.createEl('div', {
8421       className: MODAL_CLASS_NAME + '-content'
8422     }, {
8423       role: 'document'
8424     });
8426     _this.descEl_ = Dom.createEl('p', {
8427       className: MODAL_CLASS_NAME + '-description vjs-offscreen',
8428       id: _this.el().getAttribute('aria-describedby')
8429     });
8431     Dom.textContent(_this.descEl_, _this.description());
8432     _this.el_.appendChild(_this.descEl_);
8433     _this.el_.appendChild(_this.contentEl_);
8434     return _this;
8435   }
8437   /**
8438    * Create the `ModalDialog`'s DOM element
8439    *
8440    * @return {Element}
8441    *         The DOM element that gets created.
8442    */
8445   ModalDialog.prototype.createEl = function createEl() {
8446     return _Component.prototype.createEl.call(this, 'div', {
8447       className: this.buildCSSClass(),
8448       tabIndex: -1
8449     }, {
8450       'aria-describedby': this.id() + '_description',
8451       'aria-hidden': 'true',
8452       'aria-label': this.label(),
8453       'role': 'dialog'
8454     });
8455   };
8457   /**
8458    * Builds the default DOM `className`.
8459    *
8460    * @return {string}
8461    *         The DOM `className` for this object.
8462    */
8465   ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
8466     return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
8467   };
8469   /**
8470    * Handles `keydown` events on the document, looking for ESC, which closes
8471    * the modal.
8472    *
8473    * @param {EventTarget~Event} e
8474    *        The keypress that triggered this event.
8475    *
8476    * @listens keydown
8477    */
8480   ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
8481     if (e.which === ESC && this.closeable()) {
8482       this.close();
8483     }
8484   };
8486   /**
8487    * Returns the label string for this modal. Primarily used for accessibility.
8488    *
8489    * @return {string}
8490    *         the localized or raw label of this modal.
8491    */
8494   ModalDialog.prototype.label = function label() {
8495     return this.options_.label || this.localize('Modal Window');
8496   };
8498   /**
8499    * Returns the description string for this modal. Primarily used for
8500    * accessibility.
8501    *
8502    * @return {string}
8503    *         The localized or raw description of this modal.
8504    */
8507   ModalDialog.prototype.description = function description() {
8508     var desc = this.options_.description || this.localize('This is a modal window.');
8510     // Append a universal closeability message if the modal is closeable.
8511     if (this.closeable()) {
8512       desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
8513     }
8515     return desc;
8516   };
8518   /**
8519    * Opens the modal.
8520    *
8521    * @fires ModalDialog#beforemodalopen
8522    * @fires ModalDialog#modalopen
8523    *
8524    * @return {ModalDialog}
8525    *         Returns itself; method can be chained.
8526    */
8529   ModalDialog.prototype.open = function open() {
8530     if (!this.opened_) {
8531       var player = this.player();
8533       /**
8534        * Fired just before a `ModalDialog` is opened.
8535        *
8536        * @event ModalDialog#beforemodalopen
8537        * @type {EventTarget~Event}
8538        */
8539       this.trigger('beforemodalopen');
8540       this.opened_ = true;
8542       // Fill content if the modal has never opened before and
8543       // never been filled.
8544       if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
8545         this.fill();
8546       }
8548       // If the player was playing, pause it and take note of its previously
8549       // playing state.
8550       this.wasPlaying_ = !player.paused();
8552       if (this.wasPlaying_) {
8553         player.pause();
8554       }
8556       if (this.closeable()) {
8557         this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8558       }
8560       player.controls(false);
8561       this.show();
8562       this.el().setAttribute('aria-hidden', 'false');
8564       /**
8565        * Fired just after a `ModalDialog` is opened.
8566        *
8567        * @event ModalDialog#modalopen
8568        * @type {EventTarget~Event}
8569        */
8570       this.trigger('modalopen');
8571       this.hasBeenOpened_ = true;
8572     }
8573     return this;
8574   };
8576   /**
8577    * If the `ModalDialog` is currently open or closed.
8578    *
8579    * @param  {boolean} [value]
8580    *         If given, it will open (`true`) or close (`false`) the modal.
8581    *
8582    * @return {boolean}
8583    *         the current open state of the modaldialog
8584    */
8587   ModalDialog.prototype.opened = function opened(value) {
8588     if (typeof value === 'boolean') {
8589       this[value ? 'open' : 'close']();
8590     }
8591     return this.opened_;
8592   };
8594   /**
8595    * Closes the modal, does nothing if the `ModalDialog` is
8596    * not open.
8597    *
8598    * @fires ModalDialog#beforemodalclose
8599    * @fires ModalDialog#modalclose
8600    *
8601    * @return {ModalDialog}
8602    *         Returns itself; method can be chained.
8603    */
8606   ModalDialog.prototype.close = function close() {
8607     if (this.opened_) {
8608       var player = this.player();
8610       /**
8611        * Fired just before a `ModalDialog` is closed.
8612        *
8613        * @event ModalDialog#beforemodalclose
8614        * @type {EventTarget~Event}
8615        */
8616       this.trigger('beforemodalclose');
8617       this.opened_ = false;
8619       if (this.wasPlaying_) {
8620         player.play();
8621       }
8623       if (this.closeable()) {
8624         this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8625       }
8627       player.controls(true);
8628       this.hide();
8629       this.el().setAttribute('aria-hidden', 'true');
8631       /**
8632        * Fired just after a `ModalDialog` is closed.
8633        *
8634        * @event ModalDialog#modalclose
8635        * @type {EventTarget~Event}
8636        */
8637       this.trigger('modalclose');
8639       if (this.options_.temporary) {
8640         this.dispose();
8641       }
8642     }
8643     return this;
8644   };
8646   /**
8647    * Check to see if the `ModalDialog` is closeable via the UI.
8648    *
8649    * @param  {boolean} [value]
8650    *         If given as a boolean, it will set the `closeable` option.
8651    *
8652    * @return {boolean}
8653    *         Returns the final value of the closable option.
8654    */
8657   ModalDialog.prototype.closeable = function closeable(value) {
8658     if (typeof value === 'boolean') {
8659       var closeable = this.closeable_ = !!value;
8660       var close = this.getChild('closeButton');
8662       // If this is being made closeable and has no close button, add one.
8663       if (closeable && !close) {
8665         // The close button should be a child of the modal - not its
8666         // content element, so temporarily change the content element.
8667         var temp = this.contentEl_;
8669         this.contentEl_ = this.el_;
8670         close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
8671         this.contentEl_ = temp;
8672         this.on(close, 'close', this.close);
8673       }
8675       // If this is being made uncloseable and has a close button, remove it.
8676       if (!closeable && close) {
8677         this.off(close, 'close', this.close);
8678         this.removeChild(close);
8679         close.dispose();
8680       }
8681     }
8682     return this.closeable_;
8683   };
8685   /**
8686    * Fill the modal's content element with the modal's "content" option.
8687    * The content element will be emptied before this change takes place.
8688    *
8689    * @return {ModalDialog}
8690    *         Returns itself; method can be chained.
8691    */
8694   ModalDialog.prototype.fill = function fill() {
8695     return this.fillWith(this.content());
8696   };
8698   /**
8699    * Fill the modal's content element with arbitrary content.
8700    * The content element will be emptied before this change takes place.
8701    *
8702    * @fires ModalDialog#beforemodalfill
8703    * @fires ModalDialog#modalfill
8704    *
8705    * @param  {Mixed} [content]
8706    *         The same rules apply to this as apply to the `content` option.
8707    *
8708    * @return {ModalDialog}
8709    *         Returns itself; method can be chained.
8710    */
8713   ModalDialog.prototype.fillWith = function fillWith(content) {
8714     var contentEl = this.contentEl();
8715     var parentEl = contentEl.parentNode;
8716     var nextSiblingEl = contentEl.nextSibling;
8718     /**
8719      * Fired just before a `ModalDialog` is filled with content.
8720      *
8721      * @event ModalDialog#beforemodalfill
8722      * @type {EventTarget~Event}
8723      */
8724     this.trigger('beforemodalfill');
8725     this.hasBeenFilled_ = true;
8727     // Detach the content element from the DOM before performing
8728     // manipulation to avoid modifying the live DOM multiple times.
8729     parentEl.removeChild(contentEl);
8730     this.empty();
8731     Dom.insertContent(contentEl, content);
8732     /**
8733      * Fired just after a `ModalDialog` is filled with content.
8734      *
8735      * @event ModalDialog#modalfill
8736      * @type {EventTarget~Event}
8737      */
8738     this.trigger('modalfill');
8740     // Re-inject the re-filled content element.
8741     if (nextSiblingEl) {
8742       parentEl.insertBefore(contentEl, nextSiblingEl);
8743     } else {
8744       parentEl.appendChild(contentEl);
8745     }
8747     return this;
8748   };
8750   /**
8751    * Empties the content element. This happens anytime the modal is filled.
8752    *
8753    * @fires ModalDialog#beforemodalempty
8754    * @fires ModalDialog#modalempty
8755    *
8756    * @return {ModalDialog}
8757    *         Returns itself; method can be chained.
8758    */
8761   ModalDialog.prototype.empty = function empty() {
8762     /**
8763      * Fired just before a `ModalDialog` is emptied.
8764      *
8765      * @event ModalDialog#beforemodalempty
8766      * @type {EventTarget~Event}
8767      */
8768     this.trigger('beforemodalempty');
8769     Dom.emptyEl(this.contentEl());
8771     /**
8772      * Fired just after a `ModalDialog` is emptied.
8773      *
8774      * @event ModalDialog#modalempty
8775      * @type {EventTarget~Event}
8776      */
8777     this.trigger('modalempty');
8778     return this;
8779   };
8781   /**
8782    * Gets or sets the modal content, which gets normalized before being
8783    * rendered into the DOM.
8784    *
8785    * This does not update the DOM or fill the modal, but it is called during
8786    * that process.
8787    *
8788    * @param  {Mixed} [value]
8789    *         If defined, sets the internal content value to be used on the
8790    *         next call(s) to `fill`. This value is normalized before being
8791    *         inserted. To "clear" the internal content value, pass `null`.
8792    *
8793    * @return {Mixed}
8794    *         The current content of the modal dialog
8795    */
8798   ModalDialog.prototype.content = function content(value) {
8799     if (typeof value !== 'undefined') {
8800       this.content_ = value;
8801     }
8802     return this.content_;
8803   };
8805   return ModalDialog;
8806 }(_component2['default']);
8809  * Default options for `ModalDialog` default options.
8811  * @type {Object}
8812  * @private
8813  */
8816 ModalDialog.prototype.options_ = {
8817   temporary: true
8820 _component2['default'].registerComponent('ModalDialog', ModalDialog);
8821 exports['default'] = ModalDialog;
8823 },{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){
8824 'use strict';
8826 exports.__esModule = true;
8828 var _component = _dereq_(5);
8830 var _component2 = _interopRequireDefault(_component);
8832 var _document = _dereq_(94);
8834 var _document2 = _interopRequireDefault(_document);
8836 var _window = _dereq_(95);
8838 var _window2 = _interopRequireDefault(_window);
8840 var _events = _dereq_(82);
8842 var Events = _interopRequireWildcard(_events);
8844 var _dom = _dereq_(81);
8846 var Dom = _interopRequireWildcard(_dom);
8848 var _fn = _dereq_(83);
8850 var Fn = _interopRequireWildcard(_fn);
8852 var _guid = _dereq_(85);
8854 var Guid = _interopRequireWildcard(_guid);
8856 var _browser = _dereq_(78);
8858 var browser = _interopRequireWildcard(_browser);
8860 var _log = _dereq_(86);
8862 var _log2 = _interopRequireDefault(_log);
8864 var _toTitleCase = _dereq_(91);
8866 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
8868 var _timeRanges = _dereq_(90);
8870 var _buffer = _dereq_(79);
8872 var _stylesheet = _dereq_(89);
8874 var stylesheet = _interopRequireWildcard(_stylesheet);
8876 var _fullscreenApi = _dereq_(44);
8878 var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
8880 var _mediaError = _dereq_(46);
8882 var _mediaError2 = _interopRequireDefault(_mediaError);
8884 var _tuple = _dereq_(97);
8886 var _tuple2 = _interopRequireDefault(_tuple);
8888 var _obj = _dereq_(88);
8890 var _mergeOptions = _dereq_(87);
8892 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
8894 var _textTrackListConverter = _dereq_(69);
8896 var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
8898 var _modalDialog = _dereq_(50);
8900 var _modalDialog2 = _interopRequireDefault(_modalDialog);
8902 var _tech = _dereq_(62);
8904 var _tech2 = _interopRequireDefault(_tech);
8906 var _audioTrackList = _dereq_(63);
8908 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
8910 var _videoTrackList = _dereq_(76);
8912 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
8914 _dereq_(61);
8916 _dereq_(59);
8918 _dereq_(55);
8920 _dereq_(68);
8922 _dereq_(45);
8924 _dereq_(1);
8926 _dereq_(4);
8928 _dereq_(8);
8930 _dereq_(41);
8932 _dereq_(71);
8934 _dereq_(60);
8936 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8938 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8940 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8942 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8944 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8945                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file player.js
8946                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8947 // Subclasses Component
8950 // The following imports are used only to ensure that the corresponding modules
8951 // are always included in the video.js package. Importing the modules will
8952 // execute them and they will register themselves with video.js.
8955 // Import Html5 tech, at least for disposing the original video tag.
8958 // The following tech events are simply re-triggered
8959 // on the player when they happen
8960 var TECH_EVENTS_RETRIGGER = [
8962  * Fired while the user agent is downloading media data.
8964  * @event Player#progress
8965  * @type {EventTarget~Event}
8966  */
8968  * Retrigger the `progress` event that was triggered by the {@link Tech}.
8970  * @private
8971  * @method Player#handleTechProgress_
8972  * @fires Player#progress
8973  * @listens Tech#progress
8974  */
8975 'progress',
8978  * Fires when the loading of an audio/video is aborted.
8980  * @event Player#abort
8981  * @type {EventTarget~Event}
8982  */
8984  * Retrigger the `abort` event that was triggered by the {@link Tech}.
8986  * @private
8987  * @method Player#handleTechAbort_
8988  * @fires Player#abort
8989  * @listens Tech#abort
8990  */
8991 'abort',
8994  * Fires when the browser is intentionally not getting media data.
8996  * @event Player#suspend
8997  * @type {EventTarget~Event}
8998  */
9000  * Retrigger the `suspend` event that was triggered by the {@link Tech}.
9002  * @private
9003  * @method Player#handleTechSuspend_
9004  * @fires Player#suspend
9005  * @listens Tech#suspend
9006  */
9007 'suspend',
9010  * Fires when the current playlist is empty.
9012  * @event Player#emptied
9013  * @type {EventTarget~Event}
9014  */
9016  * Retrigger the `emptied` event that was triggered by the {@link Tech}.
9018  * @private
9019  * @method Player#handleTechEmptied_
9020  * @fires Player#emptied
9021  * @listens Tech#emptied
9022  */
9023 'emptied',
9025  * Fires when the browser is trying to get media data, but data is not available.
9027  * @event Player#stalled
9028  * @type {EventTarget~Event}
9029  */
9031  * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9033  * @private
9034  * @method Player#handleTechStalled_
9035  * @fires Player#stalled
9036  * @listens Tech#stalled
9037  */
9038 'stalled',
9041  * Fires when the browser has loaded meta data for the audio/video.
9043  * @event Player#loadedmetadata
9044  * @type {EventTarget~Event}
9045  */
9047  * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9049  * @private
9050  * @method Player#handleTechLoadedmetadata_
9051  * @fires Player#loadedmetadata
9052  * @listens Tech#loadedmetadata
9053  */
9054 'loadedmetadata',
9057  * Fires when the browser has loaded the current frame of the audio/video.
9059  * @event player#loadeddata
9060  * @type {event}
9061  */
9063  * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
9065  * @private
9066  * @method Player#handleTechLoaddeddata_
9067  * @fires Player#loadeddata
9068  * @listens Tech#loadeddata
9069  */
9070 'loadeddata',
9073  * Fires when the current playback position has changed.
9075  * @event player#timeupdate
9076  * @type {event}
9077  */
9079  * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
9081  * @private
9082  * @method Player#handleTechTimeUpdate_
9083  * @fires Player#timeupdate
9084  * @listens Tech#timeupdate
9085  */
9086 'timeupdate',
9089  * Fires when the playing speed of the audio/video is changed
9091  * @event player#ratechange
9092  * @type {event}
9093  */
9095  * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
9097  * @private
9098  * @method Player#handleTechRatechange_
9099  * @fires Player#ratechange
9100  * @listens Tech#ratechange
9101  */
9102 'ratechange',
9105  * Fires when the volume has been changed
9107  * @event player#volumechange
9108  * @type {event}
9109  */
9111  * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
9113  * @private
9114  * @method Player#handleTechVolumechange_
9115  * @fires Player#volumechange
9116  * @listens Tech#volumechange
9117  */
9118 'volumechange',
9121  * Fires when the text track has been changed
9123  * @event player#texttrackchange
9124  * @type {event}
9125  */
9127  * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
9129  * @private
9130  * @method Player#handleTechTexttrackchange_
9131  * @fires Player#texttrackchange
9132  * @listens Tech#texttrackchange
9133  */
9134 'texttrackchange'];
9137  * An instance of the `Player` class is created when any of the Video.js setup methods
9138  * are used to initialize a video.
9140  * After an instance has been created it can be accessed globally in two ways:
9141  * 1. By calling `videojs('example_video_1');`
9142  * 2. By using it directly via  `videojs.players.example_video_1;`
9144  * @extends Component
9145  */
9147 var Player = function (_Component) {
9148   _inherits(Player, _Component);
9150   /**
9151    * Create an instance of this class.
9152    *
9153    * @param {Element} tag
9154    *        The original video DOM element used for configuring options.
9155    *
9156    * @param {Object} [options]
9157    *        Object of option names and values.
9158    *
9159    * @param {Component~ReadyCallback} [ready]
9160    *        Ready callback function.
9161    */
9162   function Player(tag, options, ready) {
9163     _classCallCheck(this, Player);
9165     // Make sure tag ID exists
9166     tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
9168     // Set Options
9169     // The options argument overrides options set in the video tag
9170     // which overrides globally set options.
9171     // This latter part coincides with the load order
9172     // (tag must exist before Player)
9173     options = (0, _obj.assign)(Player.getTagSettings(tag), options);
9175     // Delay the initialization of children because we need to set up
9176     // player properties first, and can't use `this` before `super()`
9177     options.initChildren = false;
9179     // Same with creating the element
9180     options.createEl = false;
9182     // we don't want the player to report touch activity on itself
9183     // see enableTouchActivity in Component
9184     options.reportTouchActivity = false;
9186     // If language is not set, get the closest lang attribute
9187     if (!options.language) {
9188       if (typeof tag.closest === 'function') {
9189         var closest = tag.closest('[lang]');
9191         if (closest) {
9192           options.language = closest.getAttribute('lang');
9193         }
9194       } else {
9195         var element = tag;
9197         while (element && element.nodeType === 1) {
9198           if (Dom.getElAttributes(element).hasOwnProperty('lang')) {
9199             options.language = element.getAttribute('lang');
9200             break;
9201           }
9202           element = element.parentNode;
9203         }
9204       }
9205     }
9207     // Run base component initializing with new options
9209     // if the global option object was accidentally blown away by
9210     // someone, bail early with an informative error
9211     var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
9213     if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
9214       throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
9215     }
9217     // Store the original tag used to set options
9218     _this.tag = tag;
9220     // Store the tag attributes used to restore html5 element
9221     _this.tagAttributes = tag && Dom.getElAttributes(tag);
9223     // Update current language
9224     _this.language(_this.options_.language);
9226     // Update Supported Languages
9227     if (options.languages) {
9228       (function () {
9229         // Normalise player option languages to lowercase
9230         var languagesToLower = {};
9232         Object.getOwnPropertyNames(options.languages).forEach(function (name) {
9233           languagesToLower[name.toLowerCase()] = options.languages[name];
9234         });
9235         _this.languages_ = languagesToLower;
9236       })();
9237     } else {
9238       _this.languages_ = Player.prototype.options_.languages;
9239     }
9241     // Cache for video property values.
9242     _this.cache_ = {};
9244     // Set poster
9245     _this.poster_ = options.poster || '';
9247     // Set controls
9248     _this.controls_ = !!options.controls;
9250     // Original tag settings stored in options
9251     // now remove immediately so native controls don't flash.
9252     // May be turned back on by HTML5 tech if nativeControlsForTouch is true
9253     tag.controls = false;
9255     /*
9256      * Store the internal state of scrubbing
9257      *
9258      * @private
9259      * @return {Boolean} True if the user is scrubbing
9260      */
9261     _this.scrubbing_ = false;
9263     _this.el_ = _this.createEl();
9265     // We also want to pass the original player options to each component and plugin
9266     // as well so they don't need to reach back into the player for options later.
9267     // We also need to do another copy of this.options_ so we don't end up with
9268     // an infinite loop.
9269     var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
9271     // Load plugins
9272     if (options.plugins) {
9273       (function () {
9274         var plugins = options.plugins;
9276         Object.getOwnPropertyNames(plugins).forEach(function (name) {
9277           if (typeof this[name] === 'function') {
9278             this[name](plugins[name]);
9279           } else {
9280             _log2['default'].error('Unable to find plugin:', name);
9281           }
9282         }, _this);
9283       })();
9284     }
9286     _this.options_.playerOptions = playerOptionsCopy;
9288     _this.initChildren();
9290     // Set isAudio based on whether or not an audio tag was used
9291     _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
9293     // Update controls className. Can't do this when the controls are initially
9294     // set because the element doesn't exist yet.
9295     if (_this.controls()) {
9296       _this.addClass('vjs-controls-enabled');
9297     } else {
9298       _this.addClass('vjs-controls-disabled');
9299     }
9301     // Set ARIA label and region role depending on player type
9302     _this.el_.setAttribute('role', 'region');
9303     if (_this.isAudio()) {
9304       _this.el_.setAttribute('aria-label', 'audio player');
9305     } else {
9306       _this.el_.setAttribute('aria-label', 'video player');
9307     }
9309     if (_this.isAudio()) {
9310       _this.addClass('vjs-audio');
9311     }
9313     if (_this.flexNotSupported_()) {
9314       _this.addClass('vjs-no-flex');
9315     }
9317     // TODO: Make this smarter. Toggle user state between touching/mousing
9318     // using events, since devices can have both touch and mouse events.
9319     // if (browser.TOUCH_ENABLED) {
9320     //   this.addClass('vjs-touch-enabled');
9321     // }
9323     // iOS Safari has broken hover handling
9324     if (!browser.IS_IOS) {
9325       _this.addClass('vjs-workinghover');
9326     }
9328     // Make player easily findable by ID
9329     Player.players[_this.id_] = _this;
9331     // When the player is first initialized, trigger activity so components
9332     // like the control bar show themselves if needed
9333     _this.userActive(true);
9334     _this.reportUserActivity();
9335     _this.listenForUserActivity_();
9337     _this.on('fullscreenchange', _this.handleFullscreenChange_);
9338     _this.on('stageclick', _this.handleStageClick_);
9339     return _this;
9340   }
9342   /**
9343    * Destroys the video player and does any necessary cleanup.
9344    *
9345    * This is especially helpful if you are dynamically adding and removing videos
9346    * to/from the DOM.
9347    *
9348    * @fires Player#dispose
9349    */
9352   Player.prototype.dispose = function dispose() {
9353     /**
9354      * Called when the player is being disposed of.
9355      *
9356      * @event Player#dispose
9357      * @type {EventTarget~Event}
9358      */
9359     this.trigger('dispose');
9360     // prevent dispose from being called twice
9361     this.off('dispose');
9363     if (this.styleEl_ && this.styleEl_.parentNode) {
9364       this.styleEl_.parentNode.removeChild(this.styleEl_);
9365     }
9367     // Kill reference to this player
9368     Player.players[this.id_] = null;
9370     if (this.tag && this.tag.player) {
9371       this.tag.player = null;
9372     }
9374     if (this.el_ && this.el_.player) {
9375       this.el_.player = null;
9376     }
9378     if (this.tech_) {
9379       this.tech_.dispose();
9380     }
9382     _Component.prototype.dispose.call(this);
9383   };
9385   /**
9386    * Create the `Player`'s DOM element.
9387    *
9388    * @return {Element}
9389    *         The DOM element that gets created.
9390    */
9393   Player.prototype.createEl = function createEl() {
9394     var tag = this.tag;
9395     var el = void 0;
9396     var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute('data-vjs-player');
9398     if (playerElIngest) {
9399       el = this.el_ = tag.parentNode;
9400     } else {
9401       el = this.el_ = _Component.prototype.createEl.call(this, 'div');
9402     }
9404     // Remove width/height attrs from tag so CSS can make it 100% width/height
9405     tag.removeAttribute('width');
9406     tag.removeAttribute('height');
9408     // Copy over all the attributes from the tag, including ID and class
9409     // ID will now reference player box, not the video tag
9410     var attrs = Dom.getElAttributes(tag);
9412     Object.getOwnPropertyNames(attrs).forEach(function (attr) {
9413       // workaround so we don't totally break IE7
9414       // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
9415       if (attr === 'class') {
9416         el.className += ' ' + attrs[attr];
9417       } else {
9418         el.setAttribute(attr, attrs[attr]);
9419       }
9420     });
9422     // Update tag id/class for use as HTML5 playback tech
9423     // Might think we should do this after embedding in container so .vjs-tech class
9424     // doesn't flash 100% width/height, but class only applies with .video-js parent
9425     tag.playerId = tag.id;
9426     tag.id += '_html5_api';
9427     tag.className = 'vjs-tech';
9429     // Make player findable on elements
9430     tag.player = el.player = this;
9431     // Default state of video is paused
9432     this.addClass('vjs-paused');
9434     // Add a style element in the player that we'll use to set the width/height
9435     // of the player in a way that's still overridable by CSS, just like the
9436     // video element
9437     if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
9438       this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
9439       var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
9440       var head = Dom.$('head');
9442       head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
9443     }
9445     // Pass in the width/height/aspectRatio options which will update the style el
9446     this.width(this.options_.width);
9447     this.height(this.options_.height);
9448     this.fluid(this.options_.fluid);
9449     this.aspectRatio(this.options_.aspectRatio);
9451     // Hide any links within the video/audio tag, because IE doesn't hide them completely.
9452     var links = tag.getElementsByTagName('a');
9454     for (var i = 0; i < links.length; i++) {
9455       var linkEl = links.item(i);
9457       Dom.addElClass(linkEl, 'vjs-hidden');
9458       linkEl.setAttribute('hidden', 'hidden');
9459     }
9461     // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
9462     // keep track of the original for later so we can know if the source originally failed
9463     tag.initNetworkState_ = tag.networkState;
9465     // Wrap video tag in div (el/box) container
9466     if (tag.parentNode && !playerElIngest) {
9467       tag.parentNode.insertBefore(el, tag);
9468     }
9470     // insert the tag as the first child of the player element
9471     // then manually add it to the children array so that this.addChild
9472     // will work properly for other components
9473     //
9474     // Breaks iPhone, fixed in HTML5 setup.
9475     Dom.insertElFirst(tag, el);
9476     this.children_.unshift(tag);
9478     this.el_ = el;
9480     return el;
9481   };
9483   /**
9484    * A getter/setter for the `Player`'s width.
9485    *
9486    * @param {number} [value]
9487    *        The value to set the `Player's width to.
9488    *
9489    * @return {number}
9490    *         The current width of the `Player`.
9491    */
9494   Player.prototype.width = function width(value) {
9495     return this.dimension('width', value);
9496   };
9498   /**
9499    * A getter/setter for the `Player`'s height.
9500    *
9501    * @param {number} [value]
9502    *        The value to set the `Player's height to.
9503    *
9504    * @return {number}
9505    *         The current height of the `Player`.
9506    */
9509   Player.prototype.height = function height(value) {
9510     return this.dimension('height', value);
9511   };
9513   /**
9514    * A getter/setter for the `Player`'s width & height.
9515    *
9516    * @param {string} dimension
9517    *        This string can be:
9518    *        - 'width'
9519    *        - 'height'
9520    *
9521    * @param {number} [value]
9522    *        Value for dimension specified in the first argument.
9523    *
9524    * @return {Player|number}
9525    *         - Returns itself when setting; method can be chained.
9526    *         - The dimension arguments value when getting (width/height).
9527    */
9530   Player.prototype.dimension = function dimension(_dimension, value) {
9531     var privDimension = _dimension + '_';
9533     if (value === undefined) {
9534       return this[privDimension] || 0;
9535     }
9537     if (value === '') {
9538       // If an empty string is given, reset the dimension to be automatic
9539       this[privDimension] = undefined;
9540     } else {
9541       var parsedVal = parseFloat(value);
9543       if (isNaN(parsedVal)) {
9544         _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
9545         return this;
9546       }
9548       this[privDimension] = parsedVal;
9549     }
9551     this.updateStyleEl_();
9552     return this;
9553   };
9555   /**
9556    * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
9557    *
9558    * @param {boolean} [bool]
9559    *        - A value of true adds the class.
9560    *        - A value of false removes the class.
9561    *        - No value will toggle the fluid class.
9562    *
9563    * @return {boolean|undefined}
9564    *         - The value of fluid when getting.
9565    *         - `undefined` when setting.
9566    */
9569   Player.prototype.fluid = function fluid(bool) {
9570     if (bool === undefined) {
9571       return !!this.fluid_;
9572     }
9574     this.fluid_ = !!bool;
9576     if (bool) {
9577       this.addClass('vjs-fluid');
9578     } else {
9579       this.removeClass('vjs-fluid');
9580     }
9582     this.updateStyleEl_();
9583   };
9585   /**
9586    * Get/Set the aspect ratio
9587    *
9588    * @param {string} [ratio]
9589    *        Aspect ratio for player
9590    *
9591    * @return {string|undefined}
9592    *         returns the current aspect ratio when getting
9593    */
9595   /**
9596    * A getter/setter for the `Player`'s aspect ratio.
9597    *
9598    * @param {string} [ratio]
9599    *        The value to set the `Player's aspect ratio to.
9600    *
9601    * @return {string|undefined}
9602    *         - The current aspect ratio of the `Player` when getting.
9603    *         - undefined when setting
9604    */
9607   Player.prototype.aspectRatio = function aspectRatio(ratio) {
9608     if (ratio === undefined) {
9609       return this.aspectRatio_;
9610     }
9612     // Check for width:height format
9613     if (!/^\d+\:\d+$/.test(ratio)) {
9614       throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
9615     }
9616     this.aspectRatio_ = ratio;
9618     // We're assuming if you set an aspect ratio you want fluid mode,
9619     // because in fixed mode you could calculate width and height yourself.
9620     this.fluid(true);
9622     this.updateStyleEl_();
9623   };
9625   /**
9626    * Update styles of the `Player` element (height, width and aspect ratio).
9627    *
9628    * @private
9629    * @listens Tech#loadedmetadata
9630    */
9633   Player.prototype.updateStyleEl_ = function updateStyleEl_() {
9634     if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
9635       var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
9636       var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
9637       var techEl = this.tech_ && this.tech_.el();
9639       if (techEl) {
9640         if (_width >= 0) {
9641           techEl.width = _width;
9642         }
9643         if (_height >= 0) {
9644           techEl.height = _height;
9645         }
9646       }
9648       return;
9649     }
9651     var width = void 0;
9652     var height = void 0;
9653     var aspectRatio = void 0;
9654     var idClass = void 0;
9656     // The aspect ratio is either used directly or to calculate width and height.
9657     if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
9658       // Use any aspectRatio that's been specifically set
9659       aspectRatio = this.aspectRatio_;
9660     } else if (this.videoWidth() > 0) {
9661       // Otherwise try to get the aspect ratio from the video metadata
9662       aspectRatio = this.videoWidth() + ':' + this.videoHeight();
9663     } else {
9664       // Or use a default. The video element's is 2:1, but 16:9 is more common.
9665       aspectRatio = '16:9';
9666     }
9668     // Get the ratio as a decimal we can use to calculate dimensions
9669     var ratioParts = aspectRatio.split(':');
9670     var ratioMultiplier = ratioParts[1] / ratioParts[0];
9672     if (this.width_ !== undefined) {
9673       // Use any width that's been specifically set
9674       width = this.width_;
9675     } else if (this.height_ !== undefined) {
9676       // Or calculate the width from the aspect ratio if a height has been set
9677       width = this.height_ / ratioMultiplier;
9678     } else {
9679       // Or use the video's metadata, or use the video el's default of 300
9680       width = this.videoWidth() || 300;
9681     }
9683     if (this.height_ !== undefined) {
9684       // Use any height that's been specifically set
9685       height = this.height_;
9686     } else {
9687       // Otherwise calculate the height from the ratio and the width
9688       height = width * ratioMultiplier;
9689     }
9691     // Ensure the CSS class is valid by starting with an alpha character
9692     if (/^[^a-zA-Z]/.test(this.id())) {
9693       idClass = 'dimensions-' + this.id();
9694     } else {
9695       idClass = this.id() + '-dimensions';
9696     }
9698     // Ensure the right class is still on the player for the style element
9699     this.addClass(idClass);
9701     stylesheet.setTextContent(this.styleEl_, '\n      .' + idClass + ' {\n        width: ' + width + 'px;\n        height: ' + height + 'px;\n      }\n\n      .' + idClass + '.vjs-fluid {\n        padding-top: ' + ratioMultiplier * 100 + '%;\n      }\n    ');
9702   };
9704   /**
9705    * Load/Create an instance of playback {@link Tech} including element
9706    * and API methods. Then append the `Tech` element in `Player` as a child.
9707    *
9708    * @param {string} techName
9709    *        name of the playback technology
9710    *
9711    * @param {string} source
9712    *        video source
9713    *
9714    * @private
9715    */
9718   Player.prototype.loadTech_ = function loadTech_(techName, source) {
9719     var _this2 = this;
9721     // Pause and remove current playback technology
9722     if (this.tech_) {
9723       this.unloadTech_();
9724     }
9726     // get rid of the HTML5 video tag as soon as we are using another tech
9727     if (techName !== 'Html5' && this.tag) {
9728       _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
9729       this.tag.player = null;
9730       this.tag = null;
9731     }
9733     this.techName_ = techName;
9735     // Turn off API access because we're loading a new tech that might load asynchronously
9736     this.isReady_ = false;
9738     // Grab tech-specific options from player options and add source and parent element to use.
9739     var techOptions = (0, _obj.assign)({
9740       source: source,
9741       'nativeControlsForTouch': this.options_.nativeControlsForTouch,
9742       'playerId': this.id(),
9743       'techId': this.id() + '_' + techName + '_api',
9744       'videoTracks': this.videoTracks_,
9745       'textTracks': this.textTracks_,
9746       'audioTracks': this.audioTracks_,
9747       'autoplay': this.options_.autoplay,
9748       'preload': this.options_.preload,
9749       'loop': this.options_.loop,
9750       'muted': this.options_.muted,
9751       'poster': this.poster(),
9752       'language': this.language(),
9753       'playerElIngest': this.playerElIngest_ || false,
9754       'vtt.js': this.options_['vtt.js']
9755     }, this.options_[techName.toLowerCase()]);
9757     if (this.tag) {
9758       techOptions.tag = this.tag;
9759     }
9761     if (source) {
9762       this.currentType_ = source.type;
9764       if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
9765         techOptions.startTime = this.cache_.currentTime;
9766       }
9768       this.cache_.sources = null;
9769       this.cache_.source = source;
9770       this.cache_.src = source.src;
9771     }
9773     // Initialize tech instance
9774     var TechComponent = _tech2['default'].getTech(techName);
9776     // Support old behavior of techs being registered as components.
9777     // Remove once that deprecated behavior is removed.
9778     if (!TechComponent) {
9779       TechComponent = _component2['default'].getComponent(techName);
9780     }
9781     this.tech_ = new TechComponent(techOptions);
9783     // player.triggerReady is always async, so don't need this to be async
9784     this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
9786     _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
9788     // Listen to all HTML5-defined events and trigger them on the player
9789     TECH_EVENTS_RETRIGGER.forEach(function (event) {
9790       _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
9791     });
9792     this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
9793     this.on(this.tech_, 'waiting', this.handleTechWaiting_);
9794     this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
9795     this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
9796     this.on(this.tech_, 'playing', this.handleTechPlaying_);
9797     this.on(this.tech_, 'ended', this.handleTechEnded_);
9798     this.on(this.tech_, 'seeking', this.handleTechSeeking_);
9799     this.on(this.tech_, 'seeked', this.handleTechSeeked_);
9800     this.on(this.tech_, 'play', this.handleTechPlay_);
9801     this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
9802     this.on(this.tech_, 'pause', this.handleTechPause_);
9803     this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
9804     this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
9805     this.on(this.tech_, 'error', this.handleTechError_);
9806     this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
9807     this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
9808     this.on(this.tech_, 'textdata', this.handleTechTextData_);
9810     this.usingNativeControls(this.techGet_('controls'));
9812     if (this.controls() && !this.usingNativeControls()) {
9813       this.addTechControlsListeners_();
9814     }
9816     // Add the tech element in the DOM if it was not already there
9817     // Make sure to not insert the original video element if using Html5
9818     if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
9819       Dom.insertElFirst(this.tech_.el(), this.el());
9820     }
9822     // Get rid of the original video tag reference after the first tech is loaded
9823     if (this.tag) {
9824       this.tag.player = null;
9825       this.tag = null;
9826     }
9827   };
9829   /**
9830    * Unload and dispose of the current playback {@link Tech}.
9831    *
9832    * @private
9833    */
9836   Player.prototype.unloadTech_ = function unloadTech_() {
9837     // Save the current text tracks so that we can reuse the same text tracks with the next tech
9838     this.videoTracks_ = this.videoTracks();
9839     this.textTracks_ = this.textTracks();
9840     this.audioTracks_ = this.audioTracks();
9841     this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
9843     this.isReady_ = false;
9845     this.tech_.dispose();
9847     this.tech_ = false;
9848   };
9850   /**
9851    * Return a reference to the current {@link Tech}, but only if given an object with the
9852    * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse
9853    * of techs by plugins.
9854    *
9855    * @param {Object} safety
9856    *        An object that must contain `{IWillNotUseThisInPlugins: true}`
9857    *
9858    * @param {boolean} safety.IWillNotUseThisInPlugins
9859    *        Must be set to true or else this function will throw an error.
9860    *
9861    * @return {Tech}
9862    *         The Tech
9863    */
9866   Player.prototype.tech = function tech(safety) {
9867     if (safety && safety.IWillNotUseThisInPlugins) {
9868       return this.tech_;
9869     }
9870     var errorText = '\n      Please make sure that you are not using this inside of a plugin.\n      To disable this alert and error, please pass in an object with\n      `IWillNotUseThisInPlugins` to the `tech` method. See\n      https://github.com/videojs/video.js/issues/2617 for more info.\n    ';
9872     _window2['default'].alert(errorText);
9873     throw new Error(errorText);
9874   };
9876   /**
9877    * Set up click and touch listeners for the playback element
9878    *
9879    * - On desktops: a click on the video itself will toggle playback
9880    * - On mobile devices: a click on the video toggles controls
9881    *   which is done by toggling the user state between active and
9882    *   inactive
9883    * - A tap can signal that a user has become active or has become inactive
9884    *   e.g. a quick tap on an iPhone movie should reveal the controls. Another
9885    *   quick tap should hide them again (signaling the user is in an inactive
9886    *   viewing state)
9887    * - In addition to this, we still want the user to be considered inactive after
9888    *   a few seconds of inactivity.
9889    *
9890    * > Note: the only part of iOS interaction we can't mimic with this setup
9891    * is a touch and hold on the video element counting as activity in order to
9892    * keep the controls showing, but that shouldn't be an issue. A touch and hold
9893    * on any controls will still keep the user active
9894    *
9895    * @private
9896    */
9899   Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
9900     // Make sure to remove all the previous listeners in case we are called multiple times.
9901     this.removeTechControlsListeners_();
9903     // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
9904     // trigger mousedown/up.
9905     // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
9906     // Any touch events are set to block the mousedown event from happening
9907     this.on(this.tech_, 'mousedown', this.handleTechClick_);
9909     // If the controls were hidden we don't want that to change without a tap event
9910     // so we'll check if the controls were already showing before reporting user
9911     // activity
9912     this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
9913     this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
9914     this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
9916     // The tap listener needs to come after the touchend listener because the tap
9917     // listener cancels out any reportedUserActivity when setting userActive(false)
9918     this.on(this.tech_, 'tap', this.handleTechTap_);
9919   };
9921   /**
9922    * Remove the listeners used for click and tap controls. This is needed for
9923    * toggling to controls disabled, where a tap/touch should do nothing.
9924    *
9925    * @private
9926    */
9929   Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
9930     // We don't want to just use `this.off()` because there might be other needed
9931     // listeners added by techs that extend this.
9932     this.off(this.tech_, 'tap', this.handleTechTap_);
9933     this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
9934     this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
9935     this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
9936     this.off(this.tech_, 'mousedown', this.handleTechClick_);
9937   };
9939   /**
9940    * Player waits for the tech to be ready
9941    *
9942    * @private
9943    */
9946   Player.prototype.handleTechReady_ = function handleTechReady_() {
9947     this.triggerReady();
9949     // Keep the same volume as before
9950     if (this.cache_.volume) {
9951       this.techCall_('setVolume', this.cache_.volume);
9952     }
9954     // Look if the tech found a higher resolution poster while loading
9955     this.handleTechPosterChange_();
9957     // Update the duration if available
9958     this.handleTechDurationChange_();
9960     // Chrome and Safari both have issues with autoplay.
9961     // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
9962     // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
9963     // This fixes both issues. Need to wait for API, so it updates displays correctly
9964     if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
9965       try {
9966         // Chrome Fix. Fixed in Chrome v16.
9967         delete this.tag.poster;
9968       } catch (e) {
9969         (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
9970       }
9971       this.play();
9972     }
9973   };
9975   /**
9976    * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
9977    * function will also trigger {@link Player#firstplay} if it is the first loadstart
9978    * for a video.
9979    *
9980    * @fires Player#loadstart
9981    * @fires Player#firstplay
9982    * @listens Tech#loadstart
9983    * @private
9984    */
9987   Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
9988     // TODO: Update to use `emptied` event instead. See #1277.
9990     this.removeClass('vjs-ended');
9991     this.removeClass('vjs-seeking');
9993     // reset the error state
9994     this.error(null);
9996     // If it's already playing we want to trigger a firstplay event now.
9997     // The firstplay event relies on both the play and loadstart events
9998     // which can happen in any order for a new source
9999     if (!this.paused()) {
10000       /**
10001        * Fired when the user agent begins looking for media data
10002        *
10003        * @event Player#loadstart
10004        * @type {EventTarget~Event}
10005        */
10006       this.trigger('loadstart');
10007       this.trigger('firstplay');
10008     } else {
10009       // reset the hasStarted state
10010       this.hasStarted(false);
10011       this.trigger('loadstart');
10012     }
10013   };
10015   /**
10016    * Add/remove the vjs-has-started class
10017    *
10018    * @fires Player#firstplay
10019    *
10020    * @param {boolean} hasStarted
10021    *        - true: adds the class
10022    *        - false: remove the class
10023    *
10024    * @return {boolean}
10025    *         the boolean value of hasStarted
10026    */
10029   Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10030     if (_hasStarted !== undefined) {
10031       // only update if this is a new value
10032       if (this.hasStarted_ !== _hasStarted) {
10033         this.hasStarted_ = _hasStarted;
10034         if (_hasStarted) {
10035           this.addClass('vjs-has-started');
10036           // trigger the firstplay event if this newly has played
10037           this.trigger('firstplay');
10038         } else {
10039           this.removeClass('vjs-has-started');
10040         }
10041       }
10042       return this;
10043     }
10044     return !!this.hasStarted_;
10045   };
10047   /**
10048    * Fired whenever the media begins or resumes playback
10049    *
10050    * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
10051    * @fires Player#play
10052    * @listens Tech#play
10053    * @private
10054    */
10057   Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10058     this.removeClass('vjs-ended');
10059     this.removeClass('vjs-paused');
10060     this.addClass('vjs-playing');
10062     // hide the poster when the user hits play
10063     this.hasStarted(true);
10064     /**
10065      * Triggered whenever an {@link Tech#play} event happens. Indicates that
10066      * playback has started or resumed.
10067      *
10068      * @event Player#play
10069      * @type {EventTarget~Event}
10070      */
10071     this.trigger('play');
10072   };
10074   /**
10075    * Retrigger the `waiting` event that was triggered by the {@link Tech}.
10076    *
10077    * @fires Player#waiting
10078    * @listens Tech#waiting
10079    * @private
10080    */
10083   Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10084     var _this3 = this;
10086     this.addClass('vjs-waiting');
10087     /**
10088      * A readyState change on the DOM element has caused playback to stop.
10089      *
10090      * @event Player#waiting
10091      * @type {EventTarget~Event}
10092      */
10093     this.trigger('waiting');
10094     this.one('timeupdate', function () {
10095       return _this3.removeClass('vjs-waiting');
10096     });
10097   };
10099   /**
10100    * Retrigger the `canplay` event that was triggered by the {@link Tech}.
10101    * > Note: This is not consistent between browsers. See #1351
10102    *
10103    * @fires Player#canplay
10104    * @listens Tech#canplay
10105    * @private
10106    */
10109   Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10110     this.removeClass('vjs-waiting');
10111     /**
10112      * The media has a readyState of HAVE_FUTURE_DATA or greater.
10113      *
10114      * @event Player#canplay
10115      * @type {EventTarget~Event}
10116      */
10117     this.trigger('canplay');
10118   };
10120   /**
10121    * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
10122    *
10123    * @fires Player#canplaythrough
10124    * @listens Tech#canplaythrough
10125    * @private
10126    */
10129   Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10130     this.removeClass('vjs-waiting');
10131     /**
10132      * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
10133      * entire media file can be played without buffering.
10134      *
10135      * @event Player#canplaythrough
10136      * @type {EventTarget~Event}
10137      */
10138     this.trigger('canplaythrough');
10139   };
10141   /**
10142    * Retrigger the `playing` event that was triggered by the {@link Tech}.
10143    *
10144    * @fires Player#playing
10145    * @listens Tech#playing
10146    * @private
10147    */
10150   Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
10151     this.removeClass('vjs-waiting');
10152     /**
10153      * The media is no longer blocked from playback, and has started playing.
10154      *
10155      * @event Player#playing
10156      * @type {EventTarget~Event}
10157      */
10158     this.trigger('playing');
10159   };
10161   /**
10162    * Retrigger the `seeking` event that was triggered by the {@link Tech}.
10163    *
10164    * @fires Player#seeking
10165    * @listens Tech#seeking
10166    * @private
10167    */
10170   Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
10171     this.addClass('vjs-seeking');
10172     /**
10173      * Fired whenever the player is jumping to a new time
10174      *
10175      * @event Player#seeking
10176      * @type {EventTarget~Event}
10177      */
10178     this.trigger('seeking');
10179   };
10181   /**
10182    * Retrigger the `seeked` event that was triggered by the {@link Tech}.
10183    *
10184    * @fires Player#seeked
10185    * @listens Tech#seeked
10186    * @private
10187    */
10190   Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
10191     this.removeClass('vjs-seeking');
10192     /**
10193      * Fired when the player has finished jumping to a new time
10194      *
10195      * @event Player#seeked
10196      * @type {EventTarget~Event}
10197      */
10198     this.trigger('seeked');
10199   };
10201   /**
10202    * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
10203    *
10204    * @fires Player#firstplay
10205    * @listens Tech#firstplay
10206    * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
10207    * @private
10208    */
10211   Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
10212     // If the first starttime attribute is specified
10213     // then we will start at the given offset in seconds
10214     if (this.options_.starttime) {
10215       _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
10216       this.currentTime(this.options_.starttime);
10217     }
10219     this.addClass('vjs-has-started');
10220     /**
10221      * Fired the first time a video is played. Not part of the HLS spec, and this is
10222      * probably not the best implementation yet, so use sparingly. If you don't have a
10223      * reason to prevent playback, use `myPlayer.one('play');` instead.
10224      *
10225      * @event Player#firstplay
10226      * @type {EventTarget~Event}
10227      */
10228     this.trigger('firstplay');
10229   };
10231   /**
10232    * Retrigger the `pause` event that was triggered by the {@link Tech}.
10233    *
10234    * @fires Player#pause
10235    * @listens Tech#pause
10236    * @private
10237    */
10240   Player.prototype.handleTechPause_ = function handleTechPause_() {
10241     this.removeClass('vjs-playing');
10242     this.addClass('vjs-paused');
10243     /**
10244      * Fired whenever the media has been paused
10245      *
10246      * @event Player#pause
10247      * @type {EventTarget~Event}
10248      */
10249     this.trigger('pause');
10250   };
10252   /**
10253    * Retrigger the `ended` event that was triggered by the {@link Tech}.
10254    *
10255    * @fires Player#ended
10256    * @listens Tech#ended
10257    * @private
10258    */
10261   Player.prototype.handleTechEnded_ = function handleTechEnded_() {
10262     this.addClass('vjs-ended');
10263     if (this.options_.loop) {
10264       this.currentTime(0);
10265       this.play();
10266     } else if (!this.paused()) {
10267       this.pause();
10268     }
10270     /**
10271      * Fired when the end of the media resource is reached (currentTime == duration)
10272      *
10273      * @event Player#ended
10274      * @type {EventTarget~Event}
10275      */
10276     this.trigger('ended');
10277   };
10279   /**
10280    * Fired when the duration of the media resource is first known or changed
10281    *
10282    * @listens Tech#durationchange
10283    * @private
10284    */
10287   Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
10288     this.duration(this.techGet_('duration'));
10289   };
10291   /**
10292    * Handle a click on the media element to play/pause
10293    *
10294    * @param {EventTarget~Event} event
10295    *        the event that caused this function to trigger
10296    *
10297    * @listens Tech#mousedown
10298    * @private
10299    */
10302   Player.prototype.handleTechClick_ = function handleTechClick_(event) {
10303     // We're using mousedown to detect clicks thanks to Flash, but mousedown
10304     // will also be triggered with right-clicks, so we need to prevent that
10305     if (event.button !== 0) {
10306       return;
10307     }
10309     // When controls are disabled a click should not toggle playback because
10310     // the click is considered a control
10311     if (this.controls()) {
10312       if (this.paused()) {
10313         this.play();
10314       } else {
10315         this.pause();
10316       }
10317     }
10318   };
10320   /**
10321    * Handle a tap on the media element. It will toggle the user
10322    * activity state, which hides and shows the controls.
10323    *
10324    * @listens Tech#tap
10325    * @private
10326    */
10329   Player.prototype.handleTechTap_ = function handleTechTap_() {
10330     this.userActive(!this.userActive());
10331   };
10333   /**
10334    * Handle touch to start
10335    *
10336    * @listens Tech#touchstart
10337    * @private
10338    */
10341   Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
10342     this.userWasActive = this.userActive();
10343   };
10345   /**
10346    * Handle touch to move
10347    *
10348    * @listens Tech#touchmove
10349    * @private
10350    */
10353   Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
10354     if (this.userWasActive) {
10355       this.reportUserActivity();
10356     }
10357   };
10359   /**
10360    * Handle touch to end
10361    *
10362    * @param {EventTarget~Event} event
10363    *        the touchend event that triggered
10364    *        this function
10365    *
10366    * @listens Tech#touchend
10367    * @private
10368    */
10371   Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
10372     // Stop the mouse events from also happening
10373     event.preventDefault();
10374   };
10376   /**
10377    * Fired when the player switches in or out of fullscreen mode
10378    *
10379    * @private
10380    * @listens Player#fullscreenchange
10381    */
10384   Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
10385     if (this.isFullscreen()) {
10386       this.addClass('vjs-fullscreen');
10387     } else {
10388       this.removeClass('vjs-fullscreen');
10389     }
10390   };
10392   /**
10393    * native click events on the SWF aren't triggered on IE11, Win8.1RT
10394    * use stageclick events triggered from inside the SWF instead
10395    *
10396    * @private
10397    * @listens stageclick
10398    */
10401   Player.prototype.handleStageClick_ = function handleStageClick_() {
10402     this.reportUserActivity();
10403   };
10405   /**
10406    * Handle Tech Fullscreen Change
10407    *
10408    * @param {EventTarget~Event} event
10409    *        the fullscreenchange event that triggered this function
10410    *
10411    * @param {Object} data
10412    *        the data that was sent with the event
10413    *
10414    * @private
10415    * @listens Tech#fullscreenchange
10416    * @fires Player#fullscreenchange
10417    */
10420   Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
10421     if (data) {
10422       this.isFullscreen(data.isFullscreen);
10423     }
10424     /**
10425      * Fired when going in and out of fullscreen.
10426      *
10427      * @event Player#fullscreenchange
10428      * @type {EventTarget~Event}
10429      */
10430     this.trigger('fullscreenchange');
10431   };
10433   /**
10434    * Fires when an error occurred during the loading of an audio/video.
10435    *
10436    * @private
10437    * @listens Tech#error
10438    */
10441   Player.prototype.handleTechError_ = function handleTechError_() {
10442     var error = this.tech_.error();
10444     this.error(error);
10445   };
10447   /**
10448    * Retrigger the `textdata` event that was triggered by the {@link Tech}.
10449    *
10450    * @fires Player#textdata
10451    * @listens Tech#textdata
10452    * @private
10453    */
10456   Player.prototype.handleTechTextData_ = function handleTechTextData_() {
10457     var data = null;
10459     if (arguments.length > 1) {
10460       data = arguments[1];
10461     }
10463     /**
10464      * Fires when we get a textdata event from tech
10465      *
10466      * @event Player#textdata
10467      * @type {EventTarget~Event}
10468      */
10469     this.trigger('textdata', data);
10470   };
10472   /**
10473    * Get object for cached values.
10474    *
10475    * @return {Object}
10476    *         get the current object cache
10477    */
10480   Player.prototype.getCache = function getCache() {
10481     return this.cache_;
10482   };
10484   /**
10485    * Pass values to the playback tech
10486    *
10487    * @param {string} [method]
10488    *        the method to call
10489    *
10490    * @param {Object} arg
10491    *        the argument to pass
10492    *
10493    * @private
10494    */
10497   Player.prototype.techCall_ = function techCall_(method, arg) {
10498     // If it's not ready yet, call method when it is
10499     if (this.tech_ && !this.tech_.isReady_) {
10500       this.tech_.ready(function () {
10501         this[method](arg);
10502       }, true);
10504       // Otherwise call method now
10505     } else {
10506       try {
10507         if (this.tech_) {
10508           this.tech_[method](arg);
10509         }
10510       } catch (e) {
10511         (0, _log2['default'])(e);
10512         throw e;
10513       }
10514     }
10515   };
10517   /**
10518    * Get calls can't wait for the tech, and sometimes don't need to.
10519    *
10520    * @param {string} method
10521    *        Tech method
10522    *
10523    * @return {Function|undefined}
10524    *         the method or undefined
10525    *
10526    * @private
10527    */
10530   Player.prototype.techGet_ = function techGet_(method) {
10531     if (this.tech_ && this.tech_.isReady_) {
10533       // Flash likes to die and reload when you hide or reposition it.
10534       // In these cases the object methods go away and we get errors.
10535       // When that happens we'll catch the errors and inform tech that it's not ready any more.
10536       try {
10537         return this.tech_[method]();
10538       } catch (e) {
10539         // When building additional tech libs, an expected method may not be defined yet
10540         if (this.tech_[method] === undefined) {
10541           (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
10543           // When a method isn't available on the object it throws a TypeError
10544         } else if (e.name === 'TypeError') {
10545           (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
10546           this.tech_.isReady_ = false;
10547         } else {
10548           (0, _log2['default'])(e);
10549         }
10550         throw e;
10551       }
10552     }
10554     return;
10555   };
10557   /**
10558    * start media playback
10559    *
10560    * @return {Player}
10561    *         A reference to the player object this function was called on
10562    */
10565   Player.prototype.play = function play() {
10566     // Only calls the tech's play if we already have a src loaded
10567     if (this.src() || this.currentSrc()) {
10568       this.techCall_('play');
10569     } else {
10570       this.tech_.one('loadstart', function () {
10571         this.play();
10572       });
10573     }
10575     return this;
10576   };
10578   /**
10579    * Pause the video playback
10580    *
10581    * @return {Player}
10582    *         A reference to the player object this function was called on
10583    */
10586   Player.prototype.pause = function pause() {
10587     this.techCall_('pause');
10588     return this;
10589   };
10591   /**
10592    * Check if the player is paused or has yet to play
10593    *
10594    * @return {boolean}
10595    *         - false: if the media is currently playing
10596    *         - true: if media is not currently playing
10597    */
10600   Player.prototype.paused = function paused() {
10601     // The initial state of paused should be true (in Safari it's actually false)
10602     return this.techGet_('paused') === false ? false : true;
10603   };
10605   /**
10606    * Returns whether or not the user is "scrubbing". Scrubbing is
10607    * when the user has clicked the progress bar handle and is
10608    * dragging it along the progress bar.
10609    *
10610    * @param {boolean} [isScrubbing]
10611    *        whether the user is or is not scrubbing
10612    *
10613    * @return {boolean|Player}
10614    *         A instance of the player that called this function when setting,
10615    *         and the value of scrubbing when getting
10616    */
10619   Player.prototype.scrubbing = function scrubbing(isScrubbing) {
10620     if (isScrubbing !== undefined) {
10621       this.scrubbing_ = !!isScrubbing;
10623       if (isScrubbing) {
10624         this.addClass('vjs-scrubbing');
10625       } else {
10626         this.removeClass('vjs-scrubbing');
10627       }
10629       return this;
10630     }
10632     return this.scrubbing_;
10633   };
10635   /**
10636    * Get or set the current time (in seconds)
10637    *
10638    * @param {number|string} [seconds]
10639    *        The time to seek to in seconds
10640    *
10641    * @return {Player|number}
10642    *         - the current time in seconds when getting
10643    *         - a reference to the current player object when
10644    *           getting
10645    */
10648   Player.prototype.currentTime = function currentTime(seconds) {
10649     if (seconds !== undefined) {
10651       this.techCall_('setCurrentTime', seconds);
10653       return this;
10654     }
10656     // cache last currentTime and return. default to 0 seconds
10657     //
10658     // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10659     // currentTime when scrubbing, but may not provide much performance benefit after all.
10660     // Should be tested. Also something has to read the actual current time or the cache will
10661     // never get updated.
10662     this.cache_.currentTime = this.techGet_('currentTime') || 0;
10663     return this.cache_.currentTime;
10664   };
10666   /**
10667    * Normally gets the length in time of the video in seconds;
10668    * in all but the rarest use cases an argument will NOT be passed to the method
10669    *
10670    * > **NOTE**: The video must have started loading before the duration can be
10671    * known, and in the case of Flash, may not be known until the video starts
10672    * playing.
10673    *
10674    * @fires Player#durationchange
10675    *
10676    * @param {number} [seconds]
10677    *        The duration of the video to set in seconds
10678    *
10679    * @return {number|Player}
10680    *         - The duration of the video in seconds when getting
10681    *         - A reference to the player that called this function
10682    *           when setting
10683    */
10686   Player.prototype.duration = function duration(seconds) {
10687     if (seconds === undefined) {
10688       return this.cache_.duration || 0;
10689     }
10691     seconds = parseFloat(seconds) || 0;
10693     // Standardize on Inifity for signaling video is live
10694     if (seconds < 0) {
10695       seconds = Infinity;
10696     }
10698     if (seconds !== this.cache_.duration) {
10699       // Cache the last set value for optimized scrubbing (esp. Flash)
10700       this.cache_.duration = seconds;
10702       if (seconds === Infinity) {
10703         this.addClass('vjs-live');
10704       } else {
10705         this.removeClass('vjs-live');
10706       }
10707       /**
10708        * @event Player#durationchange
10709        * @type {EventTarget~Event}
10710        */
10711       this.trigger('durationchange');
10712     }
10714     return this;
10715   };
10717   /**
10718    * Calculates how much time is left in the video. Not part
10719    * of the native video API.
10720    *
10721    * @return {number}
10722    *         The time remaining in seconds
10723    */
10726   Player.prototype.remainingTime = function remainingTime() {
10727     return this.duration() - this.currentTime();
10728   };
10730   //
10731   // Kind of like an array of portions of the video that have been downloaded.
10733   /**
10734    * Get a TimeRange object with an array of the times of the video
10735    * that have been downloaded. If you just want the percent of the
10736    * video that's been downloaded, use bufferedPercent.
10737    *
10738    * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
10739    *
10740    * @return {TimeRange}
10741    *         A mock TimeRange object (following HTML spec)
10742    */
10745   Player.prototype.buffered = function buffered() {
10746     var buffered = this.techGet_('buffered');
10748     if (!buffered || !buffered.length) {
10749       buffered = (0, _timeRanges.createTimeRange)(0, 0);
10750     }
10752     return buffered;
10753   };
10755   /**
10756    * Get the percent (as a decimal) of the video that's been downloaded.
10757    * This method is not a part of the native HTML video API.
10758    *
10759    * @return {number}
10760    *         A decimal between 0 and 1 representing the percent
10761    *         that is buffered 0 being 0% and 1 being 100%
10762    */
10765   Player.prototype.bufferedPercent = function bufferedPercent() {
10766     return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
10767   };
10769   /**
10770    * Get the ending time of the last buffered time range
10771    * This is used in the progress bar to encapsulate all time ranges.
10772    *
10773    * @return {number}
10774    *         The end of the last buffered time range
10775    */
10778   Player.prototype.bufferedEnd = function bufferedEnd() {
10779     var buffered = this.buffered();
10780     var duration = this.duration();
10781     var end = buffered.end(buffered.length - 1);
10783     if (end > duration) {
10784       end = duration;
10785     }
10787     return end;
10788   };
10790   /**
10791    * Get or set the current volume of the media
10792    *
10793    * @param  {number} [percentAsDecimal]
10794    *         The new volume as a decimal percent:
10795    *         - 0 is muted/0%/off
10796    *         - 1.0 is 100%/full
10797    *         - 0.5 is half volume or 50%
10798    *
10799    * @return {Player|number}
10800    *         a reference to the calling player when setting and the
10801    *         current volume as a percent when getting
10802    */
10805   Player.prototype.volume = function volume(percentAsDecimal) {
10806     var vol = void 0;
10808     if (percentAsDecimal !== undefined) {
10809       // Force value to between 0 and 1
10810       vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
10811       this.cache_.volume = vol;
10812       this.techCall_('setVolume', vol);
10814       return this;
10815     }
10817     // Default to 1 when returning current volume.
10818     vol = parseFloat(this.techGet_('volume'));
10819     return isNaN(vol) ? 1 : vol;
10820   };
10822   /**
10823    * Get the current muted state, or turn mute on or off
10824    *
10825    * @param {boolean} [muted]
10826    *        - true to mute
10827    *        - false to unmute
10828    *
10829    * @return {boolean|Player}
10830    *         - true if mute is on and getting
10831    *         - false if mute is off and getting
10832    *         - A reference to the current player when setting
10833    */
10836   Player.prototype.muted = function muted(_muted) {
10837     if (_muted !== undefined) {
10838       this.techCall_('setMuted', _muted);
10839       return this;
10840     }
10841     return this.techGet_('muted') || false;
10842   };
10844   /**
10845    * Check if current tech can support native fullscreen
10846    * (e.g. with built in controls like iOS, so not our flash swf)
10847    *
10848    * @return {boolean}
10849    *         if native fullscreen is supported
10850    */
10853   Player.prototype.supportsFullScreen = function supportsFullScreen() {
10854     return this.techGet_('supportsFullScreen') || false;
10855   };
10857   /**
10858    * Check if the player is in fullscreen mode or tell the player that it
10859    * is or is not in fullscreen mode.
10860    *
10861    * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
10862    * property and instead document.fullscreenElement is used. But isFullscreen is
10863    * still a valuable property for internal player workings.
10864    *
10865    * @param  {boolean} [isFS]
10866    *         Set the players current fullscreen state
10867    *
10868    * @return {boolean|Player}
10869    *         - true if fullscreen is on and getting
10870    *         - false if fullscreen is off and getting
10871    *         - A reference to the current player when setting
10872    */
10875   Player.prototype.isFullscreen = function isFullscreen(isFS) {
10876     if (isFS !== undefined) {
10877       this.isFullscreen_ = !!isFS;
10878       return this;
10879     }
10880     return !!this.isFullscreen_;
10881   };
10883   /**
10884    * Increase the size of the video to full screen
10885    * In some browsers, full screen is not supported natively, so it enters
10886    * "full window mode", where the video fills the browser window.
10887    * In browsers and devices that support native full screen, sometimes the
10888    * browser's default controls will be shown, and not the Video.js custom skin.
10889    * This includes most mobile devices (iOS, Android) and older versions of
10890    * Safari.
10891    *
10892    * @fires Player#fullscreenchange
10893    * @return {Player}
10894    *         A reference to the current player
10895    */
10898   Player.prototype.requestFullscreen = function requestFullscreen() {
10899     var fsApi = _fullscreenApi2['default'];
10901     this.isFullscreen(true);
10903     if (fsApi.requestFullscreen) {
10904       // the browser supports going fullscreen at the element level so we can
10905       // take the controls fullscreen as well as the video
10907       // Trigger fullscreenchange event after change
10908       // We have to specifically add this each time, and remove
10909       // when canceling fullscreen. Otherwise if there's multiple
10910       // players on a page, they would all be reacting to the same fullscreen
10911       // events
10912       Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
10913         this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
10915         // If cancelling fullscreen, remove event listener.
10916         if (this.isFullscreen() === false) {
10917           Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
10918         }
10919         /**
10920          * @event Player#fullscreenchange
10921          * @type {EventTarget~Event}
10922          */
10923         this.trigger('fullscreenchange');
10924       }));
10926       this.el_[fsApi.requestFullscreen]();
10927     } else if (this.tech_.supportsFullScreen()) {
10928       // we can't take the video.js controls fullscreen but we can go fullscreen
10929       // with native controls
10930       this.techCall_('enterFullScreen');
10931     } else {
10932       // fullscreen isn't supported so we'll just stretch the video element to
10933       // fill the viewport
10934       this.enterFullWindow();
10935       /**
10936        * @event Player#fullscreenchange
10937        * @type {EventTarget~Event}
10938        */
10939       this.trigger('fullscreenchange');
10940     }
10942     return this;
10943   };
10945   /**
10946    * Return the video to its normal size after having been in full screen mode
10947    *
10948    * @fires Player#fullscreenchange
10949    *
10950    * @return {Player}
10951    *         A reference to the current player
10952    */
10955   Player.prototype.exitFullscreen = function exitFullscreen() {
10956     var fsApi = _fullscreenApi2['default'];
10958     this.isFullscreen(false);
10960     // Check for browser element fullscreen support
10961     if (fsApi.requestFullscreen) {
10962       _document2['default'][fsApi.exitFullscreen]();
10963     } else if (this.tech_.supportsFullScreen()) {
10964       this.techCall_('exitFullScreen');
10965     } else {
10966       this.exitFullWindow();
10967       /**
10968        * @event Player#fullscreenchange
10969        * @type {EventTarget~Event}
10970        */
10971       this.trigger('fullscreenchange');
10972     }
10974     return this;
10975   };
10977   /**
10978    * When fullscreen isn't supported we can stretch the
10979    * video container to as wide as the browser will let us.
10980    *
10981    * @fires Player#enterFullWindow
10982    */
10985   Player.prototype.enterFullWindow = function enterFullWindow() {
10986     this.isFullWindow = true;
10988     // Storing original doc overflow value to return to when fullscreen is off
10989     this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
10991     // Add listener for esc key to exit fullscreen
10992     Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
10994     // Hide any scroll bars
10995     _document2['default'].documentElement.style.overflow = 'hidden';
10997     // Apply fullscreen styles
10998     Dom.addElClass(_document2['default'].body, 'vjs-full-window');
11000     /**
11001      * @event Player#enterFullWindow
11002      * @type {EventTarget~Event}
11003      */
11004     this.trigger('enterFullWindow');
11005   };
11007   /**
11008    * Check for call to either exit full window or
11009    * full screen on ESC key
11010    *
11011    * @param {string} event
11012    *        Event to check for key press
11013    */
11016   Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11017     if (event.keyCode === 27) {
11018       if (this.isFullscreen() === true) {
11019         this.exitFullscreen();
11020       } else {
11021         this.exitFullWindow();
11022       }
11023     }
11024   };
11026   /**
11027    * Exit full window
11028    *
11029    * @fires Player#exitFullWindow
11030    */
11033   Player.prototype.exitFullWindow = function exitFullWindow() {
11034     this.isFullWindow = false;
11035     Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
11037     // Unhide scroll bars.
11038     _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
11040     // Remove fullscreen styles
11041     Dom.removeElClass(_document2['default'].body, 'vjs-full-window');
11043     // Resize the box, controller, and poster to original sizes
11044     // this.positionAll();
11045     /**
11046      * @event Player#exitFullWindow
11047      * @type {EventTarget~Event}
11048      */
11049     this.trigger('exitFullWindow');
11050   };
11052   /**
11053    * Check whether the player can play a given mimetype
11054    *
11055    * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
11056    *
11057    * @param {string} type
11058    *        The mimetype to check
11059    *
11060    * @return {string}
11061    *         'probably', 'maybe', or '' (empty string)
11062    */
11065   Player.prototype.canPlayType = function canPlayType(type) {
11066     var can = void 0;
11068     // Loop through each playback technology in the options order
11069     for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11070       var techName = (0, _toTitleCase2['default'])(j[i]);
11071       var tech = _tech2['default'].getTech(techName);
11073       // Support old behavior of techs being registered as components.
11074       // Remove once that deprecated behavior is removed.
11075       if (!tech) {
11076         tech = _component2['default'].getComponent(techName);
11077       }
11079       // Check if the current tech is defined before continuing
11080       if (!tech) {
11081         _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11082         continue;
11083       }
11085       // Check if the browser supports this technology
11086       if (tech.isSupported()) {
11087         can = tech.canPlayType(type);
11089         if (can) {
11090           return can;
11091         }
11092       }
11093     }
11095     return '';
11096   };
11098   /**
11099    * Select source based on tech-order or source-order
11100    * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11101    * defaults to tech-order selection
11102    *
11103    * @param {Array} sources
11104    *        The sources for a media asset
11105    *
11106    * @return {Object|boolean}
11107    *         Object of source and tech order or false
11108    */
11111   Player.prototype.selectSource = function selectSource(sources) {
11112     var _this4 = this;
11114     // Get only the techs specified in `techOrder` that exist and are supported by the
11115     // current platform
11116     var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) {
11117       // `Component.getComponent(...)` is for support of old behavior of techs
11118       // being registered as components.
11119       // Remove once that deprecated behavior is removed.
11120       return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)];
11121     }).filter(function (_ref) {
11122       var techName = _ref[0],
11123           tech = _ref[1];
11125       // Check if the current tech is defined before continuing
11126       if (tech) {
11127         // Check if the browser supports this technology
11128         return tech.isSupported();
11129       }
11131       _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11132       return false;
11133     });
11135     // Iterate over each `innerArray` element once per `outerArray` element and execute
11136     // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11137     // that value.
11138     var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11139       var found = void 0;
11141       outerArray.some(function (outerChoice) {
11142         return innerArray.some(function (innerChoice) {
11143           found = tester(outerChoice, innerChoice);
11145           if (found) {
11146             return true;
11147           }
11148         });
11149       });
11151       return found;
11152     };
11154     var foundSourceAndTech = void 0;
11155     var flip = function flip(fn) {
11156       return function (a, b) {
11157         return fn(b, a);
11158       };
11159     };
11160     var finder = function finder(_ref2, source) {
11161       var techName = _ref2[0],
11162           tech = _ref2[1];
11164       if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) {
11165         return { source: source, tech: techName };
11166       }
11167     };
11169     // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11170     // to select from them based on their priority.
11171     if (this.options_.sourceOrder) {
11172       // Source-first ordering
11173       foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11174     } else {
11175       // Tech-first ordering
11176       foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11177     }
11179     return foundSourceAndTech || false;
11180   };
11182   /**
11183    * The source function updates the video source
11184    * There are three types of variables you can pass as the argument.
11185    * **URL string**: A URL to the the video file. Use this method if you are sure
11186    * the current playback technology (HTML5/Flash) can support the source you
11187    * provide. Currently only MP4 files can be used in both HTML5 and Flash.
11188    *
11189    * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
11190    *        One SourceObject or an array of SourceObjects
11191    *
11192    * @return {string|Player}
11193    *         - The current video source when getting
11194    *         - The player when setting
11195    */
11198   Player.prototype.src = function src(source) {
11199     if (source === undefined) {
11200       return this.techGet_('src');
11201     }
11203     var currentTech = _tech2['default'].getTech(this.techName_);
11205     // Support old behavior of techs being registered as components.
11206     // Remove once that deprecated behavior is removed.
11207     if (!currentTech) {
11208       currentTech = _component2['default'].getComponent(this.techName_);
11209     }
11211     // case: Array of source objects to choose from and pick the best to play
11212     if (Array.isArray(source)) {
11213       this.sourceList_(source);
11215       // case: URL String (http://myvideo...)
11216     } else if (typeof source === 'string') {
11217       // create a source object from the string
11218       this.src({ src: source });
11220       // case: Source object { src: '', type: '' ... }
11221     } else if (source instanceof Object) {
11222       // check if the source has a type and the loaded tech cannot play the source
11223       // if there's no type we'll just try the current tech
11224       if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) {
11225         // create a source list with the current source and send through
11226         // the tech loop to check for a compatible technology
11227         this.sourceList_([source]);
11228       } else {
11229         this.cache_.sources = null;
11230         this.cache_.source = source;
11231         this.cache_.src = source.src;
11233         this.currentType_ = source.type || '';
11235         // wait until the tech is ready to set the source
11236         this.ready(function () {
11238           // The setSource tech method was added with source handlers
11239           // so older techs won't support it
11240           // We need to check the direct prototype for the case where subclasses
11241           // of the tech do not support source handlers
11242           if (currentTech.prototype.hasOwnProperty('setSource')) {
11243             this.techCall_('setSource', source);
11244           } else {
11245             this.techCall_('src', source.src);
11246           }
11248           if (this.options_.preload === 'auto') {
11249             this.load();
11250           }
11252           if (this.options_.autoplay) {
11253             this.play();
11254           }
11256           // Set the source synchronously if possible (#2326)
11257         }, true);
11258       }
11259     }
11261     return this;
11262   };
11264   /**
11265    * Handle an array of source objects
11266    *
11267    * @param  {Tech~SourceObject[]} sources
11268    *         Array of source objects
11269    *
11270    * @private
11271    */
11274   Player.prototype.sourceList_ = function sourceList_(sources) {
11275     var sourceTech = this.selectSource(sources);
11277     if (sourceTech) {
11278       if (sourceTech.tech === this.techName_) {
11279         // if this technology is already loaded, set the source
11280         this.src(sourceTech.source);
11281       } else {
11282         // load this technology with the chosen source
11283         this.loadTech_(sourceTech.tech, sourceTech.source);
11284       }
11286       this.cache_.sources = sources;
11287     } else {
11288       // We need to wrap this in a timeout to give folks a chance to add error event handlers
11289       this.setTimeout(function () {
11290         this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
11291       }, 0);
11293       // we could not find an appropriate tech, but let's still notify the delegate that this is it
11294       // this needs a better comment about why this is needed
11295       this.triggerReady();
11296     }
11297   };
11299   /**
11300    * Begin loading the src data.
11301    *
11302    * @return {Player}
11303    *         A reference to the player
11304    */
11307   Player.prototype.load = function load() {
11308     this.techCall_('load');
11309     return this;
11310   };
11312   /**
11313    * Reset the player. Loads the first tech in the techOrder,
11314    * and calls `reset` on the tech`.
11315    *
11316    * @return {Player}
11317    *         A reference to the player
11318    */
11321   Player.prototype.reset = function reset() {
11322     this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null);
11323     this.techCall_('reset');
11324     return this;
11325   };
11327   /**
11328    * Returns all of the current source objects.
11329    *
11330    * @return {Tech~SourceObject[]}
11331    *         The current source objects
11332    */
11335   Player.prototype.currentSources = function currentSources() {
11336     var source = this.currentSource();
11337     var sources = [];
11339     // assume `{}` or `{ src }`
11340     if (Object.keys(source).length !== 0) {
11341       sources.push(source);
11342     }
11344     return this.cache_.sources || sources;
11345   };
11347   /**
11348    * Returns the current source object.
11349    *
11350    * @return {Tech~SourceObject}
11351    *         The current source object
11352    */
11355   Player.prototype.currentSource = function currentSource() {
11356     var source = {};
11357     var src = this.currentSrc();
11359     if (src) {
11360       source.src = src;
11361     }
11363     return this.cache_.source || source;
11364   };
11366   /**
11367    * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
11368    * Can be used in conjunction with `currentType` to assist in rebuilding the current source object.
11369    *
11370    * @return {string}
11371    *         The current source
11372    */
11375   Player.prototype.currentSrc = function currentSrc() {
11376     return this.techGet_('currentSrc') || this.cache_.src || '';
11377   };
11379   /**
11380    * Get the current source type e.g. video/mp4
11381    * This can allow you rebuild the current source object so that you could load the same
11382    * source and tech later
11383    *
11384    * @return {string}
11385    *         The source MIME type
11386    */
11389   Player.prototype.currentType = function currentType() {
11390     return this.currentType_ || '';
11391   };
11393   /**
11394    * Get or set the preload attribute
11395    *
11396    * @param {boolean} [value]
11397    *        - true means that we should preload
11398    *        - false maens that we should not preload
11399    *
11400    * @return {string|Player}
11401    *         - the preload attribute value when getting
11402    *         - the player when setting
11403    */
11406   Player.prototype.preload = function preload(value) {
11407     if (value !== undefined) {
11408       this.techCall_('setPreload', value);
11409       this.options_.preload = value;
11410       return this;
11411     }
11412     return this.techGet_('preload');
11413   };
11415   /**
11416    * Get or set the autoplay attribute.
11417    *
11418    * @param {boolean} [value]
11419    *        - true means that we should autoplay
11420    *        - false maens that we should not autoplay
11421    *
11422    * @return {string|Player}
11423    *         - the current value of autoplay
11424    *         - the player when setting
11425    */
11428   Player.prototype.autoplay = function autoplay(value) {
11429     if (value !== undefined) {
11430       this.techCall_('setAutoplay', value);
11431       this.options_.autoplay = value;
11432       return this;
11433     }
11434     return this.techGet_('autoplay', value);
11435   };
11437   /**
11438    * Get or set the loop attribute on the video element.
11439    *
11440    * @param {boolean} [value]
11441    *        - true means that we should loop the video
11442    *        - false means that we should not loop the video
11443    *
11444    * @return {string|Player}
11445    *         - the current value of loop when getting
11446    *         - the player when setting
11447    */
11450   Player.prototype.loop = function loop(value) {
11451     if (value !== undefined) {
11452       this.techCall_('setLoop', value);
11453       this.options_.loop = value;
11454       return this;
11455     }
11456     return this.techGet_('loop');
11457   };
11459   /**
11460    * Get or set the poster image source url
11461    *
11462    * @fires Player#posterchange
11463    *
11464    * @param {string} [src]
11465    *        Poster image source URL
11466    *
11467    * @return {string|Player}
11468    *         - the current value of poster when getting
11469    *         - the player when setting
11470    */
11473   Player.prototype.poster = function poster(src) {
11474     if (src === undefined) {
11475       return this.poster_;
11476     }
11478     // The correct way to remove a poster is to set as an empty string
11479     // other falsey values will throw errors
11480     if (!src) {
11481       src = '';
11482     }
11484     // update the internal poster variable
11485     this.poster_ = src;
11487     // update the tech's poster
11488     this.techCall_('setPoster', src);
11490     // alert components that the poster has been set
11491     /**
11492      * This event fires when the poster image is changed on the player.
11493      *
11494      * @event Player#posterchange
11495      * @type {EventTarget~Event}
11496      */
11497     this.trigger('posterchange');
11499     return this;
11500   };
11502   /**
11503    * Some techs (e.g. YouTube) can provide a poster source in an
11504    * asynchronous way. We want the poster component to use this
11505    * poster source so that it covers up the tech's controls.
11506    * (YouTube's play button). However we only want to use this
11507    * source if the player user hasn't set a poster through
11508    * the normal APIs.
11509    *
11510    * @fires Player#posterchange
11511    * @listens Tech#posterchange
11512    * @private
11513    */
11516   Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
11517     if (!this.poster_ && this.tech_ && this.tech_.poster) {
11518       this.poster_ = this.tech_.poster() || '';
11520       // Let components know the poster has changed
11521       this.trigger('posterchange');
11522     }
11523   };
11525   /**
11526    * Get or set whether or not the controls are showing.
11527    *
11528    * @fires Player#controlsenabled
11529    *
11530    * @param {boolean} [bool]
11531    *        - true to turn controls on
11532    *        - false to turn controls off
11533    *
11534    * @return {boolean|Player}
11535    *         - the current value of controls when getting
11536    *         - the player when setting
11537    */
11540   Player.prototype.controls = function controls(bool) {
11541     if (bool !== undefined) {
11542       bool = !!bool;
11544       // Don't trigger a change event unless it actually changed
11545       if (this.controls_ !== bool) {
11546         this.controls_ = bool;
11548         if (this.usingNativeControls()) {
11549           this.techCall_('setControls', bool);
11550         }
11552         if (bool) {
11553           this.removeClass('vjs-controls-disabled');
11554           this.addClass('vjs-controls-enabled');
11555           /**
11556            * @event Player#controlsenabled
11557            * @type {EventTarget~Event}
11558            */
11559           this.trigger('controlsenabled');
11561           if (!this.usingNativeControls()) {
11562             this.addTechControlsListeners_();
11563           }
11564         } else {
11565           this.removeClass('vjs-controls-enabled');
11566           this.addClass('vjs-controls-disabled');
11567           /**
11568            * @event Player#controlsdisabled
11569            * @type {EventTarget~Event}
11570            */
11571           this.trigger('controlsdisabled');
11573           if (!this.usingNativeControls()) {
11574             this.removeTechControlsListeners_();
11575           }
11576         }
11577       }
11578       return this;
11579     }
11580     return !!this.controls_;
11581   };
11583   /**
11584    * Toggle native controls on/off. Native controls are the controls built into
11585    * devices (e.g. default iPhone controls), Flash, or other techs
11586    * (e.g. Vimeo Controls)
11587    * **This should only be set by the current tech, because only the tech knows
11588    * if it can support native controls**
11589    *
11590    * @fires Player#usingnativecontrols
11591    * @fires Player#usingcustomcontrols
11592    *
11593    * @param {boolean} [bool]
11594    *        - true to turn native controls on
11595    *        - false to turn native controls off
11596    *
11597    * @return {boolean|Player}
11598    *         - the current value of native controls when getting
11599    *         - the player when setting
11600    */
11603   Player.prototype.usingNativeControls = function usingNativeControls(bool) {
11604     if (bool !== undefined) {
11605       bool = !!bool;
11607       // Don't trigger a change event unless it actually changed
11608       if (this.usingNativeControls_ !== bool) {
11609         this.usingNativeControls_ = bool;
11610         if (bool) {
11611           this.addClass('vjs-using-native-controls');
11613           /**
11614            * player is using the native device controls
11615            *
11616            * @event Player#usingnativecontrols
11617            * @type {EventTarget~Event}
11618            */
11619           this.trigger('usingnativecontrols');
11620         } else {
11621           this.removeClass('vjs-using-native-controls');
11623           /**
11624            * player is using the custom HTML controls
11625            *
11626            * @event Player#usingcustomcontrols
11627            * @type {EventTarget~Event}
11628            */
11629           this.trigger('usingcustomcontrols');
11630         }
11631       }
11632       return this;
11633     }
11634     return !!this.usingNativeControls_;
11635   };
11637   /**
11638    * Set or get the current MediaError
11639    *
11640    * @fires Player#error
11641    *
11642    * @param  {MediaError|string|number} [err]
11643    *         A MediaError or a string/number to be turned
11644    *         into a MediaError
11645    *
11646    * @return {MediaError|null|Player}
11647    *         - The current MediaError when getting (or null)
11648    *         - The player when setting
11649    */
11652   Player.prototype.error = function error(err) {
11653     if (err === undefined) {
11654       return this.error_ || null;
11655     }
11657     // restoring to default
11658     if (err === null) {
11659       this.error_ = err;
11660       this.removeClass('vjs-error');
11661       if (this.errorDisplay) {
11662         this.errorDisplay.close();
11663       }
11664       return this;
11665     }
11667     this.error_ = new _mediaError2['default'](err);
11669     // add the vjs-error classname to the player
11670     this.addClass('vjs-error');
11672     // log the name of the error type and any message
11673     // ie8 just logs "[object object]" if you just log the error object
11674     _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
11676     /**
11677      * @event Player#error
11678      * @type {EventTarget~Event}
11679      */
11680     this.trigger('error');
11682     return this;
11683   };
11685   /**
11686    * Report user activity
11687    *
11688    * @param {Object} event
11689    *        Event object
11690    */
11693   Player.prototype.reportUserActivity = function reportUserActivity(event) {
11694     this.userActivity_ = true;
11695   };
11697   /**
11698    * Get/set if user is active
11699    *
11700    * @fires Player#useractive
11701    * @fires Player#userinactive
11702    *
11703    * @param {boolean} [bool]
11704    *        - true if the user is active
11705    *        - false if the user is inactive
11706    * @return {boolean|Player}
11707    *         - the current value of userActive when getting
11708    *         - the player when setting
11709    */
11712   Player.prototype.userActive = function userActive(bool) {
11713     if (bool !== undefined) {
11714       bool = !!bool;
11715       if (bool !== this.userActive_) {
11716         this.userActive_ = bool;
11717         if (bool) {
11718           // If the user was inactive and is now active we want to reset the
11719           // inactivity timer
11720           this.userActivity_ = true;
11721           this.removeClass('vjs-user-inactive');
11722           this.addClass('vjs-user-active');
11723           /**
11724            * @event Player#useractive
11725            * @type {EventTarget~Event}
11726            */
11727           this.trigger('useractive');
11728         } else {
11729           // We're switching the state to inactive manually, so erase any other
11730           // activity
11731           this.userActivity_ = false;
11733           // Chrome/Safari/IE have bugs where when you change the cursor it can
11734           // trigger a mousemove event. This causes an issue when you're hiding
11735           // the cursor when the user is inactive, and a mousemove signals user
11736           // activity. Making it impossible to go into inactive mode. Specifically
11737           // this happens in fullscreen when we really need to hide the cursor.
11738           //
11739           // When this gets resolved in ALL browsers it can be removed
11740           // https://code.google.com/p/chromium/issues/detail?id=103041
11741           if (this.tech_) {
11742             this.tech_.one('mousemove', function (e) {
11743               e.stopPropagation();
11744               e.preventDefault();
11745             });
11746           }
11748           this.removeClass('vjs-user-active');
11749           this.addClass('vjs-user-inactive');
11750           /**
11751            * @event Player#userinactive
11752            * @type {EventTarget~Event}
11753            */
11754           this.trigger('userinactive');
11755         }
11756       }
11757       return this;
11758     }
11759     return this.userActive_;
11760   };
11762   /**
11763    * Listen for user activity based on timeout value
11764    *
11765    * @private
11766    */
11769   Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
11770     var mouseInProgress = void 0;
11771     var lastMoveX = void 0;
11772     var lastMoveY = void 0;
11773     var handleActivity = Fn.bind(this, this.reportUserActivity);
11775     var handleMouseMove = function handleMouseMove(e) {
11776       // #1068 - Prevent mousemove spamming
11777       // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
11778       if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
11779         lastMoveX = e.screenX;
11780         lastMoveY = e.screenY;
11781         handleActivity();
11782       }
11783     };
11785     var handleMouseDown = function handleMouseDown() {
11786       handleActivity();
11787       // For as long as the they are touching the device or have their mouse down,
11788       // we consider them active even if they're not moving their finger or mouse.
11789       // So we want to continue to update that they are active
11790       this.clearInterval(mouseInProgress);
11791       // Setting userActivity=true now and setting the interval to the same time
11792       // as the activityCheck interval (250) should ensure we never miss the
11793       // next activityCheck
11794       mouseInProgress = this.setInterval(handleActivity, 250);
11795     };
11797     var handleMouseUp = function handleMouseUp(event) {
11798       handleActivity();
11799       // Stop the interval that maintains activity if the mouse/touch is down
11800       this.clearInterval(mouseInProgress);
11801     };
11803     // Any mouse movement will be considered user activity
11804     this.on('mousedown', handleMouseDown);
11805     this.on('mousemove', handleMouseMove);
11806     this.on('mouseup', handleMouseUp);
11808     // Listen for keyboard navigation
11809     // Shouldn't need to use inProgress interval because of key repeat
11810     this.on('keydown', handleActivity);
11811     this.on('keyup', handleActivity);
11813     // Run an interval every 250 milliseconds instead of stuffing everything into
11814     // the mousemove/touchmove function itself, to prevent performance degradation.
11815     // `this.reportUserActivity` simply sets this.userActivity_ to true, which
11816     // then gets picked up by this loop
11817     // http://ejohn.org/blog/learning-from-twitter/
11818     var inactivityTimeout = void 0;
11820     this.setInterval(function () {
11821       // Check to see if mouse/touch activity has happened
11822       if (this.userActivity_) {
11823         // Reset the activity tracker
11824         this.userActivity_ = false;
11826         // If the user state was inactive, set the state to active
11827         this.userActive(true);
11829         // Clear any existing inactivity timeout to start the timer over
11830         this.clearTimeout(inactivityTimeout);
11832         var timeout = this.options_.inactivityTimeout;
11834         if (timeout > 0) {
11835           // In <timeout> milliseconds, if no more activity has occurred the
11836           // user will be considered inactive
11837           inactivityTimeout = this.setTimeout(function () {
11838             // Protect against the case where the inactivityTimeout can trigger just
11839             // before the next user activity is picked up by the activity check loop
11840             // causing a flicker
11841             if (!this.userActivity_) {
11842               this.userActive(false);
11843             }
11844           }, timeout);
11845         }
11846       }
11847     }, 250);
11848   };
11850   /**
11851    * Gets or sets the current playback rate. A playback rate of
11852    * 1.0 represents normal speed and 0.5 would indicate half-speed
11853    * playback, for instance.
11854    *
11855    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
11856    *
11857    * @param {number} [rate]
11858    *       New playback rate to set.
11859    *
11860    * @return {number|Player}
11861    *         - The current playback rate when getting or 1.0
11862    *         - the player when setting
11863    */
11866   Player.prototype.playbackRate = function playbackRate(rate) {
11867     if (rate !== undefined) {
11868       this.techCall_('setPlaybackRate', rate);
11869       return this;
11870     }
11872     if (this.tech_ && this.tech_.featuresPlaybackRate) {
11873       return this.techGet_('playbackRate');
11874     }
11875     return 1.0;
11876   };
11878   /**
11879    * Gets or sets the audio flag
11880    *
11881    * @param {boolean} bool
11882    *        - true signals that this is an audio player
11883    *        - false signals that this is not an audio player
11884    *
11885    * @return {Player|boolean}
11886    *         - the current value of isAudio when getting
11887    *         - the player if setting
11888    */
11891   Player.prototype.isAudio = function isAudio(bool) {
11892     if (bool !== undefined) {
11893       this.isAudio_ = !!bool;
11894       return this;
11895     }
11897     return !!this.isAudio_;
11898   };
11900   /**
11901    * Get the {@link VideoTrackList}
11902    *
11903    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
11904    *
11905    * @return {VideoTrackList}
11906    *         the current video track list
11907    */
11910   Player.prototype.videoTracks = function videoTracks() {
11911     // if we have not yet loadTech_, we create videoTracks_
11912     // these will be passed to the tech during loading
11913     if (!this.tech_) {
11914       this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
11915       return this.videoTracks_;
11916     }
11918     return this.tech_.videoTracks();
11919   };
11921   /**
11922    * Get the {@link AudioTrackList}
11923    *
11924    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
11925    *
11926    * @return {AudioTrackList}
11927    *         the current audio track list
11928    */
11931   Player.prototype.audioTracks = function audioTracks() {
11932     // if we have not yet loadTech_, we create videoTracks_
11933     // these will be passed to the tech during loading
11934     if (!this.tech_) {
11935       this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
11936       return this.audioTracks_;
11937     }
11939     return this.tech_.audioTracks();
11940   };
11942   /**
11943    * Get the {@link TextTrackList}
11944    *
11945    * Text tracks are tracks of timed text events.
11946    * - Captions: text displayed over the video
11947    *             for the hearing impaired
11948    * - Subtitles: text displayed over the video for
11949    *              those who don't understand language in the video
11950    * - Chapters: text displayed in a menu allowing the user to jump
11951    *             to particular points (chapters) in the video
11952    * - Descriptions: (not yet implemented) audio descriptions that are read back to
11953    *                 the user by a screen reading device
11954    *
11955    * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
11956    *
11957    * @return {TextTrackList|undefined}
11958    *         The current TextTrackList or undefined if
11959    *         or undefined if we don't have a tech
11960    */
11963   Player.prototype.textTracks = function textTracks() {
11964     // cannot use techGet_ directly because it checks to see whether the tech is ready.
11965     // Flash is unlikely to be ready in time but textTracks should still work.
11966     if (this.tech_) {
11967       return this.tech_.textTracks();
11968     }
11969   };
11971   /**
11972    * Get the "remote" {@link TextTrackList}. Remote Text Tracks
11973    * are tracks that were added to the HTML video element and can
11974    * be removed, whereas normal texttracks cannot be removed.
11975    *
11976    *
11977    * @return {TextTrackList|undefined}
11978    *         The current remote text track list or undefined
11979    *         if we don't have a tech
11980    */
11983   Player.prototype.remoteTextTracks = function remoteTextTracks() {
11984     if (this.tech_) {
11985       return this.tech_.remoteTextTracks();
11986     }
11987   };
11989   /**
11990    * Get the "remote" {@link HTMLTrackElementList}.
11991    * This gives the user all of the DOM elements that match up
11992    * with the remote {@link TextTrackList}.
11993    *
11994    * @return {HTMLTrackElementList}
11995    *         The current remote text track list elements
11996    *         or undefined if we don't have a tech
11997    */
12000   Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
12001     if (this.tech_) {
12002       return this.tech_.remoteTextTrackEls();
12003     }
12004   };
12006   /**
12007    * A helper method for adding a {@link TextTrack} to our
12008    * {@link TextTrackList}.
12009    *
12010    * In addition to the W3C settings we allow adding additional info through options.
12011    *
12012    * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
12013    *
12014    * @param {string} [kind]
12015    *        the kind of TextTrack you are adding
12016    *
12017    * @param {string} [label]
12018    *        the label to give the TextTrack label
12019    *
12020    * @param {string} [language]
12021    *        the language to set on the TextTrack
12022    *
12023    * @return {TextTrack|undefined}
12024    *         the TextTrack that was added or undefined
12025    *         if there is no tech
12026    */
12029   Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
12030     if (this.tech_) {
12031       return this.tech_.addTextTrack(kind, label, language);
12032     }
12033   };
12035   /**
12036    * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
12037    * automatically removed from the video element whenever the source changes, unless
12038    * manualCleanup is set to false.
12039    *
12040    * @param {Object} options
12041    *        Options to pass to {@link HTMLTrackElement} during creation. See
12042    *        {@link HTMLTrackElement} for object properties that you should use.
12043    *
12044    * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
12045    *
12046    * @return {HTMLTrackElement}
12047    *         the HTMLTrackElement that was created and added
12048    *         to the HTMLTrackElementList and the remote
12049    *         TextTrackList
12050    *
12051    * @deprecated The default value of the "manualCleanup" parameter will default
12052    *             to "false" in upcoming versions of Video.js
12053    */
12056   Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
12057     if (this.tech_) {
12058       return this.tech_.addRemoteTextTrack(options, manualCleanup);
12059     }
12060   };
12062   /**
12063    * Remove a remote {@link TextTrack} from the respective
12064    * {@link TextTrackList} and {@link HTMLTrackElementList}.
12065    *
12066    * @param {Object} track
12067    *        Remote {@link TextTrack} to remove
12068    *
12069    * @return {undefined}
12070    *         does not return anything
12071    */
12074   Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
12075     var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
12076         _ref3$track = _ref3.track,
12077         track = _ref3$track === undefined ? arguments[0] : _ref3$track;
12079     // destructure the input into an object with a track argument, defaulting to arguments[0]
12080     // default the whole argument to an empty object if nothing was passed in
12082     if (this.tech_) {
12083       return this.tech_.removeRemoteTextTrack(track);
12084     }
12085   };
12087   /**
12088    * Get video width
12089    *
12090    * @return {number}
12091    *         current video width
12092    */
12095   Player.prototype.videoWidth = function videoWidth() {
12096     return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12097   };
12099   /**
12100    * Get video height
12101    *
12102    * @return {number}
12103    *         current video height
12104    */
12107   Player.prototype.videoHeight = function videoHeight() {
12108     return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12109   };
12111   // Methods to add support for
12112   // initialTime: function() { return this.techCall_('initialTime'); },
12113   // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
12114   // played: function() { return this.techCall_('played'); },
12115   // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
12116   // defaultMuted: function() { return this.techCall_('defaultMuted'); }
12118   /**
12119    * The player's language code
12120    * NOTE: The language should be set in the player options if you want the
12121    * the controls to be built with a specific language. Changing the language
12122    * later will not update controls text.
12123    *
12124    * @param {string} [code]
12125    *        the language code to set the player to
12126    *
12127    * @return {string|Player}
12128    *         - The current language code when getting
12129    *         - A reference to the player when setting
12130    */
12133   Player.prototype.language = function language(code) {
12134     if (code === undefined) {
12135       return this.language_;
12136     }
12138     this.language_ = String(code).toLowerCase();
12139     return this;
12140   };
12142   /**
12143    * Get the player's language dictionary
12144    * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12145    * Languages specified directly in the player options have precedence
12146    *
12147    * @return {Array}
12148    *         An array of of supported languages
12149    */
12152   Player.prototype.languages = function languages() {
12153     return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
12154   };
12156   /**
12157    * returns a JavaScript object representing the current track
12158    * information. **DOES not return it as JSON**
12159    *
12160    * @return {Object}
12161    *         Object representing the current of track info
12162    */
12165   Player.prototype.toJSON = function toJSON() {
12166     var options = (0, _mergeOptions2['default'])(this.options_);
12167     var tracks = options.tracks;
12169     options.tracks = [];
12171     for (var i = 0; i < tracks.length; i++) {
12172       var track = tracks[i];
12174       // deep merge tracks and null out player so no circular references
12175       track = (0, _mergeOptions2['default'])(track);
12176       track.player = undefined;
12177       options.tracks[i] = track;
12178     }
12180     return options;
12181   };
12183   /**
12184    * Creates a simple modal dialog (an instance of the {@link ModalDialog}
12185    * component) that immediately overlays the player with arbitrary
12186    * content and removes itself when closed.
12187    *
12188    * @param {string|Function|Element|Array|null} content
12189    *        Same as {@link ModalDialog#content}'s param of the same name.
12190    *        The most straight-forward usage is to provide a string or DOM
12191    *        element.
12192    *
12193    * @param {Object} [options]
12194    *        Extra options which will be passed on to the {@link ModalDialog}.
12195    *
12196    * @return {ModalDialog}
12197    *         the {@link ModalDialog} that was created
12198    */
12201   Player.prototype.createModal = function createModal(content, options) {
12202     var _this5 = this;
12204     options = options || {};
12205     options.content = content || '';
12207     var modal = new _modalDialog2['default'](this, options);
12209     this.addChild(modal);
12210     modal.on('dispose', function () {
12211       _this5.removeChild(modal);
12212     });
12214     return modal.open();
12215   };
12217   /**
12218    * Gets tag settings
12219    *
12220    * @param {Element} tag
12221    *        The player tag
12222    *
12223    * @return {Object}
12224    *         An object containing all of the settings
12225    *         for a player tag
12226    */
12229   Player.getTagSettings = function getTagSettings(tag) {
12230     var baseOptions = {
12231       sources: [],
12232       tracks: []
12233     };
12235     var tagOptions = Dom.getElAttributes(tag);
12236     var dataSetup = tagOptions['data-setup'];
12238     if (Dom.hasElClass(tag, 'vjs-fluid')) {
12239       tagOptions.fluid = true;
12240     }
12242     // Check if data-setup attr exists.
12243     if (dataSetup !== null) {
12244       // Parse options JSON
12245       // If empty string, make it a parsable json object.
12246       var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
12247           err = _safeParseTuple[0],
12248           data = _safeParseTuple[1];
12250       if (err) {
12251         _log2['default'].error(err);
12252       }
12253       (0, _obj.assign)(tagOptions, data);
12254     }
12256     (0, _obj.assign)(baseOptions, tagOptions);
12258     // Get tag children settings
12259     if (tag.hasChildNodes()) {
12260       var children = tag.childNodes;
12262       for (var i = 0, j = children.length; i < j; i++) {
12263         var child = children[i];
12264         // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12265         var childName = child.nodeName.toLowerCase();
12267         if (childName === 'source') {
12268           baseOptions.sources.push(Dom.getElAttributes(child));
12269         } else if (childName === 'track') {
12270           baseOptions.tracks.push(Dom.getElAttributes(child));
12271         }
12272       }
12273     }
12275     return baseOptions;
12276   };
12278   /**
12279    * Determine whether or not flexbox is supported
12280    *
12281    * @return {boolean}
12282    *         - true if flexbox is supported
12283    *         - false if flexbox is not supported
12284    */
12287   Player.prototype.flexNotSupported_ = function flexNotSupported_() {
12288     var elem = _document2['default'].createElement('i');
12290     // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
12291     // common flex features that we can rely on when checking for flex support.
12292     return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
12293     // IE10-specific (2012 flex spec)
12294     'msFlexOrder' in elem.style);
12295   };
12297   return Player;
12298 }(_component2['default']);
12301  * Global player list
12303  * @type {Object}
12304  */
12307 Player.players = {};
12309 var navigator = _window2['default'].navigator;
12312  * Player instance options, surfaced using options
12313  * options = Player.prototype.options_
12314  * Make changes in options, not here.
12316  * @type {Object}
12317  * @private
12318  */
12319 Player.prototype.options_ = {
12320   // Default order of fallback technology
12321   techOrder: ['html5', 'flash'],
12322   // techOrder: ['flash','html5'],
12324   html5: {},
12325   flash: {},
12327   // defaultVolume: 0.85,
12328   defaultVolume: 0.00,
12330   // default inactivity timeout
12331   inactivityTimeout: 2000,
12333   // default playback rates
12334   playbackRates: [],
12335   // Add playback rate selection by adding rates
12336   // 'playbackRates': [0.5, 1, 1.5, 2],
12338   // Included control sets
12339   children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
12341   language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
12343   // locales and their language translations
12344   languages: {},
12346   // Default message to show when a video cannot be played.
12347   notSupportedMessage: 'No compatible source was found for this media.'
12352  * Returns whether or not the player is in the "ended" state.
12354  * @return {Boolean} True if the player is in the ended state, false if not.
12355  * @method Player#ended
12356  */
12357 'ended',
12359  * Returns whether or not the player is in the "seeking" state.
12361  * @return {Boolean} True if the player is in the seeking state, false if not.
12362  * @method Player#seeking
12363  */
12364 'seeking',
12366  * Returns the TimeRanges of the media that are currently available
12367  * for seeking to.
12369  * @return {TimeRanges} the seekable intervals of the media timeline
12370  * @method Player#seekable
12371  */
12372 'seekable',
12374  * Returns the current state of network activity for the element, from
12375  * the codes in the list below.
12376  * - NETWORK_EMPTY (numeric value 0)
12377  *   The element has not yet been initialised. All attributes are in
12378  *   their initial states.
12379  * - NETWORK_IDLE (numeric value 1)
12380  *   The element's resource selection algorithm is active and has
12381  *   selected a resource, but it is not actually using the network at
12382  *   this time.
12383  * - NETWORK_LOADING (numeric value 2)
12384  *   The user agent is actively trying to download data.
12385  * - NETWORK_NO_SOURCE (numeric value 3)
12386  *   The element's resource selection algorithm is active, but it has
12387  *   not yet found a resource to use.
12389  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
12390  * @return {number} the current network activity state
12391  * @method Player#networkState
12392  */
12393 'networkState',
12395  * Returns a value that expresses the current state of the element
12396  * with respect to rendering the current playback position, from the
12397  * codes in the list below.
12398  * - HAVE_NOTHING (numeric value 0)
12399  *   No information regarding the media resource is available.
12400  * - HAVE_METADATA (numeric value 1)
12401  *   Enough of the resource has been obtained that the duration of the
12402  *   resource is available.
12403  * - HAVE_CURRENT_DATA (numeric value 2)
12404  *   Data for the immediate current playback position is available.
12405  * - HAVE_FUTURE_DATA (numeric value 3)
12406  *   Data for the immediate current playback position is available, as
12407  *   well as enough data for the user agent to advance the current
12408  *   playback position in the direction of playback.
12409  * - HAVE_ENOUGH_DATA (numeric value 4)
12410  *   The user agent estimates that enough data is available for
12411  *   playback to proceed uninterrupted.
12413  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
12414  * @return {number} the current playback rendering state
12415  * @method Player#readyState
12416  */
12417 'readyState'].forEach(function (fn) {
12418   Player.prototype[fn] = function () {
12419     return this.techGet_(fn);
12420   };
12423 TECH_EVENTS_RETRIGGER.forEach(function (event) {
12424   Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
12425     return this.trigger(event);
12426   };
12430  * Fired when the player has initial duration and dimension information
12432  * @event Player#loadedmetadata
12433  * @type {EventTarget~Event}
12434  */
12437  * Fired when the player has downloaded data at the current playback position
12439  * @event Player#loadeddata
12440  * @type {EventTarget~Event}
12441  */
12444  * Fired when the current playback position has changed *
12445  * During playback this is fired every 15-250 milliseconds, depending on the
12446  * playback technology in use.
12448  * @event Player#timeupdate
12449  * @type {EventTarget~Event}
12450  */
12453  * Fired when the volume changes
12455  * @event Player#volumechange
12456  * @type {EventTarget~Event}
12457  */
12459 _component2['default'].registerComponent('Player', Player);
12460 exports['default'] = Player;
12462 },{"1":1,"4":4,"41":41,"44":44,"45":45,"46":46,"5":5,"50":50,"55":55,"59":59,"60":60,"61":61,"62":62,"63":63,"68":68,"69":69,"71":71,"76":76,"78":78,"79":79,"8":8,"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"94":94,"95":95,"97":97}],52:[function(_dereq_,module,exports){
12463 'use strict';
12465 exports.__esModule = true;
12467 var _player = _dereq_(51);
12469 var _player2 = _interopRequireDefault(_player);
12471 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12474  * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
12476  * @param {string} name
12477  *        The name of the plugin that is being registered
12479  * @param {plugins:PluginFn} init
12480  *        The function that gets run when a `Player` initializes.
12481  */
12482 var plugin = function plugin(name, init) {
12483   _player2['default'].prototype[name] = init;
12484 }; /**
12485     * @file plugins.js
12486     * @module plugins
12487     */
12488 exports['default'] = plugin;
12490 },{"51":51}],53:[function(_dereq_,module,exports){
12491 'use strict';
12493 exports.__esModule = true;
12495 var _clickableComponent = _dereq_(3);
12497 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12499 var _component = _dereq_(5);
12501 var _component2 = _interopRequireDefault(_component);
12503 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12505 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12507 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12509 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12510                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file popup-button.js
12511                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12515  * A button class for use with {@link Popup} controls
12517  * @extends ClickableComponent
12518  */
12519 var PopupButton = function (_ClickableComponent) {
12520   _inherits(PopupButton, _ClickableComponent);
12522   /**
12523    * Create an instance of this class.
12524    *
12525    * @param {Player} player
12526    *        The `Player` that this class should be attached to.
12527    *
12528    * @param {Object} [options]
12529    *        The key/value store of player options.
12530    */
12531   function PopupButton(player) {
12532     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
12534     _classCallCheck(this, PopupButton);
12536     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12538     _this.update();
12539     return _this;
12540   }
12542   /**
12543    * Update the `Popup` that this button is attached to.
12544    */
12547   PopupButton.prototype.update = function update() {
12548     var popup = this.createPopup();
12550     if (this.popup) {
12551       this.removeChild(this.popup);
12552     }
12554     this.popup = popup;
12555     this.addChild(popup);
12557     if (this.items && this.items.length === 0) {
12558       this.hide();
12559     } else if (this.items && this.items.length > 1) {
12560       this.show();
12561     }
12562   };
12564   /**
12565    * Create a `Popup`. - Override with specific functionality for component
12566    *
12567    * @abstract
12568    */
12571   PopupButton.prototype.createPopup = function createPopup() {};
12573   /**
12574    * Create the `PopupButton`s DOM element.
12575    *
12576    * @return {Element}
12577    *         The element that gets created.
12578    */
12581   PopupButton.prototype.createEl = function createEl() {
12582     return _ClickableComponent.prototype.createEl.call(this, 'div', {
12583       className: this.buildCSSClass()
12584     });
12585   };
12587   /**
12588    * Builds the default DOM `className`.
12589    *
12590    * @return {string}
12591    *         The DOM `className` for this object.
12592    */
12595   PopupButton.prototype.buildCSSClass = function buildCSSClass() {
12596     var menuButtonClass = 'vjs-menu-button';
12598     // If the inline option is passed, we want to use different styles altogether.
12599     if (this.options_.inline === true) {
12600       menuButtonClass += '-inline';
12601     } else {
12602       menuButtonClass += '-popup';
12603     }
12605     return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
12606   };
12608   return PopupButton;
12609 }(_clickableComponent2['default']);
12611 _component2['default'].registerComponent('PopupButton', PopupButton);
12612 exports['default'] = PopupButton;
12614 },{"3":3,"5":5}],54:[function(_dereq_,module,exports){
12615 'use strict';
12617 exports.__esModule = true;
12619 var _component = _dereq_(5);
12621 var _component2 = _interopRequireDefault(_component);
12623 var _dom = _dereq_(81);
12625 var Dom = _interopRequireWildcard(_dom);
12627 var _fn = _dereq_(83);
12629 var Fn = _interopRequireWildcard(_fn);
12631 var _events = _dereq_(82);
12633 var Events = _interopRequireWildcard(_events);
12635 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12637 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12639 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12641 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12643 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12644                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file popup.js
12645                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12649  * The Popup component is used to build pop up controls.
12651  * @extends Component
12652  */
12653 var Popup = function (_Component) {
12654   _inherits(Popup, _Component);
12656   function Popup() {
12657     _classCallCheck(this, Popup);
12659     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
12660   }
12662   /**
12663    * Add a popup item to the popup
12664    *
12665    * @param {Object|string} component
12666    *        Component or component type to add
12667    *
12668    */
12669   Popup.prototype.addItem = function addItem(component) {
12670     this.addChild(component);
12671     component.on('click', Fn.bind(this, function () {
12672       this.unlockShowing();
12673     }));
12674   };
12676   /**
12677    * Create the `PopupButton`s DOM element.
12678    *
12679    * @return {Element}
12680    *         The element that gets created.
12681    */
12684   Popup.prototype.createEl = function createEl() {
12685     var contentElType = this.options_.contentElType || 'ul';
12687     this.contentEl_ = Dom.createEl(contentElType, {
12688       className: 'vjs-menu-content'
12689     });
12691     var el = _Component.prototype.createEl.call(this, 'div', {
12692       append: this.contentEl_,
12693       className: 'vjs-menu'
12694     });
12696     el.appendChild(this.contentEl_);
12698     // Prevent clicks from bubbling up. Needed for Popup Buttons,
12699     // where a click on the parent is significant
12700     Events.on(el, 'click', function (event) {
12701       event.preventDefault();
12702       event.stopImmediatePropagation();
12703     });
12705     return el;
12706   };
12708   return Popup;
12709 }(_component2['default']);
12711 _component2['default'].registerComponent('Popup', Popup);
12712 exports['default'] = Popup;
12714 },{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){
12715 'use strict';
12717 exports.__esModule = true;
12719 var _clickableComponent = _dereq_(3);
12721 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12723 var _component = _dereq_(5);
12725 var _component2 = _interopRequireDefault(_component);
12727 var _fn = _dereq_(83);
12729 var Fn = _interopRequireWildcard(_fn);
12731 var _dom = _dereq_(81);
12733 var Dom = _interopRequireWildcard(_dom);
12735 var _browser = _dereq_(78);
12737 var browser = _interopRequireWildcard(_browser);
12739 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12741 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12743 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12745 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12747 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12748                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file poster-image.js
12749                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12753  * A `ClickableComponent` that handles showing the poster image for the player.
12755  * @extends ClickableComponent
12756  */
12757 var PosterImage = function (_ClickableComponent) {
12758   _inherits(PosterImage, _ClickableComponent);
12760   /**
12761    * Create an instance of this class.
12762    *
12763    * @param {Player} player
12764    *        The `Player` that this class should attach to.
12765    *
12766    * @param {Object} [options]
12767    *        The key/value store of player options.
12768    */
12769   function PosterImage(player, options) {
12770     _classCallCheck(this, PosterImage);
12772     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12774     _this.update();
12775     player.on('posterchange', Fn.bind(_this, _this.update));
12776     return _this;
12777   }
12779   /**
12780    * Clean up and dispose of the `PosterImage`.
12781    */
12784   PosterImage.prototype.dispose = function dispose() {
12785     this.player().off('posterchange', this.update);
12786     _ClickableComponent.prototype.dispose.call(this);
12787   };
12789   /**
12790    * Create the `PosterImage`s DOM element.
12791    *
12792    * @return {Element}
12793    *         The element that gets created.
12794    */
12797   PosterImage.prototype.createEl = function createEl() {
12798     var el = Dom.createEl('div', {
12799       className: 'vjs-poster',
12801       // Don't want poster to be tabbable.
12802       tabIndex: -1
12803     });
12805     // To ensure the poster image resizes while maintaining its original aspect
12806     // ratio, use a div with `background-size` when available. For browsers that
12807     // do not support `background-size` (e.g. IE8), fall back on using a regular
12808     // img element.
12809     if (!browser.BACKGROUND_SIZE_SUPPORTED) {
12810       this.fallbackImg_ = Dom.createEl('img');
12811       el.appendChild(this.fallbackImg_);
12812     }
12814     return el;
12815   };
12817   /**
12818    * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
12819    *
12820    * @listens Player#posterchange
12821    *
12822    * @param {EventTarget~Event} [event]
12823    *        The `Player#posterchange` event that triggered this function.
12824    */
12827   PosterImage.prototype.update = function update(event) {
12828     var url = this.player().poster();
12830     this.setSrc(url);
12832     // If there's no poster source we should display:none on this component
12833     // so it's not still clickable or right-clickable
12834     if (url) {
12835       this.show();
12836     } else {
12837       this.hide();
12838     }
12839   };
12841   /**
12842    * Set the source of the `PosterImage` depending on the display method.
12843    *
12844    * @param {string} url
12845    *        The URL to the source for the `PosterImage`.
12846    */
12849   PosterImage.prototype.setSrc = function setSrc(url) {
12850     if (this.fallbackImg_) {
12851       this.fallbackImg_.src = url;
12852     } else {
12853       var backgroundImage = '';
12855       // Any falsey values should stay as an empty string, otherwise
12856       // this will throw an extra error
12857       if (url) {
12858         backgroundImage = 'url("' + url + '")';
12859       }
12861       this.el_.style.backgroundImage = backgroundImage;
12862     }
12863   };
12865   /**
12866    * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
12867    * {@link ClickableComponent#handleClick} for instances where this will be triggered.
12868    *
12869    * @listens tap
12870    * @listens click
12871    * @listens keydown
12872    *
12873    * @param {EventTarget~Event} event
12874    +        The `click`, `tap` or `keydown` event that caused this function to be called.
12875    */
12878   PosterImage.prototype.handleClick = function handleClick(event) {
12879     // We don't want a click to trigger playback when controls are disabled
12880     // but CSS should be hiding the poster to prevent that from happening
12881     if (this.player_.paused()) {
12882       this.player_.play();
12883     } else {
12884       this.player_.pause();
12885     }
12886   };
12888   return PosterImage;
12889 }(_clickableComponent2['default']);
12891 _component2['default'].registerComponent('PosterImage', PosterImage);
12892 exports['default'] = PosterImage;
12894 },{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){
12895 'use strict';
12897 exports.__esModule = true;
12898 exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
12900 var _dom = _dereq_(81);
12902 var Dom = _interopRequireWildcard(_dom);
12904 var _events = _dereq_(82);
12906 var Events = _interopRequireWildcard(_events);
12908 var _document = _dereq_(94);
12910 var _document2 = _interopRequireDefault(_document);
12912 var _window = _dereq_(95);
12914 var _window2 = _interopRequireDefault(_window);
12916 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12918 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12921  * @file setup.js - Functions for setting up a player without
12922  * user interaction based on the data-setup `attribute` of the video tag.
12924  * @module setup
12925  */
12926 var _windowLoaded = false;
12927 var videojs = void 0;
12930  * Set up any tags that have a data-setup `attribute` when the player is started.
12931  */
12932 var autoSetup = function autoSetup() {
12934   // Protect against breakage in non-browser environments.
12935   if (!Dom.isReal()) {
12936     return;
12937   }
12939   // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
12940   // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
12941   // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
12942   // var mediaEls = vids.concat(audios);
12944   // Because IE8 doesn't support calling slice on a node list, we need to loop
12945   // through each list of elements to build up a new, combined list of elements.
12946   var vids = _document2['default'].getElementsByTagName('video');
12947   var audios = _document2['default'].getElementsByTagName('audio');
12948   var mediaEls = [];
12950   if (vids && vids.length > 0) {
12951     for (var i = 0, e = vids.length; i < e; i++) {
12952       mediaEls.push(vids[i]);
12953     }
12954   }
12956   if (audios && audios.length > 0) {
12957     for (var _i = 0, _e = audios.length; _i < _e; _i++) {
12958       mediaEls.push(audios[_i]);
12959     }
12960   }
12962   // Check if any media elements exist
12963   if (mediaEls && mediaEls.length > 0) {
12965     for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
12966       var mediaEl = mediaEls[_i2];
12968       // Check if element exists, has getAttribute func.
12969       // IE seems to consider typeof el.getAttribute == 'object' instead of
12970       // 'function' like expected, at least when loading the player immediately.
12971       if (mediaEl && mediaEl.getAttribute) {
12973         // Make sure this player hasn't already been set up.
12974         if (mediaEl.player === undefined) {
12975           var options = mediaEl.getAttribute('data-setup');
12977           // Check if data-setup attr exists.
12978           // We only auto-setup if they've added the data-setup attr.
12979           if (options !== null) {
12980             // Create new video.js instance.
12981             videojs(mediaEl);
12982           }
12983         }
12985         // If getAttribute isn't defined, we need to wait for the DOM.
12986       } else {
12987         autoSetupTimeout(1);
12988         break;
12989       }
12990     }
12992     // No videos were found, so keep looping unless page is finished loading.
12993   } else if (!_windowLoaded) {
12994     autoSetupTimeout(1);
12995   }
12999  * Wait until the page is loaded before running autoSetup. This will be called in
13000  * autoSetup if `hasLoaded` returns false.
13002  * @param {number} wait
13003  *        How long to wait in ms
13005  * @param {videojs} [vjs]
13006  *        The videojs library function
13007  */
13008 function autoSetupTimeout(wait, vjs) {
13009   if (vjs) {
13010     videojs = vjs;
13011   }
13013   _window2['default'].setTimeout(autoSetup, wait);
13016 if (Dom.isReal() && _document2['default'].readyState === 'complete') {
13017   _windowLoaded = true;
13018 } else {
13019   /**
13020    * Listen for the load event on window, and set _windowLoaded to true.
13021    *
13022    * @listens load
13023    */
13024   Events.one(_window2['default'], 'load', function () {
13025     _windowLoaded = true;
13026   });
13030  * check if the document has been loaded
13031  */
13032 var hasLoaded = function hasLoaded() {
13033   return _windowLoaded;
13036 exports.autoSetup = autoSetup;
13037 exports.autoSetupTimeout = autoSetupTimeout;
13038 exports.hasLoaded = hasLoaded;
13040 },{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){
13041 'use strict';
13043 exports.__esModule = true;
13045 var _component = _dereq_(5);
13047 var _component2 = _interopRequireDefault(_component);
13049 var _dom = _dereq_(81);
13051 var Dom = _interopRequireWildcard(_dom);
13053 var _obj = _dereq_(88);
13055 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
13057 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13059 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13061 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
13063 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
13064                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file slider.js
13065                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
13069  * The base functionality for a slider. Can be vertical or horizontal.
13070  * For instance the volume bar or the seek bar on a video is a slider.
13072  * @extends Component
13073  */
13074 var Slider = function (_Component) {
13075   _inherits(Slider, _Component);
13077   /**
13078    * Create an instance of this class
13079    *
13080    * @param {Player} player
13081    *        The `Player` that this class should be attached to.
13082    *
13083    * @param {Object} [options]
13084    *        The key/value store of player options.
13085    */
13086   function Slider(player, options) {
13087     _classCallCheck(this, Slider);
13089     // Set property names to bar to match with the child Slider class is looking for
13090     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
13092     _this.bar = _this.getChild(_this.options_.barName);
13094     // Set a horizontal or vertical class on the slider depending on the slider type
13095     _this.vertical(!!_this.options_.vertical);
13097     _this.on('mousedown', _this.handleMouseDown);
13098     _this.on('touchstart', _this.handleMouseDown);
13099     _this.on('focus', _this.handleFocus);
13100     _this.on('blur', _this.handleBlur);
13101     _this.on('click', _this.handleClick);
13103     _this.on(player, 'controlsvisible', _this.update);
13104     _this.on(player, _this.playerEvent, _this.update);
13105     return _this;
13106   }
13108   /**
13109    * Create the `Button`s DOM element.
13110    *
13111    * @param {string} type
13112    *        Type of element to create.
13113    *
13114    * @param {Object} [props={}]
13115    *        List of properties in Object form.
13116    *
13117    * @param {Object} [attributes={}]
13118    *        list of attributes in Object form.
13119    *
13120    * @return {Element}
13121    *         The element that gets created.
13122    */
13125   Slider.prototype.createEl = function createEl(type) {
13126     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13127     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13129     // Add the slider element class to all sub classes
13130     props.className = props.className + ' vjs-slider';
13131     props = (0, _obj.assign)({
13132       tabIndex: 0
13133     }, props);
13135     attributes = (0, _obj.assign)({
13136       'role': 'slider',
13137       'aria-valuenow': 0,
13138       'aria-valuemin': 0,
13139       'aria-valuemax': 100,
13140       'tabIndex': 0
13141     }, attributes);
13143     return _Component.prototype.createEl.call(this, type, props, attributes);
13144   };
13146   /**
13147    * Handle `mousedown` or `touchstart` events on the `Slider`.
13148    *
13149    * @param {EventTarget~Event} event
13150    *        `mousedown` or `touchstart` event that triggered this function
13151    *
13152    * @listens mousedown
13153    * @listens touchstart
13154    * @fires Slider#slideractive
13155    */
13158   Slider.prototype.handleMouseDown = function handleMouseDown(event) {
13159     var doc = this.bar.el_.ownerDocument;
13161     event.preventDefault();
13162     Dom.blockTextSelection();
13164     this.addClass('vjs-sliding');
13165     /**
13166      * Triggered when the slider is in an active state
13167      *
13168      * @event Slider#slideractive
13169      * @type {EventTarget~Event}
13170      */
13171     this.trigger('slideractive');
13173     this.on(doc, 'mousemove', this.handleMouseMove);
13174     this.on(doc, 'mouseup', this.handleMouseUp);
13175     this.on(doc, 'touchmove', this.handleMouseMove);
13176     this.on(doc, 'touchend', this.handleMouseUp);
13178     this.handleMouseMove(event);
13179   };
13181   /**
13182    * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
13183    * The `mousemove` and `touchmove` events will only only trigger this function during
13184    * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
13185    * {@link Slider#handleMouseUp}.
13186    *
13187    * @param {EventTarget~Event} event
13188    *        `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
13189    *        this function
13190    *
13191    * @listens mousemove
13192    * @listens touchmove
13193    */
13196   Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
13198   /**
13199    * Handle `mouseup` or `touchend` events on the `Slider`.
13200    *
13201    * @param {EventTarget~Event} event
13202    *        `mouseup` or `touchend` event that triggered this function.
13203    *
13204    * @listens touchend
13205    * @listens mouseup
13206    * @fires Slider#sliderinactive
13207    */
13210   Slider.prototype.handleMouseUp = function handleMouseUp() {
13211     var doc = this.bar.el_.ownerDocument;
13213     Dom.unblockTextSelection();
13215     this.removeClass('vjs-sliding');
13216     /**
13217      * Triggered when the slider is no longer in an active state.
13218      *
13219      * @event Slider#sliderinactive
13220      * @type {EventTarget~Event}
13221      */
13222     this.trigger('sliderinactive');
13224     this.off(doc, 'mousemove', this.handleMouseMove);
13225     this.off(doc, 'mouseup', this.handleMouseUp);
13226     this.off(doc, 'touchmove', this.handleMouseMove);
13227     this.off(doc, 'touchend', this.handleMouseUp);
13229     this.update();
13230   };
13232   /**
13233    * Update the progress bar of the `Slider`.
13234    */
13237   Slider.prototype.update = function update() {
13238     // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
13239     // execution stack. The player is destroyed before then update will cause an error
13240     if (!this.el_) {
13241       return;
13242     }
13244     // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
13245     // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
13246     // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
13247     var progress = this.getPercent();
13248     var bar = this.bar;
13250     // If there's no bar...
13251     if (!bar) {
13252       return;
13253     }
13255     // Protect against no duration and other division issues
13256     if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
13257       progress = 0;
13258     }
13260     // Convert to a percentage for setting
13261     var percentage = (progress * 100).toFixed(2) + '%';
13263     // Set the new bar width or height
13264     if (this.vertical()) {
13265       bar.el().style.height = percentage;
13266     } else {
13267       bar.el().style.width = percentage;
13268     }
13269   };
13271   /**
13272    * Calculate distance for slider
13273    *
13274    * @param {EventTarget~Event} event
13275    *        The event that caused this function to run.
13276    *
13277    * @return {number}
13278    *         The current position of the Slider.
13279    *         - position.x for vertical `Slider`s
13280    *         - position.y for horizontal `Slider`s
13281    */
13284   Slider.prototype.calculateDistance = function calculateDistance(event) {
13285     var position = Dom.getPointerPosition(this.el_, event);
13287     if (this.vertical()) {
13288       return position.y;
13289     }
13290     return position.x;
13291   };
13293   /**
13294    * Handle a `focus` event on this `Slider`.
13295    *
13296    * @param {EventTarget~Event} event
13297    *        The `focus` event that caused this function to run.
13298    *
13299    * @listens focus
13300    */
13303   Slider.prototype.handleFocus = function handleFocus() {
13304     this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13305   };
13307   /**
13308    * Handle a `keydown` event on the `Slider`. Watches for left, right, up, and down
13309    * arrow keys. This function will only be called when the slider has focus. See
13310    * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
13311    *
13312    * @param {EventTarget~Event} event
13313    *        the `keydown` event that caused this function to run.
13314    *
13315    * @listens keydown
13316    */
13319   Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13320     // Left and Down Arrows
13321     if (event.which === 37 || event.which === 40) {
13322       event.preventDefault();
13323       this.stepBack();
13325       // Up and Right Arrows
13326     } else if (event.which === 38 || event.which === 39) {
13327       event.preventDefault();
13328       this.stepForward();
13329     }
13330   };
13332   /**
13333    * Handle a `blur` event on this `Slider`.
13334    *
13335    * @param {EventTarget~Event} event
13336    *        The `blur` event that caused this function to run.
13337    *
13338    * @listens blur
13339    */
13341   Slider.prototype.handleBlur = function handleBlur() {
13342     this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13343   };
13345   /**
13346    * Listener for click events on slider, used to prevent clicks
13347    *   from bubbling up to parent elements like button menus.
13348    *
13349    * @param {Object} event
13350    *        Event that caused this object to run
13351    */
13354   Slider.prototype.handleClick = function handleClick(event) {
13355     event.stopImmediatePropagation();
13356     event.preventDefault();
13357   };
13359   /**
13360    * Get/set if slider is horizontal for vertical
13361    *
13362    * @param {boolean} [bool]
13363    *        - true if slider is vertical,
13364    *        - false is horizontal
13365    *
13366    * @return {boolean|Slider}
13367    *         - true if slider is vertical, and getting
13368    *         - false is horizontal, and getting
13369    *         - a reference to this object when setting
13370    */
13373   Slider.prototype.vertical = function vertical(bool) {
13374     if (bool === undefined) {
13375       return this.vertical_ || false;
13376     }
13378     this.vertical_ = !!bool;
13380     if (this.vertical_) {
13381       this.addClass('vjs-slider-vertical');
13382     } else {
13383       this.addClass('vjs-slider-horizontal');
13384     }
13386     return this;
13387   };
13389   return Slider;
13390 }(_component2['default']);
13392 _component2['default'].registerComponent('Slider', Slider);
13393 exports['default'] = Slider;
13395 },{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){
13396 'use strict';
13398 exports.__esModule = true;
13400  * @file flash-rtmp.js
13401  * @module flash-rtmp
13402  */
13405  * Add RTMP properties to the {@link Flash} Tech.
13407  * @param {Flash} Flash
13408  *        The flash tech class.
13410  * @mixin FlashRtmpDecorator
13411  */
13412 function FlashRtmpDecorator(Flash) {
13413   Flash.streamingFormats = {
13414     'rtmp/mp4': 'MP4',
13415     'rtmp/flv': 'FLV'
13416   };
13418   /**
13419    * Join connection and stream with an ampersand.
13420    *
13421    * @param {string} connection
13422    *        The connection string.
13423    *
13424    * @param {string} stream
13425    *        The stream string.
13426    */
13427   Flash.streamFromParts = function (connection, stream) {
13428     return connection + '&' + stream;
13429   };
13431   /**
13432    * The flash parts object that contains connection and stream info.
13433    *
13434    * @typedef {Object} Flash~PartsObject
13435    *
13436    * @property {string} connection
13437    *           The connection string of a source, defaults to an empty string.
13438    *
13439    * @property {string} stream
13440    *           The stream string of the source, defaults to an empty string.
13441    */
13443   /**
13444    * Convert a source url into a stream and connection parts.
13445    *
13446    * @param {string} src
13447    *        the source url
13448    *
13449    * @return {Flash~PartsObject}
13450    *         The parts object that contains a connection and a stream
13451    */
13452   Flash.streamToParts = function (src) {
13453     var parts = {
13454       connection: '',
13455       stream: ''
13456     };
13458     if (!src) {
13459       return parts;
13460     }
13462     // Look for the normal URL separator we expect, '&'.
13463     // If found, we split the URL into two pieces around the
13464     // first '&'.
13465     var connEnd = src.search(/&(?!\w+=)/);
13466     var streamBegin = void 0;
13468     if (connEnd !== -1) {
13469       streamBegin = connEnd + 1;
13470     } else {
13471       // If there's not a '&', we use the last '/' as the delimiter.
13472       connEnd = streamBegin = src.lastIndexOf('/') + 1;
13473       if (connEnd === 0) {
13474         // really, there's not a '/'?
13475         connEnd = streamBegin = src.length;
13476       }
13477     }
13479     parts.connection = src.substring(0, connEnd);
13480     parts.stream = src.substring(streamBegin, src.length);
13482     return parts;
13483   };
13485   /**
13486    * Check if the source type is a streaming type.
13487    *
13488    * @param {string} srcType
13489    *        The mime type to check.
13490    *
13491    * @return {boolean}
13492    *          - True if the source type is a streaming type.
13493    *          - False if the source type is not a streaming type.
13494    */
13495   Flash.isStreamingType = function (srcType) {
13496     return srcType in Flash.streamingFormats;
13497   };
13499   // RTMP has four variations, any string starting
13500   // with one of these protocols should be valid
13502   /**
13503    * Regular expression used to check if the source is an rtmp source.
13504    *
13505    * @property {RegExp} Flash.RTMP_RE
13506    */
13507   Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13509   /**
13510    * Check if the source itself is a streaming type.
13511    *
13512    * @param {string} src
13513    *        The url to the source.
13514    *
13515    * @return {boolean}
13516    *          - True if the source url indicates that the source is streaming.
13517    *          - False if the shource url indicates that the source url is not streaming.
13518    */
13519   Flash.isStreamingSrc = function (src) {
13520     return Flash.RTMP_RE.test(src);
13521   };
13523   /**
13524    * A source handler for RTMP urls
13525    * @type {Object}
13526    */
13527   Flash.rtmpSourceHandler = {};
13529   /**
13530    * Check if Flash can play the given mime type.
13531    *
13532    * @param {string} type
13533    *        The mime type to check
13534    *
13535    * @return {string}
13536    *         'maybe', or '' (empty string)
13537    */
13538   Flash.rtmpSourceHandler.canPlayType = function (type) {
13539     if (Flash.isStreamingType(type)) {
13540       return 'maybe';
13541     }
13543     return '';
13544   };
13546   /**
13547    * Check if Flash can handle the source natively
13548    *
13549    * @param {Object} source
13550    *        The source object
13551    *
13552    * @param {Object} [options]
13553    *        The options passed to the tech
13554    *
13555    * @return {string}
13556    *         'maybe', or '' (empty string)
13557    */
13558   Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
13559     var can = Flash.rtmpSourceHandler.canPlayType(source.type);
13561     if (can) {
13562       return can;
13563     }
13565     if (Flash.isStreamingSrc(source.src)) {
13566       return 'maybe';
13567     }
13569     return '';
13570   };
13572   /**
13573    * Pass the source to the flash object.
13574    *
13575    * @param {Object} source
13576    *        The source object
13577    *
13578    * @param {Flash} tech
13579    *        The instance of the Flash tech
13580    *
13581    * @param {Object} [options]
13582    *        The options to pass to the source
13583    */
13584   Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
13585     var srcParts = Flash.streamToParts(source.src);
13587     tech.setRtmpConnection(srcParts.connection);
13588     tech.setRtmpStream(srcParts.stream);
13589   };
13591   // Register the native source handler
13592   Flash.registerSourceHandler(Flash.rtmpSourceHandler);
13594   return Flash;
13597 exports['default'] = FlashRtmpDecorator;
13599 },{}],59:[function(_dereq_,module,exports){
13600 'use strict';
13602 exports.__esModule = true;
13604 var _tech = _dereq_(62);
13606 var _tech2 = _interopRequireDefault(_tech);
13608 var _dom = _dereq_(81);
13610 var Dom = _interopRequireWildcard(_dom);
13612 var _url = _dereq_(92);
13614 var Url = _interopRequireWildcard(_url);
13616 var _timeRanges = _dereq_(90);
13618 var _flashRtmp = _dereq_(58);
13620 var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
13622 var _component = _dereq_(5);
13624 var _component2 = _interopRequireDefault(_component);
13626 var _window = _dereq_(95);
13628 var _window2 = _interopRequireDefault(_window);
13630 var _obj = _dereq_(88);
13632 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
13634 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13636 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13638 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
13640 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
13641                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file flash.js
13642                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
13643                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * https://github.com/zencoder/video-js-swf
13644                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * Not using setupTriggers. Using global onEvent func to distribute events
13645                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
13647 var navigator = _window2['default'].navigator;
13650  * Flash Media Controller - Wrapper for Flash Media API
13652  * @mixes FlashRtmpDecorator
13653  * @mixes Tech~SouceHandlerAdditions
13654  * @extends Tech
13655  */
13657 var Flash = function (_Tech) {
13658   _inherits(Flash, _Tech);
13660   /**
13661    * Create an instance of this Tech.
13662    *
13663    * @param {Object} [options]
13664    *        The key/value store of player options.
13665    *
13666    * @param {Component~ReadyCallback} ready
13667    *        Callback function to call when the `Flash` Tech is ready.
13668    */
13669   function Flash(options, ready) {
13670     _classCallCheck(this, Flash);
13672     // Set the source when ready
13673     var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
13675     if (options.source) {
13676       _this.ready(function () {
13677         this.setSource(options.source);
13678       }, true);
13679     }
13681     // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
13682     // This allows resetting the playhead when we catch the reload
13683     if (options.startTime) {
13684       _this.ready(function () {
13685         this.load();
13686         this.play();
13687         this.currentTime(options.startTime);
13688       }, true);
13689     }
13691     // Add global window functions that the swf expects
13692     // A 4.x workflow we weren't able to solve for in 5.0
13693     // because of the need to hard code these functions
13694     // into the swf for security reasons
13695     _window2['default'].videojs = _window2['default'].videojs || {};
13696     _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {};
13697     _window2['default'].videojs.Flash.onReady = Flash.onReady;
13698     _window2['default'].videojs.Flash.onEvent = Flash.onEvent;
13699     _window2['default'].videojs.Flash.onError = Flash.onError;
13701     _this.on('seeked', function () {
13702       this.lastSeekTarget_ = undefined;
13703     });
13705     return _this;
13706   }
13708   /**
13709    * Create the `Flash` Tech's DOM element.
13710    *
13711    * @return {Element}
13712    *         The element that gets created.
13713    */
13716   Flash.prototype.createEl = function createEl() {
13717     var options = this.options_;
13719     // If video.js is hosted locally you should also set the location
13720     // for the hosted swf, which should be relative to the page (not video.js)
13721     // Otherwise this adds a CDN url.
13722     // The CDN also auto-adds a swf URL for that specific version.
13723     if (!options.swf) {
13724       var ver = '5.1.0';
13726       options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf';
13727     }
13729     // Generate ID for swf object
13730     var objId = options.techId;
13732     // Merge default flashvars with ones passed in to init
13733     var flashVars = (0, _obj.assign)({
13735       // SWF Callback Functions
13736       readyFunction: 'videojs.Flash.onReady',
13737       eventProxyFunction: 'videojs.Flash.onEvent',
13738       errorEventProxyFunction: 'videojs.Flash.onError',
13740       // Player Settings
13741       autoplay: options.autoplay,
13742       preload: options.preload,
13743       loop: options.loop,
13744       muted: options.muted
13746     }, options.flashVars);
13748     // Merge default parames with ones passed in
13749     var params = (0, _obj.assign)({
13750       // Opaque is needed to overlay controls, but can affect playback performance
13751       wmode: 'opaque',
13752       // Using bgcolor prevents a white flash when the object is loading
13753       bgcolor: '#000000'
13754     }, options.params);
13756     // Merge default attributes with ones passed in
13757     var attributes = (0, _obj.assign)({
13758       // Both ID and Name needed or swf to identify itself
13759       id: objId,
13760       name: objId,
13761       'class': 'vjs-tech'
13762     }, options.attributes);
13764     this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
13765     this.el_.tech = this;
13767     return this.el_;
13768   };
13770   /**
13771    * Called by {@link Player#play} to play using the `Flash` `Tech`.
13772    */
13775   Flash.prototype.play = function play() {
13776     if (this.ended()) {
13777       this.setCurrentTime(0);
13778     }
13779     this.el_.vjs_play();
13780   };
13782   /**
13783    * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
13784    */
13787   Flash.prototype.pause = function pause() {
13788     this.el_.vjs_pause();
13789   };
13791   /**
13792    * A getter/setter for the `Flash` Tech's source object.
13793    * > Note: Please use {@link Flash#setSource}
13794    *
13795    * @param {Tech~SourceObject} [src]
13796    *        The source object you want to set on the `Flash` techs.
13797    *
13798    * @return {Tech~SourceObject|undefined}
13799    *         - The current source object when a source is not passed in.
13800    *         - undefined when setting
13801    *
13802    * @deprecated Since version 5.
13803    */
13806   Flash.prototype.src = function src(_src) {
13807     if (_src === undefined) {
13808       return this.currentSrc();
13809     }
13811     // Setting src through `src` not `setSrc` will be deprecated
13812     return this.setSrc(_src);
13813   };
13815   /**
13816    * A getter/setter for the `Flash` Tech's source object.
13817    *
13818    * @param {Tech~SourceObject} [src]
13819    *        The source object you want to set on the `Flash` techs.
13820    *
13821    * @return {Tech~SourceObject|undefined}
13822    *         - The current source object when a source is not passed in.
13823    *         - undefined when setting
13824    */
13827   Flash.prototype.setSrc = function setSrc(src) {
13828     var _this2 = this;
13830     // Make sure source URL is absolute.
13831     src = Url.getAbsoluteURL(src);
13832     this.el_.vjs_src(src);
13834     // Currently the SWF doesn't autoplay if you load a source later.
13835     // e.g. Load player w/ no source, wait 2s, set src.
13836     if (this.autoplay()) {
13837       this.setTimeout(function () {
13838         return _this2.play();
13839       }, 0);
13840     }
13841   };
13843   /**
13844    * Indicates whether the media is currently seeking to a new position or not.
13845    *
13846    * @return {boolean}
13847    *         - True if seeking to a new position
13848    *         - False otherwise
13849    */
13852   Flash.prototype.seeking = function seeking() {
13853     return this.lastSeekTarget_ !== undefined;
13854   };
13856   /**
13857    * Returns the current time in seconds that the media is at in playback.
13858    *
13859    * @param {number} time
13860    *        Current playtime of the media in seconds.
13861    */
13864   Flash.prototype.setCurrentTime = function setCurrentTime(time) {
13865     var seekable = this.seekable();
13867     if (seekable.length) {
13868       // clamp to the current seekable range
13869       time = time > seekable.start(0) ? time : seekable.start(0);
13870       time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
13872       this.lastSeekTarget_ = time;
13873       this.trigger('seeking');
13874       this.el_.vjs_setProperty('currentTime', time);
13875       _Tech.prototype.setCurrentTime.call(this);
13876     }
13877   };
13879   /**
13880    * Get the current playback time in seconds
13881    *
13882    * @return {number}
13883    *         The current time of playback in seconds.
13884    */
13887   Flash.prototype.currentTime = function currentTime() {
13888     // when seeking make the reported time keep up with the requested time
13889     // by reading the time we're seeking to
13890     if (this.seeking()) {
13891       return this.lastSeekTarget_ || 0;
13892     }
13893     return this.el_.vjs_getProperty('currentTime');
13894   };
13896   /**
13897    * Get the current source
13898    *
13899    * @method currentSrc
13900    * @return {Tech~SourceObject}
13901    *         The current source
13902    */
13905   Flash.prototype.currentSrc = function currentSrc() {
13906     if (this.currentSource_) {
13907       return this.currentSource_.src;
13908     }
13909     return this.el_.vjs_getProperty('currentSrc');
13910   };
13912   /**
13913    * Get the total duration of the current media.
13914    *
13915    * @return {number}
13916    8          The total duration of the current media.
13917    */
13920   Flash.prototype.duration = function duration() {
13921     if (this.readyState() === 0) {
13922       return NaN;
13923     }
13924     var duration = this.el_.vjs_getProperty('duration');
13926     return duration >= 0 ? duration : Infinity;
13927   };
13929   /**
13930    * Load media into Tech.
13931    */
13934   Flash.prototype.load = function load() {
13935     this.el_.vjs_load();
13936   };
13938   /**
13939    * Get the poster image that was set on the tech.
13940    */
13943   Flash.prototype.poster = function poster() {
13944     this.el_.vjs_getProperty('poster');
13945   };
13947   /**
13948    * Poster images are not handled by the Flash tech so make this is a no-op.
13949    */
13952   Flash.prototype.setPoster = function setPoster() {};
13954   /**
13955    * Determine the time ranges that can be seeked to in the media.
13956    *
13957    * @return {TimeRange}
13958    *         Returns the time ranges that can be seeked to.
13959    */
13962   Flash.prototype.seekable = function seekable() {
13963     var duration = this.duration();
13965     if (duration === 0) {
13966       return (0, _timeRanges.createTimeRange)();
13967     }
13968     return (0, _timeRanges.createTimeRange)(0, duration);
13969   };
13971   /**
13972    * Get and create a `TimeRange` object for buffering.
13973    *
13974    * @return {TimeRange}
13975    *         The time range object that was created.
13976    */
13979   Flash.prototype.buffered = function buffered() {
13980     var ranges = this.el_.vjs_getProperty('buffered');
13982     if (ranges.length === 0) {
13983       return (0, _timeRanges.createTimeRange)();
13984     }
13985     return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]);
13986   };
13988   /**
13989    * Get fullscreen support -
13990    *
13991    * Flash does not allow fullscreen through javascript
13992    * so this always returns false.
13993    *
13994    * @return {boolean}
13995    *         The Flash tech does not support fullscreen, so it will always return false.
13996    */
13999   Flash.prototype.supportsFullScreen = function supportsFullScreen() {
14000     // Flash does not allow fullscreen through javascript
14001     return false;
14002   };
14004   /**
14005    * Flash does not allow fullscreen through javascript
14006    * so this always returns false.
14007    *
14008    * @return {boolean}
14009    *         The Flash tech does not support fullscreen, so it will always return false.
14010    */
14013   Flash.prototype.enterFullScreen = function enterFullScreen() {
14014     return false;
14015   };
14017   return Flash;
14018 }(_tech2['default']);
14020 // Create setters and getters for attributes
14023 var _api = Flash.prototype;
14024 var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
14025 var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
14027 function _createSetter(attr) {
14028   var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
14030   _api['set' + attrUpper] = function (val) {
14031     return this.el_.vjs_setProperty(attr, val);
14032   };
14035 function _createGetter(attr) {
14036   _api[attr] = function () {
14037     return this.el_.vjs_getProperty(attr);
14038   };
14041 // Create getter and setters for all read/write attributes
14042 for (var i = 0; i < _readWrite.length; i++) {
14043   _createGetter(_readWrite[i]);
14044   _createSetter(_readWrite[i]);
14047 // Create getters for read-only attributes
14048 for (var _i = 0; _i < _readOnly.length; _i++) {
14049   _createGetter(_readOnly[_i]);
14052 /** ------------------------------ Getters ------------------------------ **/
14054  * Get the value of `rtmpConnection` from the swf.
14056  * @method Flash#rtmpConnection
14057  * @return {string}
14058  *         The current value of `rtmpConnection` on the swf.
14059  */
14062  * Get the value of `rtmpStream` from the swf.
14064  * @method Flash#rtmpStream
14065  * @return {string}
14066  *         The current value of `rtmpStream` on the swf.
14067  */
14070  * Get the value of `preload` from the swf. `preload` indicates
14071  * what should download before the media is interacted with. It can have the following
14072  * values:
14073  * - none: nothing should be downloaded
14074  * - metadata: poster and the first few frames of the media may be downloaded to get
14075  *   media dimensions and other metadata
14076  * - auto: allow the media and metadata for the media to be downloaded before
14077  *    interaction
14079  * @method Flash#preload
14080  * @return {string}
14081  *         The value of `preload` from the swf. Will be 'none', 'metadata',
14082  *         or 'auto'.
14083  */
14086  * Get the value of `defaultPlaybackRate` from the swf.
14088  * @method Flash#defaultPlaybackRate
14089  * @return {number}
14090  *         The current value of `defaultPlaybackRate` on the swf.
14091  */
14094  * Get the value of `playbackRate` from the swf. `playbackRate` indicates
14095  * the rate at which the media is currently playing back. Examples:
14096  *   - if playbackRate is set to 2, media will play twice as fast.
14097  *   - if playbackRate is set to 0.5, media will play half as fast.
14099  * @method Flash#playbackRate
14100  * @return {number}
14101  *         The value of `playbackRate` from the swf. A number indicating
14102  *         the current playback speed of the media, where 1 is normal speed.
14103  */
14106  * Get the value of `autoplay` from the swf. `autoplay` indicates
14107  * that the media should start to play as soon as the page is ready.
14109  * @method Flash#autoplay
14110  * @return {boolean}
14111  *         - The value of `autoplay` from the swf.
14112  *         - True indicates that the media ashould start as soon as the page loads.
14113  *         - False indicates that the media should not start as soon as the page loads.
14114  */
14117  * Get the value of `loop` from the swf. `loop` indicates
14118  * that the media should return to the start of the media and continue playing once
14119  * it reaches the end.
14121  * @method Flash#loop
14122  * @return {boolean}
14123  *         - The value of `loop` from the swf.
14124  *         - True indicates that playback should seek back to start once
14125  *           the end of a media is reached.
14126  *         - False indicates that playback should not loop back to the start when the
14127  *           end of the media is reached.
14128  */
14131  * Get the value of `mediaGroup` from the swf.
14133  * @method Flash#mediaGroup
14134  * @return {string}
14135  *         The current value of `mediaGroup` on the swf.
14136  */
14139  * Get the value of `controller` from the swf.
14141  * @method Flash#controller
14142  * @return {string}
14143  *         The current value of `controller` on the swf.
14144  */
14147  * Get the value of `controls` from the swf. `controls` indicates
14148  * whether the native flash controls should be shown or hidden.
14150  * @method Flash#controls
14151  * @return {boolean}
14152  *         - The value of `controls` from the swf.
14153  *         - True indicates that native controls should be showing.
14154  *         - False indicates that native controls should be hidden.
14155  */
14158  * Get the value of the `volume` from the swf. `volume` indicates the current
14159  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14160  * so on.
14162  * @method Flash#volume
14163  * @return {number}
14164  *         The volume percent as a decimal. Value will be between 0-1.
14165  */
14168  * Get the value of the `muted` from the swf. `muted` indicates the current
14169  * audio level should be silent.
14171  * @method Flash#muted
14172  * @return {boolean}
14173  *         - True if the audio should be set to silent
14174  *         - False otherwise
14175  */
14178  * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
14179  * whether the media should start muted or not. Only changes the default state of the
14180  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14181  * current state.
14183  * @method Flash#defaultMuted
14184  * @return {boolean}
14185  *         - The value of `defaultMuted` from the swf.
14186  *         - True indicates that the media should start muted.
14187  *         - False indicates that the media should not start muted.
14188  */
14191  * Get the value of `networkState` from the swf. `networkState` indicates
14192  * the current network state. It returns an enumeration from the following list:
14193  * - 0: NETWORK_EMPTY
14194  * - 1: NEWORK_IDLE
14195  * - 2: NETWORK_LOADING
14196  * - 3: NETWORK_NO_SOURCE
14198  * @method Flash#networkState
14199  * @return {number}
14200  *         The value of `networkState` from the swf. This will be a number
14201  *         from the list in the description.
14202  */
14205  * Get the value of `readyState` from the swf. `readyState` indicates
14206  * the current state of the media element. It returns an enumeration from the
14207  * following list:
14208  * - 0: HAVE_NOTHING
14209  * - 1: HAVE_METADATA
14210  * - 2: HAVE_CURRENT_DATA
14211  * - 3: HAVE_FUTURE_DATA
14212  * - 4: HAVE_ENOUGH_DATA
14214  * @method Flash#readyState
14215  * @return {number}
14216  *         The value of `readyState` from the swf. This will be a number
14217  *         from the list in the description.
14218  */
14221  * Get the value of `readyState` from the swf. `readyState` indicates
14222  * the current state of the media element. It returns an enumeration from the
14223  * following list:
14224  * - 0: HAVE_NOTHING
14225  * - 1: HAVE_METADATA
14226  * - 2: HAVE_CURRENT_DATA
14227  * - 3: HAVE_FUTURE_DATA
14228  * - 4: HAVE_ENOUGH_DATA
14230  * @method Flash#readyState
14231  * @return {number}
14232  *         The value of `readyState` from the swf. This will be a number
14233  *         from the list in the description.
14234  */
14237  * Get the value of `initialTime` from the swf.
14239  * @method Flash#initialTime
14240  * @return {number}
14241  *         The `initialTime` proprety on the swf.
14242  */
14245  * Get the value of `startOffsetTime` from the swf.
14247  * @method Flash#startOffsetTime
14248  * @return {number}
14249  *         The `startOffsetTime` proprety on the swf.
14250  */
14253  * Get the value of `paused` from the swf. `paused` indicates whether the swf
14254  * is current paused or not.
14256  * @method Flash#paused
14257  * @return {boolean}
14258  *         The value of `paused` from the swf.
14259  */
14262  * Get the value of `ended` from the swf. `ended` indicates whether
14263  * the media has reached the end or not.
14265  * @method Flash#ended
14266  * @return {boolean}
14267  *         - True indicates that the media has ended.
14268  *         - False indicates that the media has not ended.
14270  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
14271  */
14274  * Get the value of `videoWidth` from the swf. `videoWidth` indicates
14275  * the current width of the media in css pixels.
14277  * @method Flash#videoWidth
14278  * @return {number}
14279  *         The value of `videoWidth` from the swf. This will be a number
14280  *         in css pixels.
14281  */
14284  * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
14285  * the current height of the media in css pixels.
14287  * @method Flassh.prototype.videoHeight
14288  * @return {number}
14289  *         The value of `videoHeight` from the swf. This will be a number
14290  *         in css pixels.
14291  */
14292 /** ------------------------------ Setters ------------------------------ **/
14295  * Set the value of `rtmpConnection` on the swf.
14297  * @method Flash#setRtmpConnection
14298  * @param {string} rtmpConnection
14299  *        New value to set the `rtmpConnection` property to.
14300  */
14303  * Set the value of `rtmpStream` on the swf.
14305  * @method Flash#setRtmpStream
14306  * @param {string} rtmpStream
14307  *        New value to set the `rtmpStream` property to.
14308  */
14311  * Set the value of `preload` on the swf. `preload` indicates
14312  * what should download before the media is interacted with. It can have the following
14313  * values:
14314  * - none: nothing should be downloaded
14315  * - metadata: poster and the first few frames of the media may be downloaded to get
14316  *   media dimensions and other metadata
14317  * - auto: allow the media and metadata for the media to be downloaded before
14318  *    interaction
14320  * @method Flash#setPreload
14321  * @param {string} preload
14322  *        The value of `preload` to set on the swf. Should be 'none', 'metadata',
14323  *        or 'auto'.
14324  */
14327  * Set the value of `defaultPlaybackRate` on the swf.
14329  * @method Flash#setDefaultPlaybackRate
14330  * @param {number} defaultPlaybackRate
14331  *        New value to set the `defaultPlaybackRate` property to.
14332  */
14335  * Set the value of `playbackRate` on the swf. `playbackRate` indicates
14336  * the rate at which the media is currently playing back. Examples:
14337  *   - if playbackRate is set to 2, media will play twice as fast.
14338  *   - if playbackRate is set to 0.5, media will play half as fast.
14340  * @method Flash#setPlaybackRate
14341  * @param {number} playbackRate
14342  *        New value of `playbackRate` on the swf. A number indicating
14343  *        the current playback speed of the media, where 1 is normal speed.
14344  */
14347  * Set the value of `autoplay` on the swf. `autoplay` indicates
14348  * that the media should start to play as soon as the page is ready.
14350  * @method Flash#setAutoplay
14351  * @param {boolean} autoplay
14352  *        - The value of `autoplay` from the swf.
14353  *        - True indicates that the media ashould start as soon as the page loads.
14354  *        - False indicates that the media should not start as soon as the page loads.
14355  */
14358  * Set the value of `loop` on the swf. `loop` indicates
14359  * that the media should return to the start of the media and continue playing once
14360  * it reaches the end.
14362  * @method Flash#setLoop
14363  * @param {boolean} loop
14364  *        - True indicates that playback should seek back to start once
14365  *          the end of a media is reached.
14366  *        - False indicates that playback should not loop back to the start when the
14367  *          end of the media is reached.
14368  */
14371  * Set the value of `mediaGroup` on the swf.
14373  * @method Flash#setMediaGroup
14374  * @param {string} mediaGroup
14375  *        New value of `mediaGroup` to set on the swf.
14376  */
14379  * Set the value of `controller` on the swf.
14381  * @method Flash#setController
14382  * @param {string} controller
14383  *        New value the current value of `controller` on the swf.
14384  */
14387  * Get the value of `controls` from the swf. `controls` indicates
14388  * whether the native flash controls should be shown or hidden.
14390  * @method Flash#controls
14391  * @return {boolean}
14392  *         - The value of `controls` from the swf.
14393  *         - True indicates that native controls should be showing.
14394  *         - False indicates that native controls should be hidden.
14395  */
14398  * Set the value of the `volume` on the swf. `volume` indicates the current
14399  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14400  * so on.
14402  * @method Flash#setVolume
14403  * @param {number} percentAsDecimal
14404  *         The volume percent as a decimal. Value will be between 0-1.
14405  */
14408  * Set the value of the `muted` on the swf. `muted` indicates that the current
14409  * audio level should be silent.
14411  * @method Flash#setMuted
14412  * @param {boolean} muted
14413  *         - True if the audio should be set to silent
14414  *         - False otherwise
14415  */
14418  * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
14419  * whether the media should start muted or not. Only changes the default state of the
14420  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14421  * current state.
14423  * @method Flash#setDefaultMuted
14424  * @param {boolean} defaultMuted
14425  *         - True indicates that the media should start muted.
14426  *         - False indicates that the media should not start muted.
14427  */
14429 /* Flash Support Testing -------------------------------------------------------- */
14432  * Check if the Flash tech is currently supported.
14434  * @return {boolean}
14435  *          - True if the flash tech is supported.
14436  *          - False otherwise.
14437  */
14438 Flash.isSupported = function () {
14439   return Flash.version()[0] >= 10;
14440   // return swfobject.hasFlashPlayerVersion('10');
14443 // Add Source Handler pattern functions to this tech
14444 _tech2['default'].withSourceHandlers(Flash);
14447  * Native source handler for flash,  simply passes the source to the swf element.
14449  * @property {Tech~SourceObject} source
14450  *           The source object
14452  * @property {Flash} tech
14453  *           The instance of the Flash tech
14454  */
14455 Flash.nativeSourceHandler = {};
14458  * Check if the Flash can play the given mime type.
14460  * @param {string} type
14461  *        The mimetype to check
14463  * @return {string}
14464  *         'maybe', or '' (empty string)
14465  */
14466 Flash.nativeSourceHandler.canPlayType = function (type) {
14467   if (type in Flash.formats) {
14468     return 'maybe';
14469   }
14471   return '';
14475  * Check if the media element can handle a source natively.
14477  * @param {Tech~SourceObject} source
14478  *         The source object
14480  * @param {Object} [options]
14481  *         Options to be passed to the tech.
14483  * @return {string}
14484  *         'maybe', or '' (empty string).
14485  */
14486 Flash.nativeSourceHandler.canHandleSource = function (source, options) {
14487   var type = void 0;
14489   function guessMimeType(src) {
14490     var ext = Url.getFileExtension(src);
14492     if (ext) {
14493       return 'video/' + ext;
14494     }
14495     return '';
14496   }
14498   if (!source.type) {
14499     type = guessMimeType(source.src);
14500   } else {
14501     // Strip code information from the type because we don't get that specific
14502     type = source.type.replace(/;.*/, '').toLowerCase();
14503   }
14505   return Flash.nativeSourceHandler.canPlayType(type);
14509  * Pass the source to the swf.
14511  * @param {Tech~SourceObject} source
14512  *        The source object
14514  * @param {Flash} tech
14515  *        The instance of the Flash tech
14517  * @param {Object} [options]
14518  *        The options to pass to the source
14519  */
14520 Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
14521   tech.setSrc(source.src);
14525  * noop for native source handler dispose, as cleanup will happen automatically.
14526  */
14527 Flash.nativeSourceHandler.dispose = function () {};
14529 // Register the native source handler
14530 Flash.registerSourceHandler(Flash.nativeSourceHandler);
14533  * Flash supported mime types.
14535  * @constant {Object}
14536  */
14537 Flash.formats = {
14538   'video/flv': 'FLV',
14539   'video/x-flv': 'FLV',
14540   'video/mp4': 'MP4',
14541   'video/m4v': 'MP4'
14545  * Called when the the swf is "ready", and makes sure that the swf is really
14546  * ready using {@link Flash#checkReady}
14547  */
14548 Flash.onReady = function (currSwf) {
14549   var el = Dom.getEl(currSwf);
14550   var tech = el && el.tech;
14552   // if there is no el then the tech has been disposed
14553   // and the tech element was removed from the player div
14554   if (tech && tech.el()) {
14555     // check that the flash object is really ready
14556     Flash.checkReady(tech);
14557   }
14561  * The SWF isn't always ready when it says it is. Sometimes the API functions still
14562  * need to be added to the object. If it's not ready, we set a timeout to check again
14563  * shortly.
14565  * @param {Flash} tech
14566  *        The instance of the flash tech to check.
14567  */
14568 Flash.checkReady = function (tech) {
14569   // stop worrying if the tech has been disposed
14570   if (!tech.el()) {
14571     return;
14572   }
14574   // check if API property exists
14575   if (tech.el().vjs_getProperty) {
14576     // tell tech it's ready
14577     tech.triggerReady();
14578   } else {
14579     // wait longer
14580     this.setTimeout(function () {
14581       Flash.checkReady(tech);
14582     }, 50);
14583   }
14587  * Trigger events from the swf on the Flash Tech.
14589  * @param {number} swfID
14590  *        The id of the swf that had the event
14592  * @param {string} eventName
14593  *        The name of the event to trigger
14594  */
14595 Flash.onEvent = function (swfID, eventName) {
14596   var tech = Dom.getEl(swfID).tech;
14597   var args = Array.prototype.slice.call(arguments, 2);
14599   // dispatch Flash events asynchronously for two reasons:
14600   // - Flash swallows any exceptions generated by javascript it
14601   //   invokes
14602   // - Flash is suspended until the javascript returns which may cause
14603   //   playback performance issues
14604   tech.setTimeout(function () {
14605     tech.trigger(eventName, args);
14606   }, 1);
14610  * Log errors from the swf on the Flash tech.
14612  * @param {number} swfID
14613  *        The id of the swf that had an error.
14615  * @param {string} The error string
14616  *        The error to set on the Flash Tech.
14618  * @return {MediaError|undefined}
14619  *          - Returns a MediaError when err is 'srcnotfound'
14620  *          - Returns undefined otherwise.
14621  */
14622 Flash.onError = function (swfID, err) {
14623   var tech = Dom.getEl(swfID).tech;
14625   // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
14626   if (err === 'srcnotfound') {
14627     return tech.error(4);
14628   }
14630   // trigger a custom error
14631   tech.error('FLASH: ' + err);
14635  * Get the current version of Flash that is in use on the page.
14637  * @return {Array}
14638  *          an array of versions that are available.
14639  */
14640 Flash.version = function () {
14641   var version = '0,0,0';
14643   // IE
14644   try {
14645     version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14647     // other browsers
14648   } catch (e) {
14649     try {
14650       if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
14651         version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14652       }
14653     } catch (err) {
14654       // satisfy linter
14655     }
14656   }
14657   return version.split(',');
14661  * Only use for non-iframe embeds.
14663  * @param {Object} swf
14664  *        The videojs-swf object.
14666  * @param {Object} flashVars
14667  *        Names and values to use as flash option variables.
14669  * @param {Object} params
14670  *        Style parameters to set on the object.
14672  * @param {Object} attributes
14673  *        Attributes to set on the element.
14675  * @return {Element}
14676  *          The embedded Flash DOM element.
14677  */
14678 Flash.embed = function (swf, flashVars, params, attributes) {
14679   var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
14681   // Get element by embedding code and retrieving created element
14682   var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
14684   return obj;
14688  * Only use for non-iframe embeds.
14690  * @param {Object} swf
14691  *        The videojs-swf object.
14693  * @param {Object} flashVars
14694  *        Names and values to use as flash option variables.
14696  * @param {Object} params
14697  *        Style parameters to set on the object.
14699  * @param {Object} attributes
14700  *        Attributes to set on the element.
14702  * @return {Element}
14703  *          The embedded Flash DOM element.
14704  */
14705 Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
14706   var objTag = '<object type="application/x-shockwave-flash" ';
14707   var flashVarsString = '';
14708   var paramsString = '';
14709   var attrsString = '';
14711   // Convert flash vars to string
14712   if (flashVars) {
14713     Object.getOwnPropertyNames(flashVars).forEach(function (key) {
14714       flashVarsString += key + '=' + flashVars[key] + '&amp;';
14715     });
14716   }
14718   // Add swf, flashVars, and other default params
14719   params = (0, _obj.assign)({
14720     movie: swf,
14721     flashvars: flashVarsString,
14722     // Required to talk to swf
14723     allowScriptAccess: 'always',
14724     // All should be default, but having security issues.
14725     allowNetworking: 'all'
14726   }, params);
14728   // Create param tags string
14729   Object.getOwnPropertyNames(params).forEach(function (key) {
14730     paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
14731   });
14733   attributes = (0, _obj.assign)({
14734     // Add swf to attributes (need both for IE and Others to work)
14735     data: swf,
14737     // Default to 100% width/height
14738     width: '100%',
14739     height: '100%'
14741   }, attributes);
14743   // Create Attributes string
14744   Object.getOwnPropertyNames(attributes).forEach(function (key) {
14745     attrsString += key + '="' + attributes[key] + '" ';
14746   });
14748   return '' + objTag + attrsString + '>' + paramsString + '</object>';
14751 // Run Flash through the RTMP decorator
14752 (0, _flashRtmp2['default'])(Flash);
14754 _component2['default'].registerComponent('Flash', Flash);
14755 _tech2['default'].registerTech('Flash', Flash);
14756 exports['default'] = Flash;
14758 },{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){
14759 'use strict';
14761 exports.__esModule = true;
14763 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
14765 var _templateObject = _taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n            This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n            This may prevent text tracks from loading.']);
14767 var _tech = _dereq_(62);
14769 var _tech2 = _interopRequireDefault(_tech);
14771 var _component = _dereq_(5);
14773 var _component2 = _interopRequireDefault(_component);
14775 var _dom = _dereq_(81);
14777 var Dom = _interopRequireWildcard(_dom);
14779 var _url = _dereq_(92);
14781 var Url = _interopRequireWildcard(_url);
14783 var _fn = _dereq_(83);
14785 var Fn = _interopRequireWildcard(_fn);
14787 var _log = _dereq_(86);
14789 var _log2 = _interopRequireDefault(_log);
14791 var _tsml = _dereq_(98);
14793 var _tsml2 = _interopRequireDefault(_tsml);
14795 var _browser = _dereq_(78);
14797 var browser = _interopRequireWildcard(_browser);
14799 var _document = _dereq_(94);
14801 var _document2 = _interopRequireDefault(_document);
14803 var _window = _dereq_(95);
14805 var _window2 = _interopRequireDefault(_window);
14807 var _obj = _dereq_(88);
14809 var _mergeOptions = _dereq_(87);
14811 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
14813 var _toTitleCase = _dereq_(91);
14815 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
14817 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
14819 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14821 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
14823 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
14825 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
14827 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
14828                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file html5.js
14829                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
14833  * HTML5 Media Controller - Wrapper for HTML5 Media API
14835  * @mixes Tech~SouceHandlerAdditions
14836  * @extends Tech
14837  */
14838 var Html5 = function (_Tech) {
14839   _inherits(Html5, _Tech);
14841   /**
14842    * Create an instance of this Tech.
14843    *
14844    * @param {Object} [options]
14845    *        The key/value store of player options.
14846    *
14847    * @param {Component~ReadyCallback} ready
14848    *        Callback function to call when the `HTML5` Tech is ready.
14849    */
14850   function Html5(options, ready) {
14851     _classCallCheck(this, Html5);
14853     var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
14855     var source = options.source;
14856     var crossoriginTracks = false;
14858     // Set the source if one is provided
14859     // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
14860     // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
14861     // anyway so the error gets fired.
14862     if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
14863       _this.setSource(source);
14864     } else {
14865       _this.handleLateInit_(_this.el_);
14866     }
14868     if (_this.el_.hasChildNodes()) {
14870       var nodes = _this.el_.childNodes;
14871       var nodesLength = nodes.length;
14872       var removeNodes = [];
14874       while (nodesLength--) {
14875         var node = nodes[nodesLength];
14876         var nodeName = node.nodeName.toLowerCase();
14878         if (nodeName === 'track') {
14879           if (!_this.featuresNativeTextTracks) {
14880             // Empty video tag tracks so the built-in player doesn't use them also.
14881             // This may not be fast enough to stop HTML5 browsers from reading the tags
14882             // so we'll need to turn off any default tracks if we're manually doing
14883             // captions and subtitles. videoElement.textTracks
14884             removeNodes.push(node);
14885           } else {
14886             // store HTMLTrackElement and TextTrack to remote list
14887             _this.remoteTextTrackEls().addTrackElement_(node);
14888             _this.remoteTextTracks().addTrack_(node.track);
14889             if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
14890               crossoriginTracks = true;
14891             }
14892           }
14893         }
14894       }
14896       for (var i = 0; i < removeNodes.length; i++) {
14897         _this.el_.removeChild(removeNodes[i]);
14898       }
14899     }
14901     // TODO: add text tracks into this list
14902     var trackTypes = ['audio', 'video'];
14904     // ProxyNative Video/Audio Track
14905     trackTypes.forEach(function (type) {
14906       var elTracks = _this.el()[type + 'Tracks'];
14907       var techTracks = _this[type + 'Tracks']();
14908       var capitalType = (0, _toTitleCase2['default'])(type);
14910       if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
14911         return;
14912       }
14914       _this['handle' + capitalType + 'TrackChange_'] = function (e) {
14915         techTracks.trigger({
14916           type: 'change',
14917           target: techTracks,
14918           currentTarget: techTracks,
14919           srcElement: techTracks
14920         });
14921       };
14923       _this['handle' + capitalType + 'TrackAdd_'] = function (e) {
14924         return techTracks.addTrack(e.track);
14925       };
14926       _this['handle' + capitalType + 'TrackRemove_'] = function (e) {
14927         return techTracks.removeTrack(e.track);
14928       };
14930       elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']);
14931       elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']);
14932       elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']);
14933       _this['removeOld' + capitalType + 'Tracks_'] = function (e) {
14934         return _this.removeOldTracks_(techTracks, elTracks);
14935       };
14937       // Remove (native) tracks that are not used anymore
14938       _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']);
14939     });
14941     if (_this.featuresNativeTextTracks) {
14942       if (crossoriginTracks) {
14943         _log2['default'].warn((0, _tsml2['default'])(_templateObject));
14944       }
14946       _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange);
14947       _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd);
14948       _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove);
14949       _this.proxyNativeTextTracks_();
14950     }
14952     // Determine if native controls should be used
14953     // Our goal should be to get the custom controls on mobile solid everywhere
14954     // so we can remove this all together. Right now this will block custom
14955     // controls on touch enabled laptops like the Chrome Pixel
14956     if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
14957       _this.setControls(true);
14958     }
14960     // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
14961     // into a `fullscreenchange` event
14962     _this.proxyWebkitFullscreen_();
14964     _this.triggerReady();
14965     return _this;
14966   }
14968   /**
14969    * Dispose of `HTML5` media element and remove all tracks.
14970    */
14973   Html5.prototype.dispose = function dispose() {
14974     var _this2 = this;
14976     // Un-ProxyNativeTracks
14977     ['audio', 'video', 'text'].forEach(function (type) {
14978       var capitalType = (0, _toTitleCase2['default'])(type);
14979       var tl = _this2.el_[type + 'Tracks'];
14981       if (tl && tl.removeEventListener) {
14982         tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
14983         tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
14984         tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
14985       }
14987       // Stop removing old text tracks
14988       if (tl) {
14989         _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']);
14990       }
14991     });
14993     Html5.disposeMediaElement(this.el_);
14994     // tech will handle clearing of the emulated track list
14995     _Tech.prototype.dispose.call(this);
14996   };
14998   /**
14999    * Create the `Html5` Tech's DOM element.
15000    *
15001    * @return {Element}
15002    *         The element that gets created.
15003    */
15006   Html5.prototype.createEl = function createEl() {
15007     var el = this.options_.tag;
15009     // Check if this browser supports moving the element into the box.
15010     // On the iPhone video will break if you move the element,
15011     // So we have to create a brand new element.
15012     // If we ingested the player div, we do not need to move the media element.
15013     if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
15015       // If the original tag is still there, clone and remove it.
15016       if (el) {
15017         var clone = el.cloneNode(true);
15019         if (el.parentNode) {
15020           el.parentNode.insertBefore(clone, el);
15021         }
15022         Html5.disposeMediaElement(el);
15023         el = clone;
15024       } else {
15025         el = _document2['default'].createElement('video');
15027         // determine if native controls should be used
15028         var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
15029         var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
15031         if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
15032           delete attributes.controls;
15033         }
15035         Dom.setElAttributes(el, (0, _obj.assign)(attributes, {
15036           id: this.options_.techId,
15037           'class': 'vjs-tech'
15038         }));
15039       }
15041       el.playerId = this.options_.playerId;
15042     }
15044     // Update specific tag settings, in case they were overridden
15045     var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
15047     for (var i = settingsAttrs.length - 1; i >= 0; i--) {
15048       var attr = settingsAttrs[i];
15049       var overwriteAttrs = {};
15051       if (typeof this.options_[attr] !== 'undefined') {
15052         overwriteAttrs[attr] = this.options_[attr];
15053       }
15054       Dom.setElAttributes(el, overwriteAttrs);
15055     }
15057     return el;
15058   };
15060   /**
15061    * This will be triggered if the loadstart event has already fired, before videojs was
15062    * ready. Two known examples of when this can happen are:
15063    * 1. If we're loading the playback object after it has started loading
15064    * 2. The media is already playing the (often with autoplay on) then
15065    *
15066    * This function will fire another loadstart so that videojs can catchup.
15067    *
15068    * @fires Tech#loadstart
15069    *
15070    * @return {undefined}
15071    *         returns nothing.
15072    */
15075   Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
15076     var _this3 = this;
15078     if (el.networkState === 0 || el.networkState === 3) {
15079       // The video element hasn't started loading the source yet
15080       // or didn't find a source
15081       return;
15082     }
15084     if (el.readyState === 0) {
15085       var _ret = function () {
15086         // NetworkState is set synchronously BUT loadstart is fired at the
15087         // end of the current stack, usually before setInterval(fn, 0).
15088         // So at this point we know loadstart may have already fired or is
15089         // about to fire, and either way the player hasn't seen it yet.
15090         // We don't want to fire loadstart prematurely here and cause a
15091         // double loadstart so we'll wait and see if it happens between now
15092         // and the next loop, and fire it if not.
15093         // HOWEVER, we also want to make sure it fires before loadedmetadata
15094         // which could also happen between now and the next loop, so we'll
15095         // watch for that also.
15096         var loadstartFired = false;
15097         var setLoadstartFired = function setLoadstartFired() {
15098           loadstartFired = true;
15099         };
15101         _this3.on('loadstart', setLoadstartFired);
15103         var triggerLoadstart = function triggerLoadstart() {
15104           // We did miss the original loadstart. Make sure the player
15105           // sees loadstart before loadedmetadata
15106           if (!loadstartFired) {
15107             this.trigger('loadstart');
15108           }
15109         };
15111         _this3.on('loadedmetadata', triggerLoadstart);
15113         _this3.ready(function () {
15114           this.off('loadstart', setLoadstartFired);
15115           this.off('loadedmetadata', triggerLoadstart);
15117           if (!loadstartFired) {
15118             // We did miss the original native loadstart. Fire it now.
15119             this.trigger('loadstart');
15120           }
15121         });
15123         return {
15124           v: void 0
15125         };
15126       }();
15128       if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
15129     }
15131     // From here on we know that loadstart already fired and we missed it.
15132     // The other readyState events aren't as much of a problem if we double
15133     // them, so not going to go to as much trouble as loadstart to prevent
15134     // that unless we find reason to.
15135     var eventsToTrigger = ['loadstart'];
15137     // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
15138     eventsToTrigger.push('loadedmetadata');
15140     // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
15141     if (el.readyState >= 2) {
15142       eventsToTrigger.push('loadeddata');
15143     }
15145     // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
15146     if (el.readyState >= 3) {
15147       eventsToTrigger.push('canplay');
15148     }
15150     // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
15151     if (el.readyState >= 4) {
15152       eventsToTrigger.push('canplaythrough');
15153     }
15155     // We still need to give the player time to add event listeners
15156     this.ready(function () {
15157       eventsToTrigger.forEach(function (type) {
15158         this.trigger(type);
15159       }, this);
15160     });
15161   };
15163   /**
15164    * Add event listeners to native text track events. This adds the native text tracks
15165    * to our emulated {@link TextTrackList}.
15166    */
15169   Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
15170     var tt = this.el().textTracks;
15172     if (tt) {
15173       // Add tracks - if player is initialised after DOM loaded, textTracks
15174       // will not trigger addtrack
15175       for (var i = 0; i < tt.length; i++) {
15176         this.textTracks().addTrack_(tt[i]);
15177       }
15179       if (tt.addEventListener) {
15180         tt.addEventListener('change', this.handleTextTrackChange_);
15181         tt.addEventListener('addtrack', this.handleTextTrackAdd_);
15182         tt.addEventListener('removetrack', this.handleTextTrackRemove_);
15183       }
15185       // Remove (native) texttracks that are not used anymore
15186       this.on('loadstart', this.removeOldTextTracks_);
15187     }
15188   };
15190   /**
15191    * Handle any {@link TextTrackList} `change` event.
15192    *
15193    * @param {EventTarget~Event} e
15194    *        The `change` event that caused this to run.
15195    *
15196    * @listens TextTrackList#change
15197    */
15200   Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
15201     var tt = this.textTracks();
15203     this.textTracks().trigger({
15204       type: 'change',
15205       target: tt,
15206       currentTarget: tt,
15207       srcElement: tt
15208     });
15209   };
15211   /**
15212    * Handle any {@link TextTrackList} `addtrack` event.
15213    *
15214    * @param {EventTarget~Event} e
15215    *        The `addtrack` event that caused this to run.
15216    *
15217    * @listens TextTrackList#addtrack
15218    */
15221   Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
15222     this.textTracks().addTrack_(e.track);
15223   };
15225   /**
15226    * Handle any {@link TextTrackList} `removetrack` event.
15227    *
15228    * @param {EventTarget~Event} e
15229    *        The `removetrack` event that caused this to run.
15230    *
15231    * @listens TextTrackList#removetrack
15232    */
15235   Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
15236     this.textTracks().removeTrack_(e.track);
15237   };
15239   /**
15240    * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or
15241    * {@link TextTrack}s that are not in the media elements TrackList.
15242    *
15243    * @param {TrackList} techTracks
15244    *        HTML5 Tech's TrackList to search through
15245    *
15246    * @param {TrackList} elTracks
15247    *        HTML5 media elements TrackList to search through.
15248    *
15249    * @private
15250    */
15253   Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) {
15254     // This will loop over the techTracks and check if they are still used by the HTML5 media element
15255     // If not, they will be removed from the emulated list
15256     var removeTracks = [];
15258     if (!elTracks) {
15259       return;
15260     }
15262     for (var i = 0; i < techTracks.length; i++) {
15263       var techTrack = techTracks[i];
15264       var found = false;
15266       for (var j = 0; j < elTracks.length; j++) {
15267         if (elTracks[j] === techTrack) {
15268           found = true;
15269           break;
15270         }
15271       }
15273       if (!found) {
15274         removeTracks.push(techTrack);
15275       }
15276     }
15278     for (var _i = 0; _i < removeTracks.length; _i++) {
15279       var track = removeTracks[_i];
15281       techTracks.removeTrack_(track);
15282     }
15283   };
15285   /**
15286    * Remove {@link TextTrack}s that dont exist in the native track list from our
15287    * emulated {@link TextTrackList}.
15288    *
15289    * @listens Tech#loadstart
15290    */
15293   Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) {
15294     var techTracks = this.textTracks();
15295     var elTracks = this.el().textTracks;
15297     this.removeOldTracks_(techTracks, elTracks);
15298   };
15300   /**
15301    * Called by {@link Player#play} to play using the `Html5` `Tech`.
15302    */
15305   Html5.prototype.play = function play() {
15306     var playPromise = this.el_.play();
15308     // Catch/silence error when a pause interrupts a play request
15309     // on browsers which return a promise
15310     if (playPromise !== undefined && typeof playPromise.then === 'function') {
15311       playPromise.then(null, function (e) {});
15312     }
15313   };
15315   /**
15316    * Set current time for the `HTML5` tech.
15317    *
15318    * @param {number} seconds
15319    *        Set the current time of the media to this.
15320    */
15323   Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
15324     try {
15325       this.el_.currentTime = seconds;
15326     } catch (e) {
15327       (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
15328       // this.warning(VideoJS.warnings.videoNotReady);
15329     }
15330   };
15332   /**
15333    * Get the current duration of the HTML5 media element.
15334    *
15335    * @return {number}
15336    *         The duration of the media or 0 if there is no duration.
15337    */
15340   Html5.prototype.duration = function duration() {
15341     var _this4 = this;
15343     // Android Chrome will report duration as Infinity for VOD HLS until after
15344     // playback has started, which triggers the live display erroneously.
15345     // Return NaN if playback has not started and trigger a durationupdate once
15346     // the duration can be reliably known.
15347     if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
15348       if (this.el_.currentTime === 0) {
15349         var _ret2 = function () {
15350           // Wait for the first `timeupdate` with currentTime > 0 - there may be
15351           // several with 0
15352           var checkProgress = function checkProgress() {
15353             if (_this4.el_.currentTime > 0) {
15354               // Trigger durationchange for genuinely live video
15355               if (_this4.el_.duration === Infinity) {
15356                 _this4.trigger('durationchange');
15357               }
15358               _this4.off('timeupdate', checkProgress);
15359             }
15360           };
15362           _this4.on('timeupdate', checkProgress);
15363           return {
15364             v: NaN
15365           };
15366         }();
15368         if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
15369       }
15370     }
15371     return this.el_.duration || NaN;
15372   };
15374   /**
15375    * Get the current width of the HTML5 media element.
15376    *
15377    * @return {number}
15378    *         The width of the HTML5 media element.
15379    */
15382   Html5.prototype.width = function width() {
15383     return this.el_.offsetWidth;
15384   };
15386   /**
15387    * Get the current height of the HTML5 media element.
15388    *
15389    * @return {number}
15390    *         The height of the HTML5 media element.
15391    */
15394   Html5.prototype.height = function height() {
15395     return this.el_.offsetHeight;
15396   };
15398   /**
15399    * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
15400    * `fullscreenchange` event.
15401    *
15402    * @private
15403    * @fires fullscreenchange
15404    * @listens webkitendfullscreen
15405    * @listens webkitbeginfullscreen
15406    * @listens webkitbeginfullscreen
15407    */
15410   Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
15411     var _this5 = this;
15413     if (!('webkitDisplayingFullscreen' in this.el_)) {
15414       return;
15415     }
15417     var endFn = function endFn() {
15418       this.trigger('fullscreenchange', { isFullscreen: false });
15419     };
15421     var beginFn = function beginFn() {
15422       this.one('webkitendfullscreen', endFn);
15424       this.trigger('fullscreenchange', { isFullscreen: true });
15425     };
15427     this.on('webkitbeginfullscreen', beginFn);
15428     this.on('dispose', function () {
15429       _this5.off('webkitbeginfullscreen', beginFn);
15430       _this5.off('webkitendfullscreen', endFn);
15431     });
15432   };
15434   /**
15435    * Check if fullscreen is supported on the current playback device.
15436    *
15437    * @return {boolean}
15438    *         - True if fullscreen is supported.
15439    *         - False if fullscreen is not supported.
15440    */
15443   Html5.prototype.supportsFullScreen = function supportsFullScreen() {
15444     if (typeof this.el_.webkitEnterFullScreen === 'function') {
15445       var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
15447       // Seems to be broken in Chromium/Chrome && Safari in Leopard
15448       if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
15449         return true;
15450       }
15451     }
15452     return false;
15453   };
15455   /**
15456    * Request that the `HTML5` Tech enter fullscreen.
15457    */
15460   Html5.prototype.enterFullScreen = function enterFullScreen() {
15461     var video = this.el_;
15463     if (video.paused && video.networkState <= video.HAVE_METADATA) {
15464       // attempt to prime the video element for programmatic access
15465       // this isn't necessary on the desktop but shouldn't hurt
15466       this.el_.play();
15468       // playing and pausing synchronously during the transition to fullscreen
15469       // can get iOS ~6.1 devices into a play/pause loop
15470       this.setTimeout(function () {
15471         video.pause();
15472         video.webkitEnterFullScreen();
15473       }, 0);
15474     } else {
15475       video.webkitEnterFullScreen();
15476     }
15477   };
15479   /**
15480    * Request that the `HTML5` Tech exit fullscreen.
15481    */
15484   Html5.prototype.exitFullScreen = function exitFullScreen() {
15485     this.el_.webkitExitFullScreen();
15486   };
15488   /**
15489    * A getter/setter for the `Html5` Tech's source object.
15490    * > Note: Please use {@link Html5#setSource}
15491    *
15492    * @param {Tech~SourceObject} [src]
15493    *        The source object you want to set on the `HTML5` techs element.
15494    *
15495    * @return {Tech~SourceObject|undefined}
15496    *         - The current source object when a source is not passed in.
15497    *         - undefined when setting
15498    *
15499    * @deprecated Since version 5.
15500    */
15503   Html5.prototype.src = function src(_src) {
15504     if (_src === undefined) {
15505       return this.el_.src;
15506     }
15508     // Setting src through `src` instead of `setSrc` will be deprecated
15509     this.setSrc(_src);
15510   };
15512   /**
15513    * Reset the tech by removing all sources and then calling
15514    * {@link Html5.resetMediaElement}.
15515    */
15518   Html5.prototype.reset = function reset() {
15519     Html5.resetMediaElement(this.el_);
15520   };
15522   /**
15523    * Get the current source on the `HTML5` Tech. Falls back to returning the source from
15524    * the HTML5 media element.
15525    *
15526    * @return {Tech~SourceObject}
15527    *         The current source object from the HTML5 tech. With a fallback to the
15528    *         elements source.
15529    */
15532   Html5.prototype.currentSrc = function currentSrc() {
15533     if (this.currentSource_) {
15534       return this.currentSource_.src;
15535     }
15536     return this.el_.currentSrc;
15537   };
15539   /**
15540    * Set controls attribute for the HTML5 media Element.
15541    *
15542    * @param {string} val
15543    *        Value to set the controls attribute to
15544    */
15547   Html5.prototype.setControls = function setControls(val) {
15548     this.el_.controls = !!val;
15549   };
15551   /**
15552    * Create and returns a remote {@link TextTrack} object.
15553    *
15554    * @param {string} kind
15555    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
15556    *
15557    * @param {string} [label]
15558    *        Label to identify the text track
15559    *
15560    * @param {string} [language]
15561    *        Two letter language abbreviation
15562    *
15563    * @return {TextTrack}
15564    *         The TextTrack that gets created.
15565    */
15568   Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15569     if (!this.featuresNativeTextTracks) {
15570       return _Tech.prototype.addTextTrack.call(this, kind, label, language);
15571     }
15573     return this.el_.addTextTrack(kind, label, language);
15574   };
15576   /**
15577    * Creates either native TextTrack or an emulated TextTrack depending
15578    * on the value of `featuresNativeTextTracks`
15579    *
15580    * @param {Object} options
15581    *        The object should contain the options to initialize the TextTrack with.
15582    *
15583    * @param {string} [options.kind]
15584    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
15585    *
15586    * @param {string} [options.label].
15587    *        Label to identify the text track
15588    *
15589    * @param {string} [options.language]
15590    *        Two letter language abbreviation.
15591    *
15592    * @param {boolean} [options.default]
15593    *        Default this track to on.
15594    *
15595    * @param {string} [options.id]
15596    *        The internal id to assign this track.
15597    *
15598    * @param {string} [options.src]
15599    *        A source url for the track.
15600    *
15601    * @return {HTMLTrackElement}
15602    *         The track element that gets created.
15603    */
15606   Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
15607     if (!this.featuresNativeTextTracks) {
15608       return _Tech.prototype.createRemoteTextTrack.call(this, options);
15609     }
15610     var htmlTrackElement = _document2['default'].createElement('track');
15612     if (options.kind) {
15613       htmlTrackElement.kind = options.kind;
15614     }
15615     if (options.label) {
15616       htmlTrackElement.label = options.label;
15617     }
15618     if (options.language || options.srclang) {
15619       htmlTrackElement.srclang = options.language || options.srclang;
15620     }
15621     if (options['default']) {
15622       htmlTrackElement['default'] = options['default'];
15623     }
15624     if (options.id) {
15625       htmlTrackElement.id = options.id;
15626     }
15627     if (options.src) {
15628       htmlTrackElement.src = options.src;
15629     }
15631     return htmlTrackElement;
15632   };
15634   /**
15635    * Creates a remote text track object and returns an html track element.
15636    *
15637    * @param {Object} options The object should contain values for
15638    * kind, language, label, and src (location of the WebVTT file)
15639    * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
15640    * automatically removed from the video element whenever the source changes
15641    * @return {HTMLTrackElement} An Html Track Element.
15642    * This can be an emulated {@link HTMLTrackElement} or a native one.
15643    * @deprecated The default value of the "manualCleanup" parameter will default
15644    * to "false" in upcoming versions of Video.js
15645    */
15648   Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
15649     var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
15651     if (this.featuresNativeTextTracks) {
15652       this.el().appendChild(htmlTrackElement);
15653     }
15655     return htmlTrackElement;
15656   };
15658   /**
15659    * Remove remote `TextTrack` from `TextTrackList` object
15660    *
15661    * @param {TextTrack} track
15662    *        `TextTrack` object to remove
15663    */
15666   Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15667     _Tech.prototype.removeRemoteTextTrack.call(this, track);
15669     if (this.featuresNativeTextTracks) {
15670       var tracks = this.$$('track');
15672       var i = tracks.length;
15674       while (i--) {
15675         if (track === tracks[i] || track === tracks[i].track) {
15676           this.el().removeChild(tracks[i]);
15677         }
15678       }
15679     }
15680   };
15682   return Html5;
15683 }(_tech2['default']);
15685 /* HTML5 Support Testing ---------------------------------------------------- */
15687 if (Dom.isReal()) {
15689   /**
15690    * Element for testing browser HTML5 media capabilities
15691    *
15692    * @type {Element}
15693    * @constant
15694    * @private
15695    */
15696   Html5.TEST_VID = _document2['default'].createElement('video');
15697   var track = _document2['default'].createElement('track');
15699   track.kind = 'captions';
15700   track.srclang = 'en';
15701   track.label = 'English';
15702   Html5.TEST_VID.appendChild(track);
15706  * Check if HTML5 media is supported by this browser/device.
15708  * @return {boolean}
15709  *         - True if HTML5 media is supported.
15710  *         - False if HTML5 media is not supported.
15711  */
15712 Html5.isSupported = function () {
15713   // IE9 with no Media Player is a LIAR! (#984)
15714   try {
15715     Html5.TEST_VID.volume = 0.5;
15716   } catch (e) {
15717     return false;
15718   }
15720   return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
15724  * Check if the volume can be changed in this browser/device.
15725  * Volume cannot be changed in a lot of mobile devices.
15726  * Specifically, it can't be changed from 1 on iOS.
15728  * @return {boolean}
15729  *         - True if volume can be controlled
15730  *         - False otherwise
15731  */
15732 Html5.canControlVolume = function () {
15733   // IE will error if Windows Media Player not installed #3315
15734   try {
15735     var volume = Html5.TEST_VID.volume;
15737     Html5.TEST_VID.volume = volume / 2 + 0.1;
15738     return volume !== Html5.TEST_VID.volume;
15739   } catch (e) {
15740     return false;
15741   }
15745  * Check if the playback rate can be changed in this browser/device.
15747  * @return {boolean}
15748  *         - True if playback rate can be controlled
15749  *         - False otherwise
15750  */
15751 Html5.canControlPlaybackRate = function () {
15752   // Playback rate API is implemented in Android Chrome, but doesn't do anything
15753   // https://github.com/videojs/video.js/issues/3180
15754   if (browser.IS_ANDROID && browser.IS_CHROME) {
15755     return false;
15756   }
15757   // IE will error if Windows Media Player not installed #3315
15758   try {
15759     var playbackRate = Html5.TEST_VID.playbackRate;
15761     Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
15762     return playbackRate !== Html5.TEST_VID.playbackRate;
15763   } catch (e) {
15764     return false;
15765   }
15769  * Check to see if native `TextTrack`s are supported by this browser/device.
15771  * @return {boolean}
15772  *         - True if native `TextTrack`s are supported.
15773  *         - False otherwise
15774  */
15775 Html5.supportsNativeTextTracks = function () {
15776   return browser.IS_ANY_SAFARI;
15780  * Check to see if native `VideoTrack`s are supported by this browser/device
15782  * @return {boolean}
15783  *        - True if native `VideoTrack`s are supported.
15784  *        - False otherwise
15785  */
15786 Html5.supportsNativeVideoTracks = function () {
15787   return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
15791  * Check to see if native `AudioTrack`s are supported by this browser/device
15793  * @return {boolean}
15794  *        - True if native `AudioTrack`s are supported.
15795  *        - False otherwise
15796  */
15797 Html5.supportsNativeAudioTracks = function () {
15798   return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
15802  * An array of events available on the Html5 tech.
15804  * @private
15805  * @type {Array}
15806  */
15807 Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
15810  * Boolean indicating whether the `Tech` supports volume control.
15812  * @type {boolean}
15813  * @default {@link Html5.canControlVolume}
15814  */
15815 Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
15818  * Boolean indicating whether the `Tech` supports changing the speed at which the media
15819  * plays. Examples:
15820  *   - Set player to play 2x (twice) as fast
15821  *   - Set player to play 0.5x (half) as fast
15823  * @type {boolean}
15824  * @default {@link Html5.canControlPlaybackRate}
15825  */
15826 Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
15829  * Boolean indicating whether the `HTML5` tech currently supports the media element
15830  * moving in the DOM. iOS breaks if you move the media element, so this is set this to
15831  * false there. Everywhere else this should be true.
15833  * @type {boolean}
15834  * @default
15835  */
15836 Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
15838 // TODO: Previous comment: No longer appears to be used. Can probably be removed.
15839 //       Is this true?
15841  * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
15842  * when going into fullscreen.
15844  * @type {boolean}
15845  * @default
15846  */
15847 Html5.prototype.featuresFullscreenResize = true;
15850  * Boolean indicating whether the `HTML5` tech currently supports the progress event.
15851  * If this is false, manual `progress` events will be triggred instead.
15853  * @type {boolean}
15854  * @default
15855  */
15856 Html5.prototype.featuresProgressEvents = true;
15859  * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
15860  * If this is false, manual `timeupdate` events will be triggred instead.
15862  * @default
15863  */
15864 Html5.prototype.featuresTimeupdateEvents = true;
15867  * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
15869  * @type {boolean}
15870  * @default {@link Html5.supportsNativeTextTracks}
15871  */
15872 Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
15875  * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
15877  * @type {boolean}
15878  * @default {@link Html5.supportsNativeVideoTracks}
15879  */
15880 Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
15883  * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
15885  * @type {boolean}
15886  * @default {@link Html5.supportsNativeAudioTracks}
15887  */
15888 Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
15890 // HTML5 Feature detection and Device Fixes --------------------------------- //
15891 var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
15892 var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15893 var mp4RE = /^video\/mp4/i;
15895 Html5.patchCanPlayType = function () {
15897   // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15898   if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
15899     Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15900       if (type && mpegurlRE.test(type)) {
15901         return 'maybe';
15902       }
15903       return canPlayType.call(this, type);
15904     };
15906     // Override Android 2.2 and less canPlayType method which is broken
15907   } else if (browser.IS_OLD_ANDROID) {
15908     Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15909       if (type && mp4RE.test(type)) {
15910         return 'maybe';
15911       }
15912       return canPlayType.call(this, type);
15913     };
15914   }
15917 Html5.unpatchCanPlayType = function () {
15918   var r = Html5.TEST_VID.constructor.prototype.canPlayType;
15920   Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
15921   return r;
15924 // by default, patch the media element
15925 Html5.patchCanPlayType();
15927 Html5.disposeMediaElement = function (el) {
15928   if (!el) {
15929     return;
15930   }
15932   if (el.parentNode) {
15933     el.parentNode.removeChild(el);
15934   }
15936   // remove any child track or source nodes to prevent their loading
15937   while (el.hasChildNodes()) {
15938     el.removeChild(el.firstChild);
15939   }
15941   // remove any src reference. not setting `src=''` because that causes a warning
15942   // in firefox
15943   el.removeAttribute('src');
15945   // force the media element to update its loading state by calling load()
15946   // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
15947   if (typeof el.load === 'function') {
15948     // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15949     (function () {
15950       try {
15951         el.load();
15952       } catch (e) {
15953         // not supported
15954       }
15955     })();
15956   }
15959 Html5.resetMediaElement = function (el) {
15960   if (!el) {
15961     return;
15962   }
15964   var sources = el.querySelectorAll('source');
15965   var i = sources.length;
15967   while (i--) {
15968     el.removeChild(sources[i]);
15969   }
15971   // remove any src reference.
15972   // not setting `src=''` because that throws an error
15973   el.removeAttribute('src');
15975   if (typeof el.load === 'function') {
15976     // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15977     (function () {
15978       try {
15979         el.load();
15980       } catch (e) {
15981         // satisfy linter
15982       }
15983     })();
15984   }
15987 /* Native HTML5 element property wrapping ----------------------------------- */
15988 // Wrap native properties with a getter
15991  * Get the value of `paused` from the media element. `paused` indicates whether the media element
15992  * is currently paused or not.
15994  * @method Html5#paused
15995  * @return {boolean}
15996  *         The value of `paused` from the media element.
15998  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
15999  */
16000 'paused',
16003  * Get the value of `currentTime` from the media element. `currentTime` indicates
16004  * the current second that the media is at in playback.
16006  * @method Html5#currentTime
16007  * @return {number}
16008  *         The value of `currentTime` from the media element.
16010  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
16011  */
16012 'currentTime',
16015  * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
16016  * object that represents the parts of the media that are already downloaded and
16017  * available for playback.
16019  * @method Html5#buffered
16020  * @return {TimeRange}
16021  *         The value of `buffered` from the media element.
16023  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
16024  */
16025 'buffered',
16028  * Get the value of `volume` from the media element. `volume` indicates
16029  * the current playback volume of audio for a media. `volume` will be a value from 0
16030  * (silent) to 1 (loudest and default).
16032  * @method Html5#volume
16033  * @return {number}
16034  *         The value of `volume` from the media element. Value will be between 0-1.
16036  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16037  */
16038 'volume',
16041  * Get the value of `muted` from the media element. `muted` indicates
16042  * that the volume for the media should be set to silent. This does not actually change
16043  * the `volume` attribute.
16045  * @method Html5#muted
16046  * @return {boolean}
16047  *         - True if the value of `volume` should be ignored and the audio set to silent.
16048  *         - False if the value of `volume` should be used.
16050  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16051  */
16052 'muted',
16055  * Get the value of `poster` from the media element. `poster` indicates
16056  * that the url of an image file that can/will be shown when no media data is available.
16058  * @method Html5#poster
16059  * @return {string}
16060  *         The value of `poster` from the media element. Value will be a url to an
16061  *         image.
16063  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
16064  */
16065 'poster',
16068  * Get the value of `preload` from the media element. `preload` indicates
16069  * what should download before the media is interacted with. It can have the following
16070  * values:
16071  * - none: nothing should be downloaded
16072  * - metadata: poster and the first few frames of the media may be downloaded to get
16073  *   media dimensions and other metadata
16074  * - auto: allow the media and metadata for the media to be downloaded before
16075  *    interaction
16077  * @method Html5#preload
16078  * @return {string}
16079  *         The value of `preload` from the media element. Will be 'none', 'metadata',
16080  *         or 'auto'.
16082  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16083  */
16084 'preload',
16087  * Get the value of `autoplay` from the media element. `autoplay` indicates
16088  * that the media should start to play as soon as the page is ready.
16090  * @method Html5#autoplay
16091  * @return {boolean}
16092  *         - The value of `autoplay` from the media element.
16093  *         - True indicates that the media should start as soon as the page loads.
16094  *         - False indicates that the media should not start as soon as the page loads.
16096  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16097  */
16098 'autoplay',
16101  * Get the value of `controls` from the media element. `controls` indicates
16102  * whether the native media controls should be shown or hidden.
16104  * @method Html5#controls
16105  * @return {boolean}
16106  *         - The value of `controls` from the media element.
16107  *         - True indicates that native controls should be showing.
16108  *         - False indicates that native controls should be hidden.
16110  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
16111  */
16112 'controls',
16115  * Get the value of `loop` from the media element. `loop` indicates
16116  * that the media should return to the start of the media and continue playing once
16117  * it reaches the end.
16119  * @method Html5#loop
16120  * @return {boolean}
16121  *         - The value of `loop` from the media element.
16122  *         - True indicates that playback should seek back to start once
16123  *           the end of a media is reached.
16124  *         - False indicates that playback should not loop back to the start when the
16125  *           end of the media is reached.
16127  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16128  */
16129 'loop',
16132  * Get the value of the `error` from the media element. `error` indicates any
16133  * MediaError that may have occurred during playback. If error returns null there is no
16134  * current error.
16136  * @method Html5#error
16137  * @return {MediaError|null}
16138  *         The value of `error` from the media element. Will be `MediaError` if there
16139  *         is a current error and null otherwise.
16141  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
16142  */
16143 'error',
16146  * Get the value of `seeking` from the media element. `seeking` indicates whether the
16147  * media is currently seeking to a new position or not.
16149  * @method Html5#seeking
16150  * @return {boolean}
16151  *         - The value of `seeking` from the media element.
16152  *         - True indicates that the media is currently seeking to a new position.
16153  *         - Flase indicates that the media is not seeking to a new position at this time.
16155  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
16156  */
16157 'seeking',
16160  * Get the value of `seekable` from the media element. `seekable` returns a
16161  * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
16163  * @method Html5#seekable
16164  * @return {TimeRange}
16165  *         The value of `seekable` from the media element. A `TimeRange` object
16166  *         indicating the current ranges of time that can be seeked to.
16168  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
16169  */
16170 'seekable',
16173  * Get the value of `ended` from the media element. `ended` indicates whether
16174  * the media has reached the end or not.
16176  * @method Html5#ended
16177  * @return {boolean}
16178  *         - The value of `ended` from the media element.
16179  *         - True indicates that the media has ended.
16180  *         - False indicates that the media has not ended.
16182  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
16183  */
16184 'ended',
16187  * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
16188  * whether the media should start muted or not. Only changes the default state of the
16189  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
16190  * current state.
16192  * @method Html5#defaultMuted
16193  * @return {boolean}
16194  *         - The value of `defaultMuted` from the media element.
16195  *         - True indicates that the media should start muted.
16196  *         - False indicates that the media should not start muted
16198  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
16199  */
16200 'defaultMuted',
16203  * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16204  * the rate at which the media is currently playing back. Examples:
16205  *   - if playbackRate is set to 2, media will play twice as fast.
16206  *   - if playbackRate is set to 0.5, media will play half as fast.
16208  * @method Html5#playbackRate
16209  * @return {number}
16210  *         The value of `playbackRate` from the media element. A number indicating
16211  *         the current playback speed of the media, where 1 is normal speed.
16213  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16214  */
16215 'playbackRate',
16218  * Get the value of `played` from the media element. `played` returns a `TimeRange`
16219  * object representing points in the media timeline that have been played.
16221  * @method Html5#played
16222  * @return {TimeRange}
16223  *         The value of `played` from the media element. A `TimeRange` object indicating
16224  *         the ranges of time that have been played.
16226  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
16227  */
16228 'played',
16231  * Get the value of `networkState` from the media element. `networkState` indicates
16232  * the current network state. It returns an enumeration from the following list:
16233  * - 0: NETWORK_EMPTY
16234  * - 1: NEWORK_IDLE
16235  * - 2: NETWORK_LOADING
16236  * - 3: NETWORK_NO_SOURCE
16238  * @method Html5#networkState
16239  * @return {number}
16240  *         The value of `networkState` from the media element. This will be a number
16241  *         from the list in the description.
16243  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
16244  */
16245 'networkState',
16248  * Get the value of `readyState` from the media element. `readyState` indicates
16249  * the current state of the media element. It returns an enumeration from the
16250  * following list:
16251  * - 0: HAVE_NOTHING
16252  * - 1: HAVE_METADATA
16253  * - 2: HAVE_CURRENT_DATA
16254  * - 3: HAVE_FUTURE_DATA
16255  * - 4: HAVE_ENOUGH_DATA
16257  * @method Html5#readyState
16258  * @return {number}
16259  *         The value of `readyState` from the media element. This will be a number
16260  *         from the list in the description.
16262  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
16263  */
16264 'readyState',
16267  * Get the value of `videoWidth` from the video element. `videoWidth` indicates
16268  * the current width of the video in css pixels.
16270  * @method Html5#videoWidth
16271  * @return {number}
16272  *         The value of `videoWidth` from the video element. This will be a number
16273  *         in css pixels.
16275  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16276  */
16277 'videoWidth',
16280  * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
16281  * the current height of the video in css pixels.
16283  * @method Html5#videoHeight
16284  * @return {number}
16285  *         The value of `videoHeight` from the video element. This will be a number
16286  *         in css pixels.
16288  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16289  */
16290 'videoHeight'].forEach(function (prop) {
16291   Html5.prototype[prop] = function () {
16292     return this.el_[prop];
16293   };
16296 // Wrap native properties with a setter in this format:
16297 // set + toTitleCase(name)
16300  * Set the value of `volume` on the media element. `volume` indicates the current
16301  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
16302  * so on.
16304  * @method Html5#setVolume
16305  * @param {number} percentAsDecimal
16306  *        The volume percent as a decimal. Valid range is from 0-1.
16308  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16309  */
16310 'volume',
16313  * Set the value of `muted` on the media element. `muted` indicates the current
16314  * audio level should be silent.
16316  * @method Html5#setMuted
16317  * @param {boolean} muted
16318  *        - True if the audio should be set to silent
16319  *        - False otherwise
16321  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16322  */
16323 'muted',
16326  * Set the value of `src` on the media element. `src` indicates the current
16327  * {@link Tech~SourceObject} for the media.
16329  * @method Html5#setSrc
16330  * @param {Tech~SourceObject} src
16331  *        The source object to set as the current source.
16333  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
16334  */
16335 'src',
16338  * Set the value of `poster` on the media element. `poster` is the url to
16339  * an image file that can/will be shown when no media data is available.
16341  * @method Html5#setPoster
16342  * @param {string} poster
16343  *        The url to an image that should be used as the `poster` for the media
16344  *        element.
16346  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
16347  */
16348 'poster',
16351  * Set the value of `preload` on the media element. `preload` indicates
16352  * what should download before the media is interacted with. It can have the following
16353  * values:
16354  * - none: nothing should be downloaded
16355  * - metadata: poster and the first few frames of the media may be downloaded to get
16356  *   media dimensions and other metadata
16357  * - auto: allow the media and metadata for the media to be downloaded before
16358  *    interaction
16360  * @method Html5#setPreload
16361  * @param {string} preload
16362  *         The value of `preload` to set on the media element. Must be 'none', 'metadata',
16363  *         or 'auto'.
16365  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16366  */
16367 'preload',
16370  * Set the value of `autoplay` on the media element. `autoplay` indicates
16371  * that the media should start to play as soon as the page is ready.
16373  * @method Html5#setAutoplay
16374  * @param {boolean} autoplay
16375  *         - True indicates that the media should start as soon as the page loads.
16376  *         - False indicates that the media should not start as soon as the page loads.
16378  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16379  */
16380 'autoplay',
16383  * Set the value of `loop` on the media element. `loop` indicates
16384  * that the media should return to the start of the media and continue playing once
16385  * it reaches the end.
16387  * @method Html5#setLoop
16388  * @param {boolean} loop
16389  *         - True indicates that playback should seek back to start once
16390  *           the end of a media is reached.
16391  *         - False indicates that playback should not loop back to the start when the
16392  *           end of the media is reached.
16394  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16395  */
16396 'loop',
16399  * Set the value of `playbackRate` on the media element. `playbackRate` indicates
16400  * the rate at which the media should play back. Examples:
16401  *   - if playbackRate is set to 2, media will play twice as fast.
16402  *   - if playbackRate is set to 0.5, media will play half as fast.
16404  * @method Html5#setPlaybackRate
16405  * @return {number}
16406  *         The value of `playbackRate` from the media element. A number indicating
16407  *         the current playback speed of the media, where 1 is normal speed.
16409  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16410  */
16411 'playbackRate'].forEach(function (prop) {
16412   Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
16413     this.el_[prop] = v;
16414   };
16417 // wrap native functions with a function
16420  * A wrapper around the media elements `pause` function. This will call the `HTML5`
16421  * media elements `pause` function.
16423  * @method Html5#pause
16424  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
16425  */
16426 'pause',
16429  * A wrapper around the media elements `load` function. This will call the `HTML5`s
16430  * media element `load` function.
16432  * @method Html5#load
16433  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
16434  */
16435 'load'].forEach(function (prop) {
16436   Html5.prototype[prop] = function () {
16437     return this.el_[prop]();
16438   };
16441 _tech2['default'].withSourceHandlers(Html5);
16444  * Native source handler for Html5, simply passes the source to the media element.
16446  * @proprety {Tech~SourceObject} source
16447  *        The source object
16449  * @proprety {Html5} tech
16450  *        The instance of the HTML5 tech.
16451  */
16452 Html5.nativeSourceHandler = {};
16455  * Check if the media element can play the given mime type.
16457  * @param {string} type
16458  *        The mimetype to check
16460  * @return {string}
16461  *         'probably', 'maybe', or '' (empty string)
16462  */
16463 Html5.nativeSourceHandler.canPlayType = function (type) {
16464   // IE9 on Windows 7 without MediaPlayer throws an error here
16465   // https://github.com/videojs/video.js/issues/519
16466   try {
16467     return Html5.TEST_VID.canPlayType(type);
16468   } catch (e) {
16469     return '';
16470   }
16474  * Check if the media element can handle a source natively.
16476  * @param {Tech~SourceObject} source
16477  *         The source object
16479  * @param {Object} [options]
16480  *         Options to be passed to the tech.
16482  * @return {string}
16483  *         'probably', 'maybe', or '' (empty string).
16484  */
16485 Html5.nativeSourceHandler.canHandleSource = function (source, options) {
16487   // If a type was provided we should rely on that
16488   if (source.type) {
16489     return Html5.nativeSourceHandler.canPlayType(source.type);
16491     // If no type, fall back to checking 'video/[EXTENSION]'
16492   } else if (source.src) {
16493     var ext = Url.getFileExtension(source.src);
16495     return Html5.nativeSourceHandler.canPlayType('video/' + ext);
16496   }
16498   return '';
16502  * Pass the source to the native media element.
16504  * @param {Tech~SourceObject} source
16505  *        The source object
16507  * @param {Html5} tech
16508  *        The instance of the Html5 tech
16510  * @param {Object} [options]
16511  *        The options to pass to the source
16512  */
16513 Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
16514   tech.setSrc(source.src);
16518  * A noop for the native dispose function, as cleanup is not needed.
16519  */
16520 Html5.nativeSourceHandler.dispose = function () {};
16522 // Register the native source handler
16523 Html5.registerSourceHandler(Html5.nativeSourceHandler);
16525 _component2['default'].registerComponent('Html5', Html5);
16526 _tech2['default'].registerTech('Html5', Html5);
16527 exports['default'] = Html5;
16529 },{"5":5,"62":62,"78":78,"81":81,"83":83,"86":86,"87":87,"88":88,"91":91,"92":92,"94":94,"95":95,"98":98}],61:[function(_dereq_,module,exports){
16530 'use strict';
16532 exports.__esModule = true;
16534 var _component = _dereq_(5);
16536 var _component2 = _interopRequireDefault(_component);
16538 var _tech = _dereq_(62);
16540 var _tech2 = _interopRequireDefault(_tech);
16542 var _toTitleCase = _dereq_(91);
16544 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
16546 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16548 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16550 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
16552 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
16553                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file loader.js
16554                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
16558  * The `MediaLoader` is the `Component` that decides which playback technology to load
16559  * when a player is initialized.
16561  * @extends Component
16562  */
16563 var MediaLoader = function (_Component) {
16564   _inherits(MediaLoader, _Component);
16566   /**
16567    * Create an instance of this class.
16568    *
16569    * @param {Player} player
16570    *        The `Player` that this class should attach to.
16571    *
16572    * @param {Object} [options]
16573    *        The key/value store of player options.
16574    *
16575    * @param {Component~ReadyCallback} [ready]
16576    *        The function that is run when this component is ready.
16577    */
16578   function MediaLoader(player, options, ready) {
16579     _classCallCheck(this, MediaLoader);
16581     // If there are no sources when the player is initialized,
16582     // load the first supported playback technology.
16584     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
16586     if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
16587       for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
16588         var techName = (0, _toTitleCase2['default'])(j[i]);
16589         var tech = _tech2['default'].getTech(techName);
16591         // Support old behavior of techs being registered as components.
16592         // Remove once that deprecated behavior is removed.
16593         if (!techName) {
16594           tech = _component2['default'].getComponent(techName);
16595         }
16597         // Check if the browser supports this technology
16598         if (tech && tech.isSupported()) {
16599           player.loadTech_(techName);
16600           break;
16601         }
16602       }
16603     } else {
16604       // Loop through playback technologies (HTML5, Flash) and check for support.
16605       // Then load the best source.
16606       // A few assumptions here:
16607       //   All playback technologies respect preload false.
16608       player.src(options.playerOptions.sources);
16609     }
16610     return _this;
16611   }
16613   return MediaLoader;
16614 }(_component2['default']);
16616 _component2['default'].registerComponent('MediaLoader', MediaLoader);
16617 exports['default'] = MediaLoader;
16619 },{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){
16620 'use strict';
16622 exports.__esModule = true;
16624 var _component = _dereq_(5);
16626 var _component2 = _interopRequireDefault(_component);
16628 var _htmlTrackElement = _dereq_(66);
16630 var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
16632 var _htmlTrackElementList = _dereq_(65);
16634 var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
16636 var _mergeOptions = _dereq_(87);
16638 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
16640 var _textTrack = _dereq_(72);
16642 var _textTrack2 = _interopRequireDefault(_textTrack);
16644 var _textTrackList = _dereq_(70);
16646 var _textTrackList2 = _interopRequireDefault(_textTrackList);
16648 var _videoTrackList = _dereq_(76);
16650 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
16652 var _audioTrackList = _dereq_(63);
16654 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
16656 var _fn = _dereq_(83);
16658 var Fn = _interopRequireWildcard(_fn);
16660 var _log = _dereq_(86);
16662 var _log2 = _interopRequireDefault(_log);
16664 var _timeRanges = _dereq_(90);
16666 var _buffer = _dereq_(79);
16668 var _mediaError = _dereq_(46);
16670 var _mediaError2 = _interopRequireDefault(_mediaError);
16672 var _window = _dereq_(95);
16674 var _window2 = _interopRequireDefault(_window);
16676 var _document = _dereq_(94);
16678 var _document2 = _interopRequireDefault(_document);
16680 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
16682 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16684 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16686 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
16688 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
16689                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file tech.js
16690                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
16693  * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
16694  * that just contains the src url alone.
16695  * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
16696    * `var SourceString = 'http://example.com/some-video.mp4';`
16698  * @typedef {Object|string} Tech~SourceObject
16700  * @property {string} src
16701  *           The url to the source
16703  * @property {string} type
16704  *           The mime type of the source
16705  */
16708  * A function used by {@link Tech} to create a new {@link TextTrack}.
16710  * @param {Tech} self
16711  *        An instance of the Tech class.
16713  * @param {string} kind
16714  *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
16716  * @param {string} [label]
16717  *        Label to identify the text track
16719  * @param {string} [language]
16720  *        Two letter language abbreviation
16722  * @param {Object} [options={}]
16723  *        An object with additional text track options
16725  * @return {TextTrack}
16726  *          The text track that was created.
16727  */
16728 function createTrackHelper(self, kind, label, language) {
16729   var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
16731   var tracks = self.textTracks();
16733   options.kind = kind;
16735   if (label) {
16736     options.label = label;
16737   }
16738   if (language) {
16739     options.language = language;
16740   }
16741   options.tech = self;
16743   var track = new _textTrack2['default'](options);
16745   tracks.addTrack_(track);
16747   return track;
16751  * This is the base class for media playback technology controllers, such as
16752  * {@link Flash} and {@link HTML5}
16754  * @extends Component
16755  */
16757 var Tech = function (_Component) {
16758   _inherits(Tech, _Component);
16760   /**
16761    * Create an instance of this Tech.
16762    *
16763    * @param {Object} [options]
16764    *        The key/value store of player options.
16765    *
16766    * @param {Component~ReadyCallback} ready
16767    *        Callback function to call when the `HTML5` Tech is ready.
16768    */
16769   function Tech() {
16770     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
16771     var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
16773     _classCallCheck(this, Tech);
16775     // we don't want the tech to report user activity automatically.
16776     // This is done manually in addControlsListeners
16777     options.reportTouchActivity = false;
16779     // keep track of whether the current source has played at all to
16780     // implement a very limited played()
16781     var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
16783     _this.hasStarted_ = false;
16784     _this.on('playing', function () {
16785       this.hasStarted_ = true;
16786     });
16787     _this.on('loadstart', function () {
16788       this.hasStarted_ = false;
16789     });
16791     _this.textTracks_ = options.textTracks;
16792     _this.videoTracks_ = options.videoTracks;
16793     _this.audioTracks_ = options.audioTracks;
16795     // Manually track progress in cases where the browser/flash player doesn't report it.
16796     if (!_this.featuresProgressEvents) {
16797       _this.manualProgressOn();
16798     }
16800     // Manually track timeupdates in cases where the browser/flash player doesn't report it.
16801     if (!_this.featuresTimeupdateEvents) {
16802       _this.manualTimeUpdatesOn();
16803     }
16805     ['Text', 'Audio', 'Video'].forEach(function (track) {
16806       if (options['native' + track + 'Tracks'] === false) {
16807         _this['featuresNative' + track + 'Tracks'] = false;
16808       }
16809     });
16811     if (options.nativeCaptions === false) {
16812       _this.featuresNativeTextTracks = false;
16813     }
16815     if (!_this.featuresNativeTextTracks) {
16816       _this.emulateTextTracks();
16817     }
16819     _this.autoRemoteTextTracks_ = new _textTrackList2['default']();
16821     _this.initTextTrackListeners();
16822     _this.initTrackListeners();
16824     // Turn on component tap events only if not using native controls
16825     if (!options.nativeControlsForTouch) {
16826       _this.emitTapEvents();
16827     }
16828     return _this;
16829   }
16831   /* Fallbacks for unsupported event types
16832   ================================================================================ */
16834   /**
16835    * Polyfill the `progress` event for browsers that don't support it natively.
16836    *
16837    * @see {@link Tech#trackProgress}
16838    */
16841   Tech.prototype.manualProgressOn = function manualProgressOn() {
16842     this.on('durationchange', this.onDurationChange);
16844     this.manualProgress = true;
16846     // Trigger progress watching when a source begins loading
16847     this.one('ready', this.trackProgress);
16848   };
16850   /**
16851    * Turn off the polyfill for `progress` events that was created in
16852    * {@link Tech#manualProgressOn}
16853    */
16856   Tech.prototype.manualProgressOff = function manualProgressOff() {
16857     this.manualProgress = false;
16858     this.stopTrackingProgress();
16860     this.off('durationchange', this.onDurationChange);
16861   };
16863   /**
16864    * This is used to trigger a `progress` event when the buffered percent changes. It
16865    * sets an interval function that will be called every 500 milliseconds to check if the
16866    * buffer end percent has changed.
16867    *
16868    * > This function is called by {@link Tech#manualProgressOn}
16869    *
16870    * @param {EventTarget~Event} event
16871    *        The `ready` event that caused this to run.
16872    *
16873    * @listens Tech#ready
16874    * @fires Tech#progress
16875    */
16878   Tech.prototype.trackProgress = function trackProgress(event) {
16879     this.stopTrackingProgress();
16880     this.progressInterval = this.setInterval(Fn.bind(this, function () {
16881       // Don't trigger unless buffered amount is greater than last time
16883       var numBufferedPercent = this.bufferedPercent();
16885       if (this.bufferedPercent_ !== numBufferedPercent) {
16886         /**
16887          * See {@link Player#progress}
16888          *
16889          * @event Tech#progress
16890          * @type {EventTarget~Event}
16891          */
16892         this.trigger('progress');
16893       }
16895       this.bufferedPercent_ = numBufferedPercent;
16897       if (numBufferedPercent === 1) {
16898         this.stopTrackingProgress();
16899       }
16900     }), 500);
16901   };
16903   /**
16904    * Update our internal duration on a `durationchange` event by calling
16905    * {@link Tech#duration}.
16906    *
16907    * @param {EventTarget~Event} event
16908    *        The `durationchange` event that caused this to run.
16909    *
16910    * @listens Tech#durationchange
16911    */
16914   Tech.prototype.onDurationChange = function onDurationChange(event) {
16915     this.duration_ = this.duration();
16916   };
16918   /**
16919    * Get and create a `TimeRange` object for buffering.
16920    *
16921    * @return {TimeRange}
16922    *         The time range object that was created.
16923    */
16926   Tech.prototype.buffered = function buffered() {
16927     return (0, _timeRanges.createTimeRange)(0, 0);
16928   };
16930   /**
16931    * Get the percentage of the current video that is currently buffered.
16932    *
16933    * @return {number}
16934    *         A number from 0 to 1 that represents the decimal percentage of the
16935    *         video that is buffered.
16936    *
16937    */
16940   Tech.prototype.bufferedPercent = function bufferedPercent() {
16941     return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
16942   };
16944   /**
16945    * Turn off the polyfill for `progress` events that was created in
16946    * {@link Tech#manualProgressOn}
16947    * Stop manually tracking progress events by clearing the interval that was set in
16948    * {@link Tech#trackProgress}.
16949    */
16952   Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
16953     this.clearInterval(this.progressInterval);
16954   };
16956   /**
16957    * Polyfill the `timeupdate` event for browsers that don't support it.
16958    *
16959    * @see {@link Tech#trackCurrentTime}
16960    */
16963   Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
16964     this.manualTimeUpdates = true;
16966     this.on('play', this.trackCurrentTime);
16967     this.on('pause', this.stopTrackingCurrentTime);
16968   };
16970   /**
16971    * Turn off the polyfill for `timeupdate` events that was created in
16972    * {@link Tech#manualTimeUpdatesOn}
16973    */
16976   Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
16977     this.manualTimeUpdates = false;
16978     this.stopTrackingCurrentTime();
16979     this.off('play', this.trackCurrentTime);
16980     this.off('pause', this.stopTrackingCurrentTime);
16981   };
16983   /**
16984    * Sets up an interval function to track current time and trigger `timeupdate` every
16985    * 250 milliseconds.
16986    *
16987    * @listens Tech#play
16988    * @triggers Tech#timeupdate
16989    */
16992   Tech.prototype.trackCurrentTime = function trackCurrentTime() {
16993     if (this.currentTimeInterval) {
16994       this.stopTrackingCurrentTime();
16995     }
16996     this.currentTimeInterval = this.setInterval(function () {
16997       /**
16998        * Triggered at an interval of 250ms to indicated that time is passing in the video.
16999        *
17000        * @event Tech#timeupdate
17001        * @type {EventTarget~Event}
17002        */
17003       this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17005       // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
17006     }, 250);
17007   };
17009   /**
17010    * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
17011    * `timeupdate` event is no longer triggered.
17012    *
17013    * @listens {Tech#pause}
17014    */
17017   Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
17018     this.clearInterval(this.currentTimeInterval);
17020     // #1002 - if the video ends right before the next timeupdate would happen,
17021     // the progress bar won't make it all the way to the end
17022     this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17023   };
17025   /**
17026    * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
17027    * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
17028    *
17029    * @fires Component#dispose
17030    */
17033   Tech.prototype.dispose = function dispose() {
17035     // clear out all tracks because we can't reuse them between techs
17036     this.clearTracks(['audio', 'video', 'text']);
17038     // Turn off any manual progress or timeupdate tracking
17039     if (this.manualProgress) {
17040       this.manualProgressOff();
17041     }
17043     if (this.manualTimeUpdates) {
17044       this.manualTimeUpdatesOff();
17045     }
17047     _Component.prototype.dispose.call(this);
17048   };
17050   /**
17051    * Clear out a single `TrackList` or an array of `TrackLists` given their names.
17052    *
17053    * > Note: Techs without source handlers should call this between sources for `video`
17054    *         & `audio` tracks. You don't want to use them between tracks!
17055    *
17056    * @param {string[]|string} types
17057    *        TrackList names to clear, valid names are `video`, `audio`, and
17058    *        `text`.
17059    */
17062   Tech.prototype.clearTracks = function clearTracks(types) {
17063     var _this2 = this;
17065     types = [].concat(types);
17066     // clear out all tracks because we can't reuse them between techs
17067     types.forEach(function (type) {
17068       var list = _this2[type + 'Tracks']() || [];
17069       var i = list.length;
17071       while (i--) {
17072         var track = list[i];
17074         if (type === 'text') {
17075           _this2.removeRemoteTextTrack(track);
17076         }
17077         list.removeTrack_(track);
17078       }
17079     });
17080   };
17082   /**
17083    * Remove any TextTracks added via addRemoteTextTrack that are
17084    * flagged for automatic garbage collection
17085    */
17088   Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
17089     var list = this.autoRemoteTextTracks_ || [];
17090     var i = list.length;
17092     while (i--) {
17093       var track = list[i];
17095       this.removeRemoteTextTrack(track);
17096     }
17097   };
17099   /**
17100    * Reset the tech, which will removes all sources and reset the internal readyState.
17101    *
17102    * @abstract
17103    */
17106   Tech.prototype.reset = function reset() {};
17108   /**
17109    * Get or set an error on the Tech.
17110    *
17111    * @param {MediaError} [err]
17112    *        Error to set on the Tech
17113    *
17114    * @return {MediaError|null}
17115    *         The current error object on the tech, or null if there isn't one.
17116    */
17119   Tech.prototype.error = function error(err) {
17120     if (err !== undefined) {
17121       this.error_ = new _mediaError2['default'](err);
17122       this.trigger('error');
17123     }
17124     return this.error_;
17125   };
17127   /**
17128    * Returns the `TimeRange`s that have been played through for the current source.
17129    *
17130    * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
17131    *         It only checks whether the source has played at all or not.
17132    *
17133    * @return {TimeRange}
17134    *         - A single time range if this video has played
17135    *         - An empty set of ranges if not.
17136    */
17139   Tech.prototype.played = function played() {
17140     if (this.hasStarted_) {
17141       return (0, _timeRanges.createTimeRange)(0, 0);
17142     }
17143     return (0, _timeRanges.createTimeRange)();
17144   };
17146   /**
17147    * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
17148    * previously called.
17149    *
17150    * @fires Tech#timeupdate
17151    */
17154   Tech.prototype.setCurrentTime = function setCurrentTime() {
17155     // improve the accuracy of manual timeupdates
17156     if (this.manualTimeUpdates) {
17157       /**
17158        * A manual `timeupdate` event.
17159        *
17160        * @event Tech#timeupdate
17161        * @type {EventTarget~Event}
17162        */
17163       this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17164     }
17165   };
17167   /**
17168    * Turn on listeners for {@link TextTrackList} events. This adds
17169    * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
17170    * `removetrack`.
17171    *
17172    * @fires Tech#texttrackchange
17173    */
17176   Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
17177     var textTrackListChanges = Fn.bind(this, function () {
17178       /**
17179        * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
17180        *
17181        * @event Tech#texttrackchange
17182        * @type {EventTarget~Event}
17183        */
17184       this.trigger('texttrackchange');
17185     });
17187     var tracks = this.textTracks();
17189     if (!tracks) {
17190       return;
17191     }
17193     tracks.addEventListener('removetrack', textTrackListChanges);
17194     tracks.addEventListener('addtrack', textTrackListChanges);
17196     this.on('dispose', Fn.bind(this, function () {
17197       tracks.removeEventListener('removetrack', textTrackListChanges);
17198       tracks.removeEventListener('addtrack', textTrackListChanges);
17199     }));
17200   };
17202   /**
17203    * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
17204    * This adds {@link EventTarget~EventListeners} for `addtrack`, and  `removetrack`.
17205    *
17206    * @fires Tech#audiotrackchange
17207    * @fires Tech#videotrackchange
17208    */
17211   Tech.prototype.initTrackListeners = function initTrackListeners() {
17212     var _this3 = this;
17214     var trackTypes = ['video', 'audio'];
17216     trackTypes.forEach(function (type) {
17217       /**
17218        * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
17219        *
17220        * @event Tech#audiotrackchange
17221        * @type {EventTarget~Event}
17222        */
17224       /**
17225        * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
17226        *
17227        * @event Tech#videotrackchange
17228        * @type {EventTarget~Event}
17229        */
17230       var trackListChanges = function trackListChanges() {
17231         _this3.trigger(type + 'trackchange');
17232       };
17234       var tracks = _this3[type + 'Tracks']();
17236       tracks.addEventListener('removetrack', trackListChanges);
17237       tracks.addEventListener('addtrack', trackListChanges);
17239       _this3.on('dispose', function () {
17240         tracks.removeEventListener('removetrack', trackListChanges);
17241         tracks.removeEventListener('addtrack', trackListChanges);
17242       });
17243     });
17244   };
17246   /**
17247    * Emulate TextTracks using vtt.js if necessary
17248    *
17249    * @fires Tech#vttjsloaded
17250    * @fires Tech#vttjserror
17251    * @fires Tech#texttrackchange
17252    */
17255   Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
17256     var _this4 = this;
17258     if (!_window2['default'].WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) {
17259       (function () {
17260         var script = _document2['default'].createElement('script');
17262         script.src = _this4.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
17263         script.onload = function () {
17264           /**
17265            * Fired when vtt.js is loaded.
17266            *
17267            * @event Tech#vttjsloaded
17268            * @type {EventTarget~Event}
17269            */
17270           _this4.trigger('vttjsloaded');
17271         };
17272         script.onerror = function () {
17273           /**
17274            * Fired when vtt.js was not loaded due to an error
17275            *
17276            * @event Tech#vttjsloaded
17277            * @type {EventTarget~Event}
17278            */
17279           _this4.trigger('vttjserror');
17280         };
17281         _this4.on('dispose', function () {
17282           script.onload = null;
17283           script.onerror = null;
17284         });
17285         // but have not loaded yet and we set it to true before the inject so that
17286         // we don't overwrite the injected window.WebVTT if it loads right away
17287         _window2['default'].WebVTT = true;
17288         _this4.el().parentNode.appendChild(script);
17289       })();
17290     }
17291   };
17293   /**
17294    * Emulate texttracks
17295    *
17296    * @method emulateTextTracks
17297    */
17300   Tech.prototype.emulateTextTracks = function emulateTextTracks() {
17301     var _this5 = this;
17303     var tracks = this.textTracks();
17305     if (!tracks) {
17306       return;
17307     }
17309     this.remoteTextTracks().on('addtrack', function (e) {
17310       _this5.textTracks().addTrack_(e.track);
17311     });
17313     this.remoteTextTracks().on('removetrack', function (e) {
17314       _this5.textTracks().removeTrack_(e.track);
17315     });
17317     // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
17318     // signals that the Tech is ready at which point Tech.el_ is part of the DOM
17319     // before inserting the WebVTT script
17320     this.on('ready', this.addWebVttScript_);
17322     var updateDisplay = function updateDisplay() {
17323       return _this5.trigger('texttrackchange');
17324     };
17325     var textTracksChanges = function textTracksChanges() {
17326       updateDisplay();
17328       for (var i = 0; i < tracks.length; i++) {
17329         var track = tracks[i];
17331         track.removeEventListener('cuechange', updateDisplay);
17332         if (track.mode === 'showing') {
17333           track.addEventListener('cuechange', updateDisplay);
17334         }
17335       }
17336     };
17338     textTracksChanges();
17339     tracks.addEventListener('change', textTracksChanges);
17341     this.on('dispose', function () {
17342       tracks.removeEventListener('change', textTracksChanges);
17343     });
17344   };
17346   /**
17347    * Get the `Tech`s {@link VideoTrackList}.
17348    *
17349    * @return {VideoTrackList}
17350    *          The video track list that the Tech is currently using.
17351    */
17354   Tech.prototype.videoTracks = function videoTracks() {
17355     this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
17356     return this.videoTracks_;
17357   };
17359   /**
17360    * Get the `Tech`s {@link AudioTrackList}.
17361    *
17362    * @return {AudioTrackList}
17363    *          The audio track list that the Tech is currently using.
17364    */
17367   Tech.prototype.audioTracks = function audioTracks() {
17368     this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
17369     return this.audioTracks_;
17370   };
17372   /**
17373    * Get the `Tech`s {@link TextTrackList}.
17374    *
17375    * @return {TextTrackList}
17376    *          The text track list that the Tech is currently using.
17377    */
17380   Tech.prototype.textTracks = function textTracks() {
17381     this.textTracks_ = this.textTracks_ || new _textTrackList2['default']();
17382     return this.textTracks_;
17383   };
17385   /**
17386    * Get the `Tech`s remote {@link TextTrackList}, which is created from elements
17387    * that were added to the DOM.
17388    *
17389    * @return {TextTrackList}
17390    *          The remote text track list that the Tech is currently using.
17391    */
17394   Tech.prototype.remoteTextTracks = function remoteTextTracks() {
17395     this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default']();
17396     return this.remoteTextTracks_;
17397   };
17399   /**
17400    * Get The `Tech`s  {HTMLTrackElementList}, which are the elements in the DOM that are
17401    * being used as TextTracks.
17402    *
17403    * @return {HTMLTrackElementList}
17404    *          The current HTML track elements that exist for the tech.
17405    */
17408   Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
17409     this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default']();
17410     return this.remoteTextTrackEls_;
17411   };
17413   /**
17414    * Create and returns a remote {@link TextTrack} object.
17415    *
17416    * @param {string} kind
17417    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
17418    *
17419    * @param {string} [label]
17420    *        Label to identify the text track
17421    *
17422    * @param {string} [language]
17423    *        Two letter language abbreviation
17424    *
17425    * @return {TextTrack}
17426    *         The TextTrack that gets created.
17427    */
17430   Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
17431     if (!kind) {
17432       throw new Error('TextTrack kind is required but was not provided');
17433     }
17435     return createTrackHelper(this, kind, label, language);
17436   };
17438   /**
17439    * Create an emulated TextTrack for use by addRemoteTextTrack
17440    *
17441    * This is intended to be overridden by classes that inherit from
17442    * Tech in order to create native or custom TextTracks.
17443    *
17444    * @param {Object} options
17445    *        The object should contain the options to initialize the TextTrack with.
17446    *
17447    * @param {string} [options.kind]
17448    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
17449    *
17450    * @param {string} [options.label].
17451    *        Label to identify the text track
17452    *
17453    * @param {string} [options.language]
17454    *        Two letter language abbreviation.
17455    *
17456    * @return {HTMLTrackElement}
17457    *         The track element that gets created.
17458    */
17461   Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
17462     var track = (0, _mergeOptions2['default'])(options, {
17463       tech: this
17464     });
17466     return new _htmlTrackElement2['default'](track);
17467   };
17469   /**
17470    * Creates a remote text track object and returns an html track element.
17471    *
17472    * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
17473    *
17474    * @param {Object} options
17475    *        See {@link Tech#createRemoteTextTrack} for more detailed properties.
17476    *
17477    * @param {boolean} [manualCleanup=true]
17478    *        - When false: the TextTrack will be automatically removed from the video
17479    *          element whenever the source changes
17480    *        - When True: The TextTrack will have to be cleaned up manually
17481    *
17482    * @return {HTMLTrackElement}
17483    *         An Html Track Element.
17484    *
17485    * @deprecated The default functionality for this function will be equivalent
17486    *             to "manualCleanup=false" in the future. The manualCleanup parameter will
17487    *             also be removed.
17488    */
17491   Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
17492     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
17493     var manualCleanup = arguments[1];
17495     var htmlTrackElement = this.createRemoteTextTrack(options);
17497     if (manualCleanup !== true && manualCleanup !== false) {
17498       // deprecation warning
17499       _log2['default'].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js');
17500       manualCleanup = true;
17501     }
17503     // store HTMLTrackElement and TextTrack to remote list
17504     this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
17505     this.remoteTextTracks().addTrack_(htmlTrackElement.track);
17507     if (manualCleanup !== true) {
17508       // create the TextTrackList if it doesn't exist
17509       this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track);
17510     }
17512     return htmlTrackElement;
17513   };
17515   /**
17516    * Remove a remote text track from the remote `TextTrackList`.
17517    *
17518    * @param {TextTrack} track
17519    *        `TextTrack` to remove from the `TextTrackList`
17520    */
17523   Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
17524     var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
17526     // remove HTMLTrackElement and TextTrack from remote list
17527     this.remoteTextTrackEls().removeTrackElement_(trackElement);
17528     this.remoteTextTracks().removeTrack_(track);
17529     this.autoRemoteTextTracks_.removeTrack_(track);
17530   };
17532   /**
17533    * A method to set a poster from a `Tech`.
17534    *
17535    * @abstract
17536    */
17539   Tech.prototype.setPoster = function setPoster() {};
17541   /*
17542    * Check if the tech can support the given mime-type.
17543    *
17544    * The base tech does not support any type, but source handlers might
17545    * overwrite this.
17546    *
17547    * @param  {string} type
17548    *         The mimetype to check for support
17549    *
17550    * @return {string}
17551    *         'probably', 'maybe', or empty string
17552    *
17553    * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
17554    *
17555    * @abstract
17556    */
17559   Tech.prototype.canPlayType = function canPlayType() {
17560     return '';
17561   };
17563   /*
17564    * Return whether the argument is a Tech or not.
17565    * Can be passed either a Class like `Html5` or a instance like `player.tech_`
17566    *
17567    * @param {Object} component
17568    *        The item to check
17569    *
17570    * @return {boolean}
17571    *         Whether it is a tech or not
17572    *         - True if it is a tech
17573    *         - False if it is not
17574    */
17577   Tech.isTech = function isTech(component) {
17578     return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
17579   };
17581   /**
17582    * Registers a `Tech` into a shared list for videojs.
17583    *
17584    * @param {string} name
17585    *        Name of the `Tech` to register.
17586    *
17587    * @param {Object} tech
17588    *        The `Tech` class to register.
17589    */
17592   Tech.registerTech = function registerTech(name, tech) {
17593     if (!Tech.techs_) {
17594       Tech.techs_ = {};
17595     }
17597     if (!Tech.isTech(tech)) {
17598       throw new Error('Tech ' + name + ' must be a Tech');
17599     }
17601     Tech.techs_[name] = tech;
17602     return tech;
17603   };
17605   /**
17606    * Get a `Tech` from the shared list by name.
17607    *
17608    * @param {string} name
17609    *        Name of the component to get
17610    *
17611    * @return {Tech|undefined}
17612    *         The `Tech` or undefined if there was no tech with the name requested.
17613    */
17616   Tech.getTech = function getTech(name) {
17617     if (Tech.techs_ && Tech.techs_[name]) {
17618       return Tech.techs_[name];
17619     }
17621     if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
17622       _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
17623       return _window2['default'].videojs[name];
17624     }
17625   };
17627   return Tech;
17628 }(_component2['default']);
17631  * List of associated text tracks.
17633  * @type {TextTrackList}
17634  * @private
17635  */
17638 Tech.prototype.textTracks_; // eslint-disable-line
17641  * List of associated audio tracks.
17643  * @type {AudioTrackList}
17644  * @private
17645  */
17646 Tech.prototype.audioTracks_; // eslint-disable-line
17649  * List of associated video tracks.
17651  * @type {VideoTrackList}
17652  * @private
17653  */
17654 Tech.prototype.videoTracks_; // eslint-disable-line
17657  * Boolean indicating whether the `Tech` supports volume control.
17659  * @type {boolean}
17660  * @default
17661  */
17662 Tech.prototype.featuresVolumeControl = true;
17665  * Boolean indicating whether the `Tech` support fullscreen resize control.
17666  * Resizing plugins using request fullscreen reloads the plugin
17668  * @type {boolean}
17669  * @default
17670  */
17671 Tech.prototype.featuresFullscreenResize = false;
17674  * Boolean indicating whether the `Tech` supports changing the speed at which the video
17675  * plays. Examples:
17676  *   - Set player to play 2x (twice) as fast
17677  *   - Set player to play 0.5x (half) as fast
17679  * @type {boolean}
17680  * @default
17681  */
17682 Tech.prototype.featuresPlaybackRate = false;
17685  * Boolean indicating whether the `Tech` supports the `progress` event. This is currently
17686  * not triggered by video-js-swf. This will be used to determine if
17687  * {@link Tech#manualProgressOn} should be called.
17689  * @type {boolean}
17690  * @default
17691  */
17692 Tech.prototype.featuresProgressEvents = false;
17695  * Boolean indicating whether the `Tech` supports the `timeupdate` event. This is currently
17696  * not triggered by video-js-swf. This will be used to determine if
17697  * {@link Tech#manualTimeUpdates} should be called.
17699  * @type {boolean}
17700  * @default
17701  */
17702 Tech.prototype.featuresTimeupdateEvents = false;
17705  * Boolean indicating whether the `Tech` supports the native `TextTrack`s.
17706  * This will help us integrate with native `TextTrack`s if the browser supports them.
17708  * @type {boolean}
17709  * @default
17710  */
17711 Tech.prototype.featuresNativeTextTracks = false;
17714  * A functional mixin for techs that want to use the Source Handler pattern.
17715  * Source handlers are scripts for handling specific formats.
17716  * The source handler pattern is used for adaptive formats (HLS, DASH) that
17717  * manually load video data and feed it into a Source Buffer (Media Source Extensions)
17718  * Example: `Tech.withSourceHandlers.call(MyTech);`
17720  * @param {Tech} _Tech
17721  *        The tech to add source handler functions to.
17723  * @mixes Tech~SourceHandlerAdditions
17724  */
17725 Tech.withSourceHandlers = function (_Tech) {
17727   /**
17728    * Register a source handler
17729    *
17730    * @param {Function} handler
17731    *        The source handler class
17732    *
17733    * @param {number} [index]
17734    *        Register it at the following index
17735    */
17736   _Tech.registerSourceHandler = function (handler, index) {
17737     var handlers = _Tech.sourceHandlers;
17739     if (!handlers) {
17740       handlers = _Tech.sourceHandlers = [];
17741     }
17743     if (index === undefined) {
17744       // add to the end of the list
17745       index = handlers.length;
17746     }
17748     handlers.splice(index, 0, handler);
17749   };
17751   /**
17752    * Check if the tech can support the given type. Also checks the
17753    * Techs sourceHandlers.
17754    *
17755    * @param {string} type
17756    *         The mimetype to check.
17757    *
17758    * @return {string}
17759    *         'probably', 'maybe', or '' (empty string)
17760    */
17761   _Tech.canPlayType = function (type) {
17762     var handlers = _Tech.sourceHandlers || [];
17763     var can = void 0;
17765     for (var i = 0; i < handlers.length; i++) {
17766       can = handlers[i].canPlayType(type);
17768       if (can) {
17769         return can;
17770       }
17771     }
17773     return '';
17774   };
17776   /**
17777    * Returns the first source handler that supports the source.
17778    *
17779    * TODO: Answer question: should 'probably' be prioritized over 'maybe'
17780    *
17781    * @param {Tech~SourceObject} source
17782    *        The source object
17783    *
17784    * @param {Object} options
17785    *        The options passed to the tech
17786    *
17787    * @return {SourceHandler|null}
17788    *          The first source handler that supports the source or null if
17789    *          no SourceHandler supports the source
17790    */
17791   _Tech.selectSourceHandler = function (source, options) {
17792     var handlers = _Tech.sourceHandlers || [];
17793     var can = void 0;
17795     for (var i = 0; i < handlers.length; i++) {
17796       can = handlers[i].canHandleSource(source, options);
17798       if (can) {
17799         return handlers[i];
17800       }
17801     }
17803     return null;
17804   };
17806   /**
17807    * Check if the tech can support the given source.
17808    *
17809    * @param {Tech~SourceObject} srcObj
17810    *        The source object
17811    *
17812    * @param {Object} options
17813    *        The options passed to the tech
17814    *
17815    * @return {string}
17816    *         'probably', 'maybe', or '' (empty string)
17817    */
17818   _Tech.canPlaySource = function (srcObj, options) {
17819     var sh = _Tech.selectSourceHandler(srcObj, options);
17821     if (sh) {
17822       return sh.canHandleSource(srcObj, options);
17823     }
17825     return '';
17826   };
17828   /**
17829    * When using a source handler, prefer its implementation of
17830    * any function normally provided by the tech.
17831    */
17832   var deferrable = ['seekable', 'duration'];
17834   /**
17835    * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
17836    * function if it exists, with a fallback to the Techs seekable function.
17837    *
17838    * @method _Tech.seekable
17839    */
17841   /**
17842    * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
17843    * function if it exists, otherwise it will fallback to the techs duration function.
17844    *
17845    * @method _Tech.duration
17846    */
17848   deferrable.forEach(function (fnName) {
17849     var originalFn = this[fnName];
17851     if (typeof originalFn !== 'function') {
17852       return;
17853     }
17855     this[fnName] = function () {
17856       if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
17857         return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
17858       }
17859       return originalFn.apply(this, arguments);
17860     };
17861   }, _Tech.prototype);
17863   /**
17864    * Create a function for setting the source using a source object
17865    * and source handlers.
17866    * Should never be called unless a source handler was found.
17867    *
17868    * @param {Tech~SourceObject} source
17869    *        A source object with src and type keys
17870    *
17871    * @return {Tech}
17872    *         Returns itself; this method is chainable
17873    */
17874   _Tech.prototype.setSource = function (source) {
17875     var sh = _Tech.selectSourceHandler(source, this.options_);
17877     if (!sh) {
17878       // Fall back to a native source handler when unsupported sources are
17879       // deliberately set
17880       if (_Tech.nativeSourceHandler) {
17881         sh = _Tech.nativeSourceHandler;
17882       } else {
17883         _log2['default'].error('No source handler found for the current source.');
17884       }
17885     }
17887     // Dispose any existing source handler
17888     this.disposeSourceHandler();
17889     this.off('dispose', this.disposeSourceHandler);
17891     if (sh !== _Tech.nativeSourceHandler) {
17892       this.currentSource_ = source;
17894       // Catch if someone replaced the src without calling setSource.
17895       // If they do, set currentSource_ to null and dispose our source handler.
17896       this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17897       this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17898       this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17899     }
17901     this.sourceHandler_ = sh.handleSource(source, this, this.options_);
17902     this.on('dispose', this.disposeSourceHandler);
17904     return this;
17905   };
17907   /**
17908    * Called once for the first loadstart of a video.
17909    *
17910    * @listens Tech#loadstart
17911    */
17912   _Tech.prototype.firstLoadStartListener_ = function () {
17913     this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17914   };
17916   // On successive loadstarts when setSource has not been called again
17917   /**
17918    * Called after the first loadstart for a video occurs.
17919    *
17920    * @listens Tech#loadstart
17921    */
17922   _Tech.prototype.successiveLoadStartListener_ = function () {
17923     this.disposeSourceHandler();
17924     this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17925   };
17927   /**
17928    * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
17929    *
17930    * @listens Tech#dispose
17931    */
17932   _Tech.prototype.disposeSourceHandler = function () {
17933     // if we have a source and get another one
17934     // then we are loading something new
17935     // than clear all of our current tracks
17936     if (this.currentSource_) {
17937       this.clearTracks(['audio', 'video']);
17938       this.currentSource_ = null;
17939     }
17941     // always clean up auto-text tracks
17942     this.cleanupAutoTextTracks();
17944     if (this.sourceHandler_) {
17945       this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17946       this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17948       if (this.sourceHandler_.dispose) {
17949         this.sourceHandler_.dispose();
17950       }
17952       this.sourceHandler_ = null;
17953     }
17954   };
17957 _component2['default'].registerComponent('Tech', Tech);
17958 // Old name for Tech
17959 // @deprecated
17960 _component2['default'].registerComponent('MediaTechController', Tech);
17961 Tech.registerTech('Tech', Tech);
17962 exports['default'] = Tech;
17964 },{"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"90":90,"94":94,"95":95}],63:[function(_dereq_,module,exports){
17965 'use strict';
17967 exports.__esModule = true;
17969 var _trackList = _dereq_(74);
17971 var _trackList2 = _interopRequireDefault(_trackList);
17973 var _browser = _dereq_(78);
17975 var browser = _interopRequireWildcard(_browser);
17977 var _document = _dereq_(94);
17979 var _document2 = _interopRequireDefault(_document);
17981 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
17983 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17985 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
17987 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
17989 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
17990                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-list.js
17991                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
17995  * Anywhere we call this function we diverge from the spec
17996  * as we only support one enabled audiotrack at a time
17998  * @param {AudioTrackList} list
17999  *        list to work on
18001  * @param {AudioTrack} track
18002  *        The track to skip
18004  * @private
18005  */
18006 var disableOthers = function disableOthers(list, track) {
18007   for (var i = 0; i < list.length; i++) {
18008     if (track.id === list[i].id) {
18009       continue;
18010     }
18011     // another audio track is enabled, disable it
18012     list[i].enabled = false;
18013   }
18017  * The current list of {@link AudioTrack} for a media file.
18019  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
18020  * @extends TrackList
18021  */
18023 var AudioTrackList = function (_TrackList) {
18024   _inherits(AudioTrackList, _TrackList);
18026   /**
18027    * Create an instance of this class.
18028    *
18029    * @param {AudioTrack[]} [tracks=[]]
18030    *        A list of `AudioTrack` to instantiate the list with.
18031    */
18032   function AudioTrackList() {
18033     var _this, _ret;
18035     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18037     _classCallCheck(this, AudioTrackList);
18039     var list = void 0;
18041     // make sure only 1 track is enabled
18042     // sorted from last index to first index
18043     for (var i = tracks.length - 1; i >= 0; i--) {
18044       if (tracks[i].enabled) {
18045         disableOthers(tracks, tracks[i]);
18046         break;
18047       }
18048     }
18050     // IE8 forces us to implement inheritance ourselves
18051     // as it does not support Object.defineProperty properly
18052     if (browser.IS_IE8) {
18053       list = _document2['default'].createElement('custom');
18054       for (var prop in _trackList2['default'].prototype) {
18055         if (prop !== 'constructor') {
18056           list[prop] = _trackList2['default'].prototype[prop];
18057         }
18058       }
18059       for (var _prop in AudioTrackList.prototype) {
18060         if (_prop !== 'constructor') {
18061           list[_prop] = AudioTrackList.prototype[_prop];
18062         }
18063       }
18064     }
18066     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
18067     list.changing_ = false;
18069     return _ret = list, _possibleConstructorReturn(_this, _ret);
18070   }
18072   /**
18073    * Add an {@link AudioTrack} to the `AudioTrackList`.
18074    *
18075    * @param {AudioTrack} track
18076    *        The AudioTrack to add to the list
18077    *
18078    * @fires Track#addtrack
18079    * @private
18080    */
18083   AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
18084     var _this2 = this;
18086     if (track.enabled) {
18087       disableOthers(this, track);
18088     }
18090     _TrackList.prototype.addTrack_.call(this, track);
18091     // native tracks don't have this
18092     if (!track.addEventListener) {
18093       return;
18094     }
18096     /**
18097      * @listens AudioTrack#enabledchange
18098      * @fires TrackList#change
18099      */
18100     track.addEventListener('enabledchange', function () {
18101       // when we are disabling other tracks (since we don't support
18102       // more than one track at a time) we will set changing_
18103       // to true so that we don't trigger additional change events
18104       if (_this2.changing_) {
18105         return;
18106       }
18107       _this2.changing_ = true;
18108       disableOthers(_this2, track);
18109       _this2.changing_ = false;
18110       _this2.trigger('change');
18111     });
18112   };
18114   /**
18115    * Add an {@link AudioTrack} to the `AudioTrackList`.
18116    *
18117    * @param {AudioTrack} track
18118    *        The AudioTrack to add to the list
18119    *
18120    * @fires Track#addtrack
18121    */
18124   AudioTrackList.prototype.addTrack = function addTrack(track) {
18125     this.addTrack_(track);
18126   };
18128   /**
18129    * Remove an {@link AudioTrack} from the `AudioTrackList`.
18130    *
18131    * @param {AudioTrack} track
18132    *        The AudioTrack to remove from the list
18133    *
18134    * @fires Track#removetrack
18135    */
18138   AudioTrackList.prototype.removeTrack = function removeTrack(track) {
18139     _TrackList.prototype.removeTrack_.call(this, track);
18140   };
18142   return AudioTrackList;
18143 }(_trackList2['default']);
18145 exports['default'] = AudioTrackList;
18147 },{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){
18148 'use strict';
18150 exports.__esModule = true;
18152 var _trackEnums = _dereq_(73);
18154 var _track = _dereq_(75);
18156 var _track2 = _interopRequireDefault(_track);
18158 var _mergeOptions = _dereq_(87);
18160 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
18162 var _browser = _dereq_(78);
18164 var browser = _interopRequireWildcard(_browser);
18166 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18168 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18170 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18172 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18174 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18177  * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
18178  * only one `AudioTrack` in the list will be enabled at a time.
18180  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
18181  * @extends Track
18182  */
18183 var AudioTrack = function (_Track) {
18184   _inherits(AudioTrack, _Track);
18186   /**
18187    * Create an instance of this class.
18188    *
18189    * @param {Object} [options={}]
18190    *        Object of option names and values
18191    *
18192    * @param {AudioTrack~Kind} [options.kind='']
18193    *        A valid audio track kind
18194    *
18195    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18196    *        A unique id for this AudioTrack.
18197    *
18198    * @param {string} [options.label='']
18199    *        The menu label for this track.
18200    *
18201    * @param {string} [options.language='']
18202    *        A valid two character language code.
18203    *
18204    * @param {boolean} [options.enabled]
18205    *        If this track is the one that is currently playing. If this track is part of
18206    *        an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
18207    */
18208   function AudioTrack() {
18209     var _this, _ret;
18211     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18213     _classCallCheck(this, AudioTrack);
18215     var settings = (0, _mergeOptions2['default'])(options, {
18216       kind: _trackEnums.AudioTrackKind[options.kind] || ''
18217     });
18218     // on IE8 this will be a document element
18219     // for every other browser this will be a normal object
18220     var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
18221     var enabled = false;
18223     if (browser.IS_IE8) {
18224       for (var prop in AudioTrack.prototype) {
18225         if (prop !== 'constructor') {
18226           track[prop] = AudioTrack.prototype[prop];
18227         }
18228       }
18229     }
18230     /**
18231      * @member {boolean} enabled
18232      *         If this `AudioTrack` is enabled or not. When setting this will
18233      *         fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
18234      *
18235      * @fires VideoTrack#selectedchange
18236      */
18237     Object.defineProperty(track, 'enabled', {
18238       get: function get() {
18239         return enabled;
18240       },
18241       set: function set(newEnabled) {
18242         // an invalid or unchanged value
18243         if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
18244           return;
18245         }
18246         enabled = newEnabled;
18248         /**
18249          * An event that fires when enabled changes on this track. This allows
18250          * the AudioTrackList that holds this track to act accordingly.
18251          *
18252          * > Note: This is not part of the spec! Native tracks will do
18253          *         this internally without an event.
18254          *
18255          * @event AudioTrack#enabledchange
18256          * @type {EventTarget~Event}
18257          */
18258         this.trigger('enabledchange');
18259       }
18260     });
18262     // if the user sets this track to selected then
18263     // set selected to that true value otherwise
18264     // we keep it false
18265     if (settings.enabled) {
18266       track.enabled = settings.enabled;
18267     }
18268     track.loaded_ = true;
18270     return _ret = track, _possibleConstructorReturn(_this, _ret);
18271   }
18273   return AudioTrack;
18274 }(_track2['default']);
18276 exports['default'] = AudioTrack;
18278 },{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){
18279 'use strict';
18281 exports.__esModule = true;
18283 var _browser = _dereq_(78);
18285 var browser = _interopRequireWildcard(_browser);
18287 var _document = _dereq_(94);
18289 var _document2 = _interopRequireDefault(_document);
18291 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18293 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18295 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18296                                                                                                                                                            * @file html-track-element-list.js
18297                                                                                                                                                            */
18300  * The current list of {@link HtmlTrackElement}s.
18301  */
18302 var HtmlTrackElementList = function () {
18304   /**
18305    * Create an instance of this class.
18306    *
18307    * @param {HtmlTrackElement[]} [tracks=[]]
18308    *        A list of `HtmlTrackElement` to instantiate the list with.
18309    */
18310   function HtmlTrackElementList() {
18311     var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18313     _classCallCheck(this, HtmlTrackElementList);
18315     var list = this; // eslint-disable-line
18317     if (browser.IS_IE8) {
18318       list = _document2['default'].createElement('custom');
18320       for (var prop in HtmlTrackElementList.prototype) {
18321         if (prop !== 'constructor') {
18322           list[prop] = HtmlTrackElementList.prototype[prop];
18323         }
18324       }
18325     }
18327     list.trackElements_ = [];
18329     /**
18330      * @member {number} length
18331      *         The current number of `Track`s in the this Trackist.
18332      */
18333     Object.defineProperty(list, 'length', {
18334       get: function get() {
18335         return this.trackElements_.length;
18336       }
18337     });
18339     for (var i = 0, length = trackElements.length; i < length; i++) {
18340       list.addTrackElement_(trackElements[i]);
18341     }
18343     if (browser.IS_IE8) {
18344       return list;
18345     }
18346   }
18348   /**
18349    * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
18350    *
18351    * @param {HtmlTrackElement} trackElement
18352    *        The track element to add to the list.
18353    *
18354    * @private
18355    */
18358   HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
18359     var index = this.trackElements_.length;
18361     if (!('' + index in this)) {
18362       Object.defineProperty(this, index, {
18363         get: function get() {
18364           return this.trackElements_[index];
18365         }
18366       });
18367     }
18369     // Do not add duplicate elements
18370     if (this.trackElements_.indexOf(trackElement) === -1) {
18371       this.trackElements_.push(trackElement);
18372     }
18373   };
18375   /**
18376    * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
18377    * {@link TextTrack}.
18378    *
18379    * @param {TextTrack} track
18380    *        The track associated with a track element.
18381    *
18382    * @return {HtmlTrackElement|undefined}
18383    *         The track element that was found or undefined.
18384    *
18385    * @private
18386    */
18389   HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
18390     var trackElement_ = void 0;
18392     for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18393       if (track === this.trackElements_[i].track) {
18394         trackElement_ = this.trackElements_[i];
18396         break;
18397       }
18398     }
18400     return trackElement_;
18401   };
18403   /**
18404    * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
18405    *
18406    * @param {HtmlTrackElement} trackElement
18407    *        The track element to remove from the list.
18408    *
18409    * @private
18410    */
18413   HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
18414     for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18415       if (trackElement === this.trackElements_[i]) {
18416         this.trackElements_.splice(i, 1);
18418         break;
18419       }
18420     }
18421   };
18423   return HtmlTrackElementList;
18424 }();
18426 exports['default'] = HtmlTrackElementList;
18428 },{"78":78,"94":94}],66:[function(_dereq_,module,exports){
18429 'use strict';
18431 exports.__esModule = true;
18433 var _browser = _dereq_(78);
18435 var browser = _interopRequireWildcard(_browser);
18437 var _document = _dereq_(94);
18439 var _document2 = _interopRequireDefault(_document);
18441 var _eventTarget = _dereq_(42);
18443 var _eventTarget2 = _interopRequireDefault(_eventTarget);
18445 var _textTrack = _dereq_(72);
18447 var _textTrack2 = _interopRequireDefault(_textTrack);
18449 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18451 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18453 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18455 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18457 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
18458                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file html-track-element.js
18459                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
18462  * @typedef {HTMLTrackElement~ReadyState}
18463  * @enum {number}
18464  */
18465 var NONE = 0;
18466 var LOADING = 1;
18467 var LOADED = 2;
18468 var ERROR = 3;
18471  * A single track represented in the DOM.
18473  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18474  * @extends EventTarget
18475  */
18477 var HTMLTrackElement = function (_EventTarget) {
18478   _inherits(HTMLTrackElement, _EventTarget);
18480   /**
18481    * Create an instance of this class.
18482    *
18483    * @param {Object} options={}
18484    *        Object of option names and values
18485    *
18486    * @param {Tech} options.tech
18487    *        A reference to the tech that owns this HTMLTrackElement.
18488    *
18489    * @param {TextTrack~Kind} [options.kind='subtitles']
18490    *        A valid text track kind.
18491    *
18492    * @param {TextTrack~Mode} [options.mode='disabled']
18493    *        A valid text track mode.
18494    *
18495    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18496    *        A unique id for this TextTrack.
18497    *
18498    * @param {string} [options.label='']
18499    *        The menu label for this track.
18500    *
18501    * @param {string} [options.language='']
18502    *        A valid two character language code.
18503    *
18504    * @param {string} [options.srclang='']
18505    *        A valid two character language code. An alternative, but deprioritized
18506    *        version of `options.language`
18507    *
18508    * @param {string} [options.src]
18509    *        A url to TextTrack cues.
18510    *
18511    * @param {boolean} [options.default]
18512    *        If this track should default to on or off.
18513    */
18514   function HTMLTrackElement() {
18515     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18517     _classCallCheck(this, HTMLTrackElement);
18519     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
18521     var readyState = void 0;
18522     var trackElement = _this; // eslint-disable-line
18524     if (browser.IS_IE8) {
18525       trackElement = _document2['default'].createElement('custom');
18527       for (var prop in HTMLTrackElement.prototype) {
18528         if (prop !== 'constructor') {
18529           trackElement[prop] = HTMLTrackElement.prototype[prop];
18530         }
18531       }
18532     }
18534     var track = new _textTrack2['default'](options);
18536     trackElement.kind = track.kind;
18537     trackElement.src = track.src;
18538     trackElement.srclang = track.language;
18539     trackElement.label = track.label;
18540     trackElement['default'] = track['default'];
18542     /**
18543      * @member {HTMLTrackElement~ReadyState} readyState
18544      *         The current ready state of the track element.
18545      */
18546     Object.defineProperty(trackElement, 'readyState', {
18547       get: function get() {
18548         return readyState;
18549       }
18550     });
18552     /**
18553      * @member {TextTrack} track
18554      *         The underlying TextTrack object.
18555      */
18556     Object.defineProperty(trackElement, 'track', {
18557       get: function get() {
18558         return track;
18559       }
18560     });
18562     readyState = NONE;
18564     /**
18565      * @listens TextTrack#loadeddata
18566      * @fires HTMLTrackElement#load
18567      */
18568     track.addEventListener('loadeddata', function () {
18569       readyState = LOADED;
18571       trackElement.trigger({
18572         type: 'load',
18573         target: trackElement
18574       });
18575     });
18577     if (browser.IS_IE8) {
18578       var _ret;
18580       return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
18581     }
18582     return _this;
18583   }
18585   return HTMLTrackElement;
18586 }(_eventTarget2['default']);
18588 HTMLTrackElement.prototype.allowedEvents_ = {
18589   load: 'load'
18592 HTMLTrackElement.NONE = NONE;
18593 HTMLTrackElement.LOADING = LOADING;
18594 HTMLTrackElement.LOADED = LOADED;
18595 HTMLTrackElement.ERROR = ERROR;
18597 exports['default'] = HTMLTrackElement;
18599 },{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){
18600 'use strict';
18602 exports.__esModule = true;
18604 var _browser = _dereq_(78);
18606 var browser = _interopRequireWildcard(_browser);
18608 var _document = _dereq_(94);
18610 var _document2 = _interopRequireDefault(_document);
18612 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18614 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18616 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18617                                                                                                                                                            * @file text-track-cue-list.js
18618                                                                                                                                                            */
18622  * @typedef {Object} TextTrackCue
18624  * @property {string} id
18625  *           The unique id for this text track cue
18627  * @property {number} startTime
18628  *           The start time for this text track cue
18630  * @property {number} endTime
18631  *           The end time for this text track cue
18633  * @property {boolean} pauseOnExit
18634  *           Pause when the end time is reached if true.
18636  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
18637  */
18640  * A List of TextTrackCues.
18642  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
18643  */
18644 var TextTrackCueList = function () {
18646   /**
18647    * Create an instance of this class..
18648    *
18649    * @param {Array} cues
18650    *        A list of cues to be initialized with
18651    */
18652   function TextTrackCueList(cues) {
18653     _classCallCheck(this, TextTrackCueList);
18655     var list = this; // eslint-disable-line
18657     if (browser.IS_IE8) {
18658       list = _document2['default'].createElement('custom');
18660       for (var prop in TextTrackCueList.prototype) {
18661         if (prop !== 'constructor') {
18662           list[prop] = TextTrackCueList.prototype[prop];
18663         }
18664       }
18665     }
18667     TextTrackCueList.prototype.setCues_.call(list, cues);
18669     /**
18670      * @member {number} length
18671      *         The current number of `TextTrackCue`s in the TextTrackCueList.
18672      */
18673     Object.defineProperty(list, 'length', {
18674       get: function get() {
18675         return this.length_;
18676       }
18677     });
18679     if (browser.IS_IE8) {
18680       return list;
18681     }
18682   }
18684   /**
18685    * A setter for cues in this list. Creates getters
18686    * an an index for the cues.
18687    *
18688    * @param {Array} cues
18689    *        An array of cues to set
18690    *
18691    * @private
18692    */
18695   TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
18696     var oldLength = this.length || 0;
18697     var i = 0;
18698     var l = cues.length;
18700     this.cues_ = cues;
18701     this.length_ = cues.length;
18703     var defineProp = function defineProp(index) {
18704       if (!('' + index in this)) {
18705         Object.defineProperty(this, '' + index, {
18706           get: function get() {
18707             return this.cues_[index];
18708           }
18709         });
18710       }
18711     };
18713     if (oldLength < l) {
18714       i = oldLength;
18716       for (; i < l; i++) {
18717         defineProp.call(this, i);
18718       }
18719     }
18720   };
18722   /**
18723    * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
18724    *
18725    * @param {string} id
18726    *        The id of the cue that should be searched for.
18727    *
18728    * @return {TextTrackCue|null}
18729    *         A single cue or null if none was found.
18730    */
18733   TextTrackCueList.prototype.getCueById = function getCueById(id) {
18734     var result = null;
18736     for (var i = 0, l = this.length; i < l; i++) {
18737       var cue = this[i];
18739       if (cue.id === id) {
18740         result = cue;
18741         break;
18742       }
18743     }
18745     return result;
18746   };
18748   return TextTrackCueList;
18749 }();
18751 exports['default'] = TextTrackCueList;
18753 },{"78":78,"94":94}],68:[function(_dereq_,module,exports){
18754 'use strict';
18756 exports.__esModule = true;
18758 var _component = _dereq_(5);
18760 var _component2 = _interopRequireDefault(_component);
18762 var _fn = _dereq_(83);
18764 var Fn = _interopRequireWildcard(_fn);
18766 var _window = _dereq_(95);
18768 var _window2 = _interopRequireDefault(_window);
18770 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18772 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18774 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18776 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18778 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
18779                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-display.js
18780                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
18783 var darkGray = '#222';
18784 var lightGray = '#ccc';
18785 var fontMap = {
18786   monospace: 'monospace',
18787   sansSerif: 'sans-serif',
18788   serif: 'serif',
18789   monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
18790   monospaceSerif: '"Courier New", monospace',
18791   proportionalSansSerif: 'sans-serif',
18792   proportionalSerif: 'serif',
18793   casual: '"Comic Sans MS", Impact, fantasy',
18794   script: '"Monotype Corsiva", cursive',
18795   smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
18799  * Construct an rgba color from a given hex color code.
18801  * @param {number} color
18802  *        Hex number for color, like #f0e.
18804  * @param {number} opacity
18805  *        Value for opacity, 0.0 - 1.0.
18807  * @return {string}
18808  *         The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
18810  * @private
18811  */
18812 function constructColor(color, opacity) {
18813   return 'rgba(' +
18814   // color looks like "#f0e"
18815   parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
18819  * Try to update the style of a DOM element. Some style changes will throw an error,
18820  * particularly in IE8. Those should be noops.
18822  * @param {Element} el
18823  *        The DOM element to be styled.
18825  * @param {string} style
18826  *        The CSS property on the element that should be styled.
18828  * @param {string} rule
18829  *        The style rule that should be applied to the property.
18830  */
18831 function tryUpdateStyle(el, style, rule) {
18832   try {
18833     el.style[style] = rule;
18834   } catch (e) {
18836     // Satisfies linter.
18837     return;
18838   }
18842  * The component for displaying text track cues.
18844  * @extends Component
18845  */
18847 var TextTrackDisplay = function (_Component) {
18848   _inherits(TextTrackDisplay, _Component);
18850   /**
18851    * Creates an instance of this class.
18852    *
18853    * @param {Player} player
18854    *        The `Player` that this class should be attached to.
18855    *
18856    * @param {Object} [options]
18857    *        The key/value store of player options.
18858    *
18859    * @param {Component~ReadyCallback} [ready]
18860    *        The function to call when `TextTrackDisplay` is ready.
18861    */
18862   function TextTrackDisplay(player, options, ready) {
18863     _classCallCheck(this, TextTrackDisplay);
18865     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
18867     player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
18868     player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
18870     // This used to be called during player init, but was causing an error
18871     // if a track should show by default and the display hadn't loaded yet.
18872     // Should probably be moved to an external track loader when we support
18873     // tracks that don't need a display.
18874     player.ready(Fn.bind(_this, function () {
18875       if (player.tech_ && player.tech_.featuresNativeTextTracks) {
18876         this.hide();
18877         return;
18878       }
18880       player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
18882       var tracks = this.options_.playerOptions.tracks || [];
18884       for (var i = 0; i < tracks.length; i++) {
18885         this.player_.addRemoteTextTrack(tracks[i], true);
18886       }
18888       var modes = { captions: 1, subtitles: 1 };
18889       var trackList = this.player_.textTracks();
18890       var firstDesc = void 0;
18891       var firstCaptions = void 0;
18893       if (trackList) {
18894         for (var _i = 0; _i < trackList.length; _i++) {
18895           var track = trackList[_i];
18897           if (track['default']) {
18898             if (track.kind === 'descriptions' && !firstDesc) {
18899               firstDesc = track;
18900             } else if (track.kind in modes && !firstCaptions) {
18901               firstCaptions = track;
18902             }
18903           }
18904         }
18906         // We want to show the first default track but captions and subtitles
18907         // take precedence over descriptions.
18908         // So, display the first default captions or subtitles track
18909         // and otherwise the first default descriptions track.
18910         if (firstCaptions) {
18911           firstCaptions.mode = 'showing';
18912         } else if (firstDesc) {
18913           firstDesc.mode = 'showing';
18914         }
18915       }
18916     }));
18917     return _this;
18918   }
18920   /**
18921    * Turn display of {@link TextTrack}'s from the current state into the other state.
18922    * There are only two states:
18923    * - 'shown'
18924    * - 'hidden'
18925    *
18926    * @listens Player#loadstart
18927    */
18930   TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
18931     if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
18932       this.hide();
18933     } else {
18934       this.show();
18935     }
18936   };
18938   /**
18939    * Create the {@link Component}'s DOM element.
18940    *
18941    * @return {Element}
18942    *         The element that was created.
18943    */
18946   TextTrackDisplay.prototype.createEl = function createEl() {
18947     return _Component.prototype.createEl.call(this, 'div', {
18948       className: 'vjs-text-track-display'
18949     }, {
18950       'aria-live': 'off',
18951       'aria-atomic': 'true'
18952     });
18953   };
18955   /**
18956    * Clear all displayed {@link TextTrack}s.
18957    */
18960   TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
18961     if (typeof _window2['default'].WebVTT === 'function') {
18962       _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
18963     }
18964   };
18966   /**
18967    * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
18968    * a {@link Player#fullscreenchange} is fired.
18969    *
18970    * @listens Player#texttrackchange
18971    * @listens Player#fullscreenchange
18972    */
18975   TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
18976     var tracks = this.player_.textTracks();
18978     this.clearDisplay();
18980     if (!tracks) {
18981       return;
18982     }
18984     // Track display prioritization model: if multiple tracks are 'showing',
18985     //  display the first 'subtitles' or 'captions' track which is 'showing',
18986     //  otherwise display the first 'descriptions' track which is 'showing'
18988     var descriptionsTrack = null;
18989     var captionsSubtitlesTrack = null;
18991     var i = tracks.length;
18993     while (i--) {
18994       var track = tracks[i];
18996       if (track.mode === 'showing') {
18997         if (track.kind === 'descriptions') {
18998           descriptionsTrack = track;
18999         } else {
19000           captionsSubtitlesTrack = track;
19001         }
19002       }
19003     }
19005     if (captionsSubtitlesTrack) {
19006       if (this.getAttribute('aria-live') !== 'off') {
19007         this.setAttribute('aria-live', 'off');
19008       }
19009       this.updateForTrack(captionsSubtitlesTrack);
19010     } else if (descriptionsTrack) {
19011       if (this.getAttribute('aria-live') !== 'assertive') {
19012         this.setAttribute('aria-live', 'assertive');
19013       }
19014       this.updateForTrack(descriptionsTrack);
19015     }
19016   };
19018   /**
19019    * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
19020    *
19021    * @param {TextTrack} track
19022    *        Text track object to be added to the list.
19023    */
19026   TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
19027     if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
19028       return;
19029     }
19031     var overrides = this.player_.textTrackSettings.getValues();
19032     var cues = [];
19034     for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
19035       cues.push(track.activeCues[_i2]);
19036     }
19038     _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
19040     var i = cues.length;
19042     while (i--) {
19043       var cue = cues[i];
19045       if (!cue) {
19046         continue;
19047       }
19049       var cueDiv = cue.displayState;
19051       if (overrides.color) {
19052         cueDiv.firstChild.style.color = overrides.color;
19053       }
19054       if (overrides.textOpacity) {
19055         tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
19056       }
19057       if (overrides.backgroundColor) {
19058         cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
19059       }
19060       if (overrides.backgroundOpacity) {
19061         tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
19062       }
19063       if (overrides.windowColor) {
19064         if (overrides.windowOpacity) {
19065           tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
19066         } else {
19067           cueDiv.style.backgroundColor = overrides.windowColor;
19068         }
19069       }
19070       if (overrides.edgeStyle) {
19071         if (overrides.edgeStyle === 'dropshadow') {
19072           cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
19073         } else if (overrides.edgeStyle === 'raised') {
19074           cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
19075         } else if (overrides.edgeStyle === 'depressed') {
19076           cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
19077         } else if (overrides.edgeStyle === 'uniform') {
19078           cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
19079         }
19080       }
19081       if (overrides.fontPercent && overrides.fontPercent !== 1) {
19082         var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
19084         cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
19085         cueDiv.style.height = 'auto';
19086         cueDiv.style.top = 'auto';
19087         cueDiv.style.bottom = '2px';
19088       }
19089       if (overrides.fontFamily && overrides.fontFamily !== 'default') {
19090         if (overrides.fontFamily === 'small-caps') {
19091           cueDiv.firstChild.style.fontVariant = 'small-caps';
19092         } else {
19093           cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
19094         }
19095       }
19096     }
19097   };
19099   return TextTrackDisplay;
19100 }(_component2['default']);
19102 _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
19103 exports['default'] = TextTrackDisplay;
19105 },{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){
19106 'use strict';
19108 exports.__esModule = true;
19110  * @file text-track-list-converter.js Utilities for capturing text track state and
19111  * re-creating tracks based on a capture.
19113  * @module text-track-list-converter
19114  */
19117  * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
19118  * represents the {@link TextTrack}'s state.
19120  * @param {TextTrack} track
19121  *        The text track to query.
19123  * @return {Object}
19124  *         A serializable javascript representation of the TextTrack.
19125  * @private
19126  */
19127 var trackToJson_ = function trackToJson_(track) {
19128   var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
19130     if (track[prop]) {
19131       acc[prop] = track[prop];
19132     }
19134     return acc;
19135   }, {
19136     cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
19137       return {
19138         startTime: cue.startTime,
19139         endTime: cue.endTime,
19140         text: cue.text,
19141         id: cue.id
19142       };
19143     })
19144   });
19146   return ret;
19150  * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
19151  * state of all {@link TextTrack}s currently configured. The return array is compatible with
19152  * {@link text-track-list-converter:jsonToTextTracks}.
19154  * @param {Tech} tech
19155  *        The tech object to query
19157  * @return {Array}
19158  *         A serializable javascript representation of the {@link Tech}s
19159  *         {@link TextTrackList}.
19160  */
19161 var textTracksToJson = function textTracksToJson(tech) {
19163   var trackEls = tech.$$('track');
19165   var trackObjs = Array.prototype.map.call(trackEls, function (t) {
19166     return t.track;
19167   });
19168   var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
19169     var json = trackToJson_(trackEl.track);
19171     if (trackEl.src) {
19172       json.src = trackEl.src;
19173     }
19174     return json;
19175   });
19177   return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
19178     return trackObjs.indexOf(track) === -1;
19179   }).map(trackToJson_));
19183  * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
19184  * object {@link TextTrack} representations.
19186  * @param {Array} json
19187  *        An array of `TextTrack` representation objects, like those that would be
19188  *        produced by `textTracksToJson`.
19190  * @param {Tech} tech
19191  *        The `Tech` to create the `TextTrack`s on.
19192  */
19193 var jsonToTextTracks = function jsonToTextTracks(json, tech) {
19194   json.forEach(function (track) {
19195     var addedTrack = tech.addRemoteTextTrack(track).track;
19197     if (!track.src && track.cues) {
19198       track.cues.forEach(function (cue) {
19199         return addedTrack.addCue(cue);
19200       });
19201     }
19202   });
19204   return tech.textTracks();
19207 exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
19209 },{}],70:[function(_dereq_,module,exports){
19210 'use strict';
19212 exports.__esModule = true;
19214 var _trackList = _dereq_(74);
19216 var _trackList2 = _interopRequireDefault(_trackList);
19218 var _fn = _dereq_(83);
19220 var Fn = _interopRequireWildcard(_fn);
19222 var _browser = _dereq_(78);
19224 var browser = _interopRequireWildcard(_browser);
19226 var _document = _dereq_(94);
19228 var _document2 = _interopRequireDefault(_document);
19230 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19232 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19234 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19236 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19238 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19239                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-list.js
19240                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19244  * The current list of {@link TextTrack} for a media file.
19246  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
19247  * @extends TrackList
19248  */
19249 var TextTrackList = function (_TrackList) {
19250   _inherits(TextTrackList, _TrackList);
19252   /**
19253    * Create an instance of this class.
19254    *
19255    * @param {TextTrack[]} [tracks=[]]
19256    *        A list of `TextTrack` to instantiate the list with.
19257    */
19258   function TextTrackList() {
19259     var _this, _ret;
19261     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
19263     _classCallCheck(this, TextTrackList);
19265     var list = void 0;
19267     // IE8 forces us to implement inheritance ourselves
19268     // as it does not support Object.defineProperty properly
19269     if (browser.IS_IE8) {
19270       list = _document2['default'].createElement('custom');
19271       for (var prop in _trackList2['default'].prototype) {
19272         if (prop !== 'constructor') {
19273           list[prop] = _trackList2['default'].prototype[prop];
19274         }
19275       }
19276       for (var _prop in TextTrackList.prototype) {
19277         if (_prop !== 'constructor') {
19278           list[_prop] = TextTrackList.prototype[_prop];
19279         }
19280       }
19281     }
19283     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
19284     return _ret = list, _possibleConstructorReturn(_this, _ret);
19285   }
19287   /**
19288    * Add a {@link TextTrack} to the `TextTrackList`
19289    *
19290    * @param {TextTrack} track
19291    *        The text track to add to the list.
19292    *
19293    * @fires TrackList#addtrack
19294    * @private
19295    */
19298   TextTrackList.prototype.addTrack_ = function addTrack_(track) {
19299     _TrackList.prototype.addTrack_.call(this, track);
19301     /**
19302      * @listens TextTrack#modechange
19303      * @fires TrackList#change
19304      */
19305     track.addEventListener('modechange', Fn.bind(this, function () {
19306       this.trigger('change');
19307     }));
19308   };
19310   return TextTrackList;
19311 }(_trackList2['default']);
19313 exports['default'] = TextTrackList;
19315 },{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){
19316 'use strict';
19318 exports.__esModule = true;
19320 var _window = _dereq_(95);
19322 var _window2 = _interopRequireDefault(_window);
19324 var _component = _dereq_(5);
19326 var _component2 = _interopRequireDefault(_component);
19328 var _dom = _dereq_(81);
19330 var _fn = _dereq_(83);
19332 var Fn = _interopRequireWildcard(_fn);
19334 var _obj = _dereq_(88);
19336 var Obj = _interopRequireWildcard(_obj);
19338 var _log = _dereq_(86);
19340 var _log2 = _interopRequireDefault(_log);
19342 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19344 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19346 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19348 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19350 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19351                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-settings.js
19352                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19355 var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
19357 var COLOR_BLACK = ['#000', 'Black'];
19358 var COLOR_BLUE = ['#00F', 'Blue'];
19359 var COLOR_CYAN = ['#0FF', 'Cyan'];
19360 var COLOR_GREEN = ['#0F0', 'Green'];
19361 var COLOR_MAGENTA = ['#F0F', 'Magenta'];
19362 var COLOR_RED = ['#F00', 'Red'];
19363 var COLOR_WHITE = ['#FFF', 'White'];
19364 var COLOR_YELLOW = ['#FF0', 'Yellow'];
19366 var OPACITY_OPAQUE = ['1', 'Opaque'];
19367 var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
19368 var OPACITY_TRANS = ['0', 'Transparent'];
19370 // Configuration for the various <select> elements in the DOM of this component.
19372 // Possible keys include:
19374 // `default`:
19375 //   The default option index. Only needs to be provided if not zero.
19376 // `parser`:
19377 //   A function which is used to parse the value from the selected option in
19378 //   a customized way.
19379 // `selector`:
19380 //   The selector used to find the associated <select> element.
19381 var selectConfigs = {
19382   backgroundColor: {
19383     selector: '.vjs-bg-color > select',
19384     id: 'captions-background-color-%s',
19385     label: 'Color',
19386     options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19387   },
19389   backgroundOpacity: {
19390     selector: '.vjs-bg-opacity > select',
19391     id: 'captions-background-opacity-%s',
19392     label: 'Transparency',
19393     options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
19394   },
19396   color: {
19397     selector: '.vjs-fg-color > select',
19398     id: 'captions-foreground-color-%s',
19399     label: 'Color',
19400     options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19401   },
19403   edgeStyle: {
19404     selector: '.vjs-edge-style > select',
19405     id: '%s',
19406     label: 'Text Edge Style',
19407     options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
19408   },
19410   fontFamily: {
19411     selector: '.vjs-font-family > select',
19412     id: 'captions-font-family-%s',
19413     label: 'Font Family',
19414     options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
19415   },
19417   fontPercent: {
19418     selector: '.vjs-font-percent > select',
19419     id: 'captions-font-size-%s',
19420     label: 'Font Size',
19421     options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']],
19422     'default': 2,
19423     parser: function parser(v) {
19424       return v === '1.00' ? null : Number(v);
19425     }
19426   },
19428   textOpacity: {
19429     selector: '.vjs-text-opacity > select',
19430     id: 'captions-foreground-opacity-%s',
19431     label: 'Transparency',
19432     options: [OPACITY_OPAQUE, OPACITY_SEMI]
19433   },
19435   // Options for this object are defined below.
19436   windowColor: {
19437     selector: '.vjs-window-color > select',
19438     id: 'captions-window-color-%s',
19439     label: 'Color'
19440   },
19442   // Options for this object are defined below.
19443   windowOpacity: {
19444     selector: '.vjs-window-opacity > select',
19445     id: 'captions-window-opacity-%s',
19446     label: 'Transparency',
19447     options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
19448   }
19451 selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
19454  * Get the actual value of an option.
19456  * @param  {string} value
19457  *         The value to get
19459  * @param  {Function} [parser]
19460  *         Optional function to adjust the value.
19462  * @return {Mixed}
19463  *         - Will be `undefined` if no value exists
19464  *         - Will be `undefined` if the given value is "none".
19465  *         - Will be the actual value otherwise.
19467  * @private
19468  */
19469 function parseOptionValue(value, parser) {
19470   if (parser) {
19471     value = parser(value);
19472   }
19474   if (value && value !== 'none') {
19475     return value;
19476   }
19480  * Gets the value of the selected <option> element within a <select> element.
19482  * @param  {Element} el
19483  *         the element to look in
19485  * @param  {Function} [parser]
19486  *         Optional function to adjust the value.
19488  * @return {Mixed}
19489  *         - Will be `undefined` if no value exists
19490  *         - Will be `undefined` if the given value is "none".
19491  *         - Will be the actual value otherwise.
19493  * @private
19494  */
19495 function getSelectedOptionValue(el, parser) {
19496   var value = el.options[el.options.selectedIndex].value;
19498   return parseOptionValue(value, parser);
19502  * Sets the selected <option> element within a <select> element based on a
19503  * given value.
19505  * @param {Element} el
19506  *        The element to look in.
19508  * @param {string} value
19509  *        the property to look on.
19511  * @param {Function} [parser]
19512  *        Optional function to adjust the value before comparing.
19514  * @private
19515  */
19516 function setSelectedOption(el, value, parser) {
19517   if (!value) {
19518     return;
19519   }
19521   for (var i = 0; i < el.options.length; i++) {
19522     if (parseOptionValue(el.options[i].value, parser) === value) {
19523       el.selectedIndex = i;
19524       break;
19525     }
19526   }
19530  * Manipulate Text Tracks settings.
19532  * @extends Component
19533  */
19535 var TextTrackSettings = function (_Component) {
19536   _inherits(TextTrackSettings, _Component);
19538   /**
19539    * Creates an instance of this class.
19540    *
19541    * @param {Player} player
19542    *         The `Player` that this class should be attached to.
19543    *
19544    * @param {Object} [options]
19545    *         The key/value store of player options.
19546    */
19547   function TextTrackSettings(player, options) {
19548     _classCallCheck(this, TextTrackSettings);
19550     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
19552     _this.setDefaults();
19553     _this.hide();
19555     _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
19557     // Grab `persistTextTrackSettings` from the player options if not passed in child options
19558     if (options.persistTextTrackSettings === undefined) {
19559       _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
19560     }
19562     _this.on(_this.$('.vjs-done-button'), 'click', function () {
19563       _this.saveSettings();
19564       _this.hide();
19565     });
19567     _this.on(_this.$('.vjs-default-button'), 'click', function () {
19568       _this.setDefaults();
19569       _this.updateDisplay();
19570     });
19572     Obj.each(selectConfigs, function (config) {
19573       _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
19574     });
19576     if (_this.options_.persistTextTrackSettings) {
19577       _this.restoreSettings();
19578     }
19579     return _this;
19580   }
19582   /**
19583    * Create a <select> element with configured options.
19584    *
19585    * @param {string} key
19586    *        Configuration key to use during creation.
19587    *
19588    * @return {Element}
19589    *         The DOM element that gets created.
19590    * @private
19591    */
19594   TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
19595     var _this2 = this;
19597     var config = selectConfigs[key];
19598     var id = config.id.replace('%s', this.id_);
19600     return [(0, _dom.createEl)('label', {
19601       className: 'vjs-label',
19602       textContent: config.label
19603     }, {
19604       'for': id
19605     }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
19606       return (0, _dom.createEl)('option', {
19607         textContent: _this2.localize(o[1]),
19608         value: o[0]
19609       });
19610     }))];
19611   };
19613   /**
19614    * Create foreground color element for the component
19615    *
19616    * @return {Element}
19617    *         The element that was created.
19618    *
19619    * @private
19620    */
19623   TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
19624     var legend = (0, _dom.createEl)('legend', {
19625       textContent: this.localize('Text')
19626     });
19628     var select = this.createElSelect_('color');
19630     var opacity = (0, _dom.createEl)('span', {
19631       className: 'vjs-text-opacity vjs-opacity'
19632     }, undefined, this.createElSelect_('textOpacity'));
19634     return (0, _dom.createEl)('fieldset', {
19635       className: 'vjs-fg-color vjs-tracksetting'
19636     }, undefined, [legend].concat(select, opacity));
19637   };
19639   /**
19640    * Create background color element for the component
19641    *
19642    * @return {Element}
19643    *         The element that was created
19644    *
19645    * @private
19646    */
19649   TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
19650     var legend = (0, _dom.createEl)('legend', {
19651       textContent: this.localize('Background')
19652     });
19654     var select = this.createElSelect_('backgroundColor');
19656     var opacity = (0, _dom.createEl)('span', {
19657       className: 'vjs-bg-opacity vjs-opacity'
19658     }, undefined, this.createElSelect_('backgroundOpacity'));
19660     return (0, _dom.createEl)('fieldset', {
19661       className: 'vjs-bg-color vjs-tracksetting'
19662     }, undefined, [legend].concat(select, opacity));
19663   };
19665   /**
19666    * Create window color element for the component
19667    *
19668    * @return {Element}
19669    *         The element that was created
19670    *
19671    * @private
19672    */
19675   TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
19676     var legend = (0, _dom.createEl)('legend', {
19677       textContent: this.localize('Window')
19678     });
19680     var select = this.createElSelect_('windowColor');
19682     var opacity = (0, _dom.createEl)('span', {
19683       className: 'vjs-window-opacity vjs-opacity'
19684     }, undefined, this.createElSelect_('windowOpacity'));
19686     return (0, _dom.createEl)('fieldset', {
19687       className: 'vjs-window-color vjs-tracksetting'
19688     }, undefined, [legend].concat(select, opacity));
19689   };
19691   /**
19692    * Create color elements for the component
19693    *
19694    * @return {Element}
19695    *         The element that was created
19696    *
19697    * @private
19698    */
19701   TextTrackSettings.prototype.createElColors_ = function createElColors_() {
19702     return (0, _dom.createEl)('div', {
19703       className: 'vjs-tracksettings-colors'
19704     }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
19705   };
19707   /**
19708    * Create font elements for the component
19709    *
19710    * @return {Element}
19711    *         The element that was created.
19712    *
19713    * @private
19714    */
19717   TextTrackSettings.prototype.createElFont_ = function createElFont_() {
19718     var fontPercent = (0, _dom.createEl)('div', {
19719       className: 'vjs-font-percent vjs-tracksetting'
19720     }, undefined, this.createElSelect_('fontPercent'));
19722     var edgeStyle = (0, _dom.createEl)('div', {
19723       className: 'vjs-edge-style vjs-tracksetting'
19724     }, undefined, this.createElSelect_('edgeStyle'));
19726     var fontFamily = (0, _dom.createEl)('div', {
19727       className: 'vjs-font-family vjs-tracksetting'
19728     }, undefined, this.createElSelect_('fontFamily'));
19730     return (0, _dom.createEl)('div', {
19731       className: 'vjs-tracksettings-font'
19732     }, undefined, [fontPercent, edgeStyle, fontFamily]);
19733   };
19735   /**
19736    * Create controls for the component
19737    *
19738    * @return {Element}
19739    *         The element that was created.
19740    *
19741    * @private
19742    */
19745   TextTrackSettings.prototype.createElControls_ = function createElControls_() {
19746     var defaultsButton = (0, _dom.createEl)('button', {
19747       className: 'vjs-default-button',
19748       textContent: this.localize('Defaults')
19749     });
19751     var doneButton = (0, _dom.createEl)('button', {
19752       className: 'vjs-done-button',
19753       textContent: 'Done'
19754     });
19756     return (0, _dom.createEl)('div', {
19757       className: 'vjs-tracksettings-controls'
19758     }, undefined, [defaultsButton, doneButton]);
19759   };
19761   /**
19762    * Create the component's DOM element
19763    *
19764    * @return {Element}
19765    *         The element that was created.
19766    */
19769   TextTrackSettings.prototype.createEl = function createEl() {
19770     var settings = (0, _dom.createEl)('div', {
19771       className: 'vjs-tracksettings'
19772     }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
19774     var heading = (0, _dom.createEl)('div', {
19775       className: 'vjs-control-text',
19776       id: 'TTsettingsDialogLabel-' + this.id_,
19777       textContent: 'Caption Settings Dialog'
19778     }, {
19779       'aria-level': '1',
19780       'role': 'heading'
19781     });
19783     var description = (0, _dom.createEl)('div', {
19784       className: 'vjs-control-text',
19785       id: 'TTsettingsDialogDescription-' + this.id_,
19786       textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
19787     });
19789     var doc = (0, _dom.createEl)('div', undefined, {
19790       role: 'document'
19791     }, [heading, description, settings]);
19793     return (0, _dom.createEl)('div', {
19794       className: 'vjs-caption-settings vjs-modal-overlay',
19795       tabIndex: -1
19796     }, {
19797       'role': 'dialog',
19798       'aria-labelledby': heading.id,
19799       'aria-describedby': description.id
19800     }, doc);
19801   };
19803   /**
19804    * Gets an object of text track settings (or null).
19805    *
19806    * @return {Object}
19807    *         An object with config values parsed from the DOM or localStorage.
19808    */
19811   TextTrackSettings.prototype.getValues = function getValues() {
19812     var _this3 = this;
19814     return Obj.reduce(selectConfigs, function (accum, config, key) {
19815       var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
19817       if (value !== undefined) {
19818         accum[key] = value;
19819       }
19821       return accum;
19822     }, {});
19823   };
19825   /**
19826    * Sets text track settings from an object of values.
19827    *
19828    * @param {Object} values
19829    *        An object with config values parsed from the DOM or localStorage.
19830    */
19833   TextTrackSettings.prototype.setValues = function setValues(values) {
19834     var _this4 = this;
19836     Obj.each(selectConfigs, function (config, key) {
19837       setSelectedOption(_this4.$(config.selector), values[key], config.parser);
19838     });
19839   };
19841   /**
19842    * Sets all <select> elements to their default values.
19843    */
19846   TextTrackSettings.prototype.setDefaults = function setDefaults() {
19847     var _this5 = this;
19849     Obj.each(selectConfigs, function (config) {
19850       var index = config.hasOwnProperty('default') ? config['default'] : 0;
19852       _this5.$(config.selector).selectedIndex = index;
19853     });
19854   };
19856   /**
19857    * Restore texttrack settings from localStorage
19858    */
19861   TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
19862     var values = void 0;
19864     try {
19865       values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
19866     } catch (err) {
19867       _log2['default'].warn(err);
19868     }
19870     if (values) {
19871       this.setValues(values);
19872     }
19873   };
19875   /**
19876    * Save text track settings to localStorage
19877    */
19880   TextTrackSettings.prototype.saveSettings = function saveSettings() {
19881     if (!this.options_.persistTextTrackSettings) {
19882       return;
19883     }
19885     var values = this.getValues();
19887     try {
19888       if (Object.keys(values).length) {
19889         _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
19890       } else {
19891         _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
19892       }
19893     } catch (err) {
19894       _log2['default'].warn(err);
19895     }
19896   };
19898   /**
19899    * Update display of text track settings
19900    */
19903   TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
19904     var ttDisplay = this.player_.getChild('textTrackDisplay');
19906     if (ttDisplay) {
19907       ttDisplay.updateDisplay();
19908     }
19909   };
19911   return TextTrackSettings;
19912 }(_component2['default']);
19914 _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
19916 exports['default'] = TextTrackSettings;
19918 },{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){
19919 'use strict';
19921 exports.__esModule = true;
19923 var _textTrackCueList = _dereq_(67);
19925 var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
19927 var _fn = _dereq_(83);
19929 var Fn = _interopRequireWildcard(_fn);
19931 var _trackEnums = _dereq_(73);
19933 var _log = _dereq_(86);
19935 var _log2 = _interopRequireDefault(_log);
19937 var _window = _dereq_(95);
19939 var _window2 = _interopRequireDefault(_window);
19941 var _track = _dereq_(75);
19943 var _track2 = _interopRequireDefault(_track);
19945 var _url = _dereq_(92);
19947 var _xhr = _dereq_(99);
19949 var _xhr2 = _interopRequireDefault(_xhr);
19951 var _mergeOptions = _dereq_(87);
19953 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
19955 var _browser = _dereq_(78);
19957 var browser = _interopRequireWildcard(_browser);
19959 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19961 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19963 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19965 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19967 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19968                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track.js
19969                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19973  * Takes a webvtt file contents and parses it into cues
19975  * @param {string} srcContent
19976  *        webVTT file contents
19978  * @param {TextTrack} track
19979  *        TextTrack to add cues to. Cues come from the srcContent.
19981  * @private
19982  */
19983 var parseCues = function parseCues(srcContent, track) {
19984   var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
19985   var errors = [];
19987   parser.oncue = function (cue) {
19988     track.addCue(cue);
19989   };
19991   parser.onparsingerror = function (error) {
19992     errors.push(error);
19993   };
19995   parser.onflush = function () {
19996     track.trigger({
19997       type: 'loadeddata',
19998       target: track
19999     });
20000   };
20002   parser.parse(srcContent);
20003   if (errors.length > 0) {
20004     if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
20005       _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
20006     }
20007     errors.forEach(function (error) {
20008       return _log2['default'].error(error);
20009     });
20010     if (_window2['default'].console && _window2['default'].console.groupEnd) {
20011       _window2['default'].console.groupEnd();
20012     }
20013   }
20015   parser.flush();
20019  * Load a `TextTrack` from a specified url.
20021  * @param {string} src
20022  *        Url to load track from.
20024  * @param {TextTrack} track
20025  *        Track to add cues to. Comes from the content at the end of `url`.
20027  * @private
20028  */
20029 var loadTrack = function loadTrack(src, track) {
20030   var opts = {
20031     uri: src
20032   };
20033   var crossOrigin = (0, _url.isCrossOrigin)(src);
20035   if (crossOrigin) {
20036     opts.cors = crossOrigin;
20037   }
20039   (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
20040     if (err) {
20041       return _log2['default'].error(err, response);
20042     }
20044     track.loaded_ = true;
20046     // Make sure that vttjs has loaded, otherwise, wait till it finished loading
20047     // NOTE: this is only used for the alt/video.novtt.js build
20048     if (typeof _window2['default'].WebVTT !== 'function') {
20049       if (track.tech_) {
20050         (function () {
20051           var loadHandler = function loadHandler() {
20052             return parseCues(responseBody, track);
20053           };
20055           track.tech_.on('vttjsloaded', loadHandler);
20056           track.tech_.on('vttjserror', function () {
20057             _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
20058             track.tech_.off('vttjsloaded', loadHandler);
20059           });
20060         })();
20061       }
20062     } else {
20063       parseCues(responseBody, track);
20064     }
20065   }));
20069  * A representation of a single `TextTrack`.
20071  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
20072  * @extends Track
20073  */
20075 var TextTrack = function (_Track) {
20076   _inherits(TextTrack, _Track);
20078   /**
20079    * Create an instance of this class.
20080    *
20081    * @param {Object} options={}
20082    *        Object of option names and values
20083    *
20084    * @param {Tech} options.tech
20085    *        A reference to the tech that owns this TextTrack.
20086    *
20087    * @param {TextTrack~Kind} [options.kind='subtitles']
20088    *        A valid text track kind.
20089    *
20090    * @param {TextTrack~Mode} [options.mode='disabled']
20091    *        A valid text track mode.
20092    *
20093    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20094    *        A unique id for this TextTrack.
20095    *
20096    * @param {string} [options.label='']
20097    *        The menu label for this track.
20098    *
20099    * @param {string} [options.language='']
20100    *        A valid two character language code.
20101    *
20102    * @param {string} [options.srclang='']
20103    *        A valid two character language code. An alternative, but deprioritized
20104    *        version of `options.language`
20105    *
20106    * @param {string} [options.src]
20107    *        A url to TextTrack cues.
20108    *
20109    * @param {boolean} [options.default]
20110    *        If this track should default to on or off.
20111    */
20112   function TextTrack() {
20113     var _this, _ret2;
20115     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20117     _classCallCheck(this, TextTrack);
20119     if (!options.tech) {
20120       throw new Error('A tech was not provided.');
20121     }
20123     var settings = (0, _mergeOptions2['default'])(options, {
20124       kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
20125       language: options.language || options.srclang || ''
20126     });
20127     var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
20128     var default_ = settings['default'];
20130     if (settings.kind === 'metadata' || settings.kind === 'chapters') {
20131       mode = 'hidden';
20132     }
20133     // on IE8 this will be a document element
20134     // for every other browser this will be a normal object
20135     var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
20137     tt.tech_ = settings.tech;
20139     if (browser.IS_IE8) {
20140       for (var prop in TextTrack.prototype) {
20141         if (prop !== 'constructor') {
20142           tt[prop] = TextTrack.prototype[prop];
20143         }
20144       }
20145     }
20147     tt.cues_ = [];
20148     tt.activeCues_ = [];
20150     var cues = new _textTrackCueList2['default'](tt.cues_);
20151     var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
20152     var changed = false;
20153     var timeupdateHandler = Fn.bind(tt, function () {
20155       // Accessing this.activeCues for the side-effects of updating itself
20156       // due to it's nature as a getter function. Do not remove or cues will
20157       // stop updating!
20158       /* eslint-disable no-unused-expressions */
20159       this.activeCues;
20160       /* eslint-enable no-unused-expressions */
20161       if (changed) {
20162         this.trigger('cuechange');
20163         changed = false;
20164       }
20165     });
20167     if (mode !== 'disabled') {
20168       tt.tech_.on('timeupdate', timeupdateHandler);
20169     }
20171     /**
20172      * @member {boolean} default
20173      *         If this track was set to be on or off by default. Cannot be changed after
20174      *         creation.
20175      *
20176      * @readonly
20177      */
20178     Object.defineProperty(tt, 'default', {
20179       get: function get() {
20180         return default_;
20181       },
20182       set: function set() {}
20183     });
20185     /**
20186      * @member {string} mode
20187      *         Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
20188      *         not be set if setting to an invalid mode.
20189      *
20190      * @fires TextTrack#modechange
20191      */
20192     Object.defineProperty(tt, 'mode', {
20193       get: function get() {
20194         return mode;
20195       },
20196       set: function set(newMode) {
20197         if (!_trackEnums.TextTrackMode[newMode]) {
20198           return;
20199         }
20200         mode = newMode;
20201         if (mode === 'showing') {
20202           this.tech_.on('timeupdate', timeupdateHandler);
20203         }
20204         /**
20205          * An event that fires when mode changes on this track. This allows
20206          * the TextTrackList that holds this track to act accordingly.
20207          *
20208          * > Note: This is not part of the spec!
20209          *
20210          * @event TextTrack#modechange
20211          * @type {EventTarget~Event}
20212          */
20213         this.trigger('modechange');
20214       }
20215     });
20217     /**
20218      * @member {TextTrackCueList} cues
20219      *         The text track cue list for this TextTrack.
20220      */
20221     Object.defineProperty(tt, 'cues', {
20222       get: function get() {
20223         if (!this.loaded_) {
20224           return null;
20225         }
20227         return cues;
20228       },
20229       set: function set() {}
20230     });
20232     /**
20233      * @member {TextTrackCueList} activeCues
20234      *         The list text track cues that are currently active for this TextTrack.
20235      */
20236     Object.defineProperty(tt, 'activeCues', {
20237       get: function get() {
20238         if (!this.loaded_) {
20239           return null;
20240         }
20242         // nothing to do
20243         if (this.cues.length === 0) {
20244           return activeCues;
20245         }
20247         var ct = this.tech_.currentTime();
20248         var active = [];
20250         for (var i = 0, l = this.cues.length; i < l; i++) {
20251           var cue = this.cues[i];
20253           if (cue.startTime <= ct && cue.endTime >= ct) {
20254             active.push(cue);
20255           } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
20256             active.push(cue);
20257           }
20258         }
20260         changed = false;
20262         if (active.length !== this.activeCues_.length) {
20263           changed = true;
20264         } else {
20265           for (var _i = 0; _i < active.length; _i++) {
20266             if (this.activeCues_.indexOf(active[_i]) === -1) {
20267               changed = true;
20268             }
20269           }
20270         }
20272         this.activeCues_ = active;
20273         activeCues.setCues_(this.activeCues_);
20275         return activeCues;
20276       },
20277       set: function set() {}
20278     });
20280     if (settings.src) {
20281       tt.src = settings.src;
20282       loadTrack(settings.src, tt);
20283     } else {
20284       tt.loaded_ = true;
20285     }
20287     return _ret2 = tt, _possibleConstructorReturn(_this, _ret2);
20288   }
20290   /**
20291    * Add a cue to the internal list of cues.
20292    *
20293    * @param {TextTrack~Cue} cue
20294    *        The cue to add to our internal list
20295    */
20298   TextTrack.prototype.addCue = function addCue(cue) {
20299     var tracks = this.tech_.textTracks();
20301     if (tracks) {
20302       for (var i = 0; i < tracks.length; i++) {
20303         if (tracks[i] !== this) {
20304           tracks[i].removeCue(cue);
20305         }
20306       }
20307     }
20309     this.cues_.push(cue);
20310     this.cues.setCues_(this.cues_);
20311   };
20313   /**
20314    * Remove a cue from our internal list
20315    *
20316    * @param {TextTrack~Cue} removeCue
20317    *        The cue to remove from our internal list
20318    */
20321   TextTrack.prototype.removeCue = function removeCue(_removeCue) {
20322     var removed = false;
20324     for (var i = 0, l = this.cues_.length; i < l; i++) {
20325       var cue = this.cues_[i];
20327       if (cue === _removeCue) {
20328         this.cues_.splice(i, 1);
20329         removed = true;
20330       }
20331     }
20333     if (removed) {
20334       this.cues.setCues_(this.cues_);
20335     }
20336   };
20338   return TextTrack;
20339 }(_track2['default']);
20342  * cuechange - One or more cues in the track have become active or stopped being active.
20343  */
20346 TextTrack.prototype.allowedEvents_ = {
20347   cuechange: 'cuechange'
20350 exports['default'] = TextTrack;
20352 },{"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95,"99":99}],73:[function(_dereq_,module,exports){
20353 'use strict';
20355 exports.__esModule = true;
20357  * @file track-kinds.js
20358  */
20361  * All possible `VideoTrackKind`s
20363  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
20364  * @typedef VideoTrack~Kind
20365  * @enum
20366  */
20367 var VideoTrackKind = exports.VideoTrackKind = {
20368   alternative: 'alternative',
20369   captions: 'captions',
20370   main: 'main',
20371   sign: 'sign',
20372   subtitles: 'subtitles',
20373   commentary: 'commentary'
20377  * All possible `AudioTrackKind`s
20379  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
20380  * @typedef AudioTrack~Kind
20381  * @enum
20382  */
20383 var AudioTrackKind = exports.AudioTrackKind = {
20384   'alternative': 'alternative',
20385   'descriptions': 'descriptions',
20386   'main': 'main',
20387   'main-desc': 'main-desc',
20388   'translation': 'translation',
20389   'commentary': 'commentary'
20393  * All possible `TextTrackKind`s
20395  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
20396  * @typedef TextTrack~Kind
20397  * @enum
20398  */
20399 var TextTrackKind = exports.TextTrackKind = {
20400   subtitles: 'subtitles',
20401   captions: 'captions',
20402   descriptions: 'descriptions',
20403   chapters: 'chapters',
20404   metadata: 'metadata'
20408  * All possible `TextTrackMode`s
20410  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
20411  * @typedef TextTrack~Mode
20412  * @enum
20413  */
20414 var TextTrackMode = exports.TextTrackMode = {
20415   disabled: 'disabled',
20416   hidden: 'hidden',
20417   showing: 'showing'
20420 },{}],74:[function(_dereq_,module,exports){
20421 'use strict';
20423 exports.__esModule = true;
20425 var _eventTarget = _dereq_(42);
20427 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20429 var _browser = _dereq_(78);
20431 var browser = _interopRequireWildcard(_browser);
20433 var _document = _dereq_(94);
20435 var _document2 = _interopRequireDefault(_document);
20437 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20439 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20441 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20443 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20445 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20446                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track-list.js
20447                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20451  * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
20452  * {@link VideoTrackList}
20454  * @extends EventTarget
20455  */
20456 var TrackList = function (_EventTarget) {
20457   _inherits(TrackList, _EventTarget);
20459   /**
20460    * Create an instance of this class
20461    *
20462    * @param {Track[]} tracks
20463    *        A list of tracks to initialize the list with.
20464    *
20465    * @param {Object} [list]
20466    *        The child object with inheritance done manually for ie8.
20467    *
20468    * @abstract
20469    */
20470   function TrackList() {
20471     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20473     var _ret;
20475     var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
20477     _classCallCheck(this, TrackList);
20479     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20481     if (!list) {
20482       list = _this; // eslint-disable-line
20483       if (browser.IS_IE8) {
20484         list = _document2['default'].createElement('custom');
20485         for (var prop in TrackList.prototype) {
20486           if (prop !== 'constructor') {
20487             list[prop] = TrackList.prototype[prop];
20488           }
20489         }
20490       }
20491     }
20493     list.tracks_ = [];
20495     /**
20496      * @member {number} length
20497      *         The current number of `Track`s in the this Trackist.
20498      */
20499     Object.defineProperty(list, 'length', {
20500       get: function get() {
20501         return this.tracks_.length;
20502       }
20503     });
20505     for (var i = 0; i < tracks.length; i++) {
20506       list.addTrack_(tracks[i]);
20507     }
20509     // must return the object, as for ie8 it will not be this
20510     // but a reference to a document object
20511     return _ret = list, _possibleConstructorReturn(_this, _ret);
20512   }
20514   /**
20515    * Add a {@link Track} to the `TrackList`
20516    *
20517    * @param {Track} track
20518    *        The audio, video, or text track to add to the list.
20519    *
20520    * @fires TrackList#addtrack
20521    * @private
20522    */
20525   TrackList.prototype.addTrack_ = function addTrack_(track) {
20526     var index = this.tracks_.length;
20528     if (!('' + index in this)) {
20529       Object.defineProperty(this, index, {
20530         get: function get() {
20531           return this.tracks_[index];
20532         }
20533       });
20534     }
20536     // Do not add duplicate tracks
20537     if (this.tracks_.indexOf(track) === -1) {
20538       this.tracks_.push(track);
20539       /**
20540        * Triggered when a track is added to a track list.
20541        *
20542        * @event TrackList#addtrack
20543        * @type {EventTarget~Event}
20544        * @property {Track} track
20545        *           A reference to track that was added.
20546        */
20547       this.trigger({
20548         track: track,
20549         type: 'addtrack'
20550       });
20551     }
20552   };
20554   /**
20555    * Remove a {@link Track} from the `TrackList`
20556    *
20557    * @param {Track} track
20558    *        The audio, video, or text track to remove from the list.
20559    *
20560    * @fires TrackList#removetrack
20561    * @private
20562    */
20565   TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
20566     var track = void 0;
20568     for (var i = 0, l = this.length; i < l; i++) {
20569       if (this[i] === rtrack) {
20570         track = this[i];
20571         if (track.off) {
20572           track.off();
20573         }
20575         this.tracks_.splice(i, 1);
20577         break;
20578       }
20579     }
20581     if (!track) {
20582       return;
20583     }
20585     /**
20586      * Triggered when a track is removed from track list.
20587      *
20588      * @event TrackList#removetrack
20589      * @type {EventTarget~Event}
20590      * @property {Track} track
20591      *           A reference to track that was removed.
20592      */
20593     this.trigger({
20594       track: track,
20595       type: 'removetrack'
20596     });
20597   };
20599   /**
20600    * Get a Track from the TrackList by a tracks id
20601    *
20602    * @param {String} id - the id of the track to get
20603    * @method getTrackById
20604    * @return {Track}
20605    * @private
20606    */
20609   TrackList.prototype.getTrackById = function getTrackById(id) {
20610     var result = null;
20612     for (var i = 0, l = this.length; i < l; i++) {
20613       var track = this[i];
20615       if (track.id === id) {
20616         result = track;
20617         break;
20618       }
20619     }
20621     return result;
20622   };
20624   return TrackList;
20625 }(_eventTarget2['default']);
20628  * Triggered when a different track is selected/enabled.
20630  * @event TrackList#change
20631  * @type {EventTarget~Event}
20632  */
20635  * Events that can be called with on + eventName. See {@link EventHandler}.
20637  * @property {Object} TrackList#allowedEvents_
20638  * @private
20639  */
20642 TrackList.prototype.allowedEvents_ = {
20643   change: 'change',
20644   addtrack: 'addtrack',
20645   removetrack: 'removetrack'
20648 // emulate attribute EventHandler support to allow for feature detection
20649 for (var event in TrackList.prototype.allowedEvents_) {
20650   TrackList.prototype['on' + event] = null;
20653 exports['default'] = TrackList;
20655 },{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){
20656 'use strict';
20658 exports.__esModule = true;
20660 var _browser = _dereq_(78);
20662 var browser = _interopRequireWildcard(_browser);
20664 var _document = _dereq_(94);
20666 var _document2 = _interopRequireDefault(_document);
20668 var _guid = _dereq_(85);
20670 var Guid = _interopRequireWildcard(_guid);
20672 var _eventTarget = _dereq_(42);
20674 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20676 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20678 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20680 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20682 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20684 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20685                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track.js
20686                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20690  * A Track class that contains all of the common functionality for {@link AudioTrack},
20691  * {@link VideoTrack}, and {@link TextTrack}.
20693  * > Note: This class should not be used directly
20695  * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
20696  * @extends EventTarget
20697  * @abstract
20698  */
20699 var Track = function (_EventTarget) {
20700   _inherits(Track, _EventTarget);
20702   /**
20703    * Create an instance of this class.
20704    *
20705    * @param {Object} [options={}]
20706    *        Object of option names and values
20707    *
20708    * @param {string} [options.kind='']
20709    *        A valid kind for the track type you are creating.
20710    *
20711    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20712    *        A unique id for this AudioTrack.
20713    *
20714    * @param {string} [options.label='']
20715    *        The menu label for this track.
20716    *
20717    * @param {string} [options.language='']
20718    *        A valid two character language code.
20719    *
20720    * @abstract
20721    */
20722   function Track() {
20723     var _ret;
20725     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20727     _classCallCheck(this, Track);
20729     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20731     var track = _this; // eslint-disable-line
20733     if (browser.IS_IE8) {
20734       track = _document2['default'].createElement('custom');
20735       for (var prop in Track.prototype) {
20736         if (prop !== 'constructor') {
20737           track[prop] = Track.prototype[prop];
20738         }
20739       }
20740     }
20742     var trackProps = {
20743       id: options.id || 'vjs_track_' + Guid.newGUID(),
20744       kind: options.kind || '',
20745       label: options.label || '',
20746       language: options.language || ''
20747     };
20749     /**
20750      * @member {string} id
20751      *         The id of this track. Cannot be changed after creation.
20752      *
20753      * @readonly
20754      */
20756     /**
20757      * @member {string} kind
20758      *         The kind of track that this is. Cannot be changed after creation.
20759      *
20760      * @readonly
20761      */
20763     /**
20764      * @member {string} label
20765      *         The label of this track. Cannot be changed after creation.
20766      *
20767      * @readonly
20768      */
20770     /**
20771      * @member {string} language
20772      *         The two letter language code for this track. Cannot be changed after
20773      *         creation.
20774      *
20775      * @readonly
20776      */
20778     var _loop = function _loop(key) {
20779       Object.defineProperty(track, key, {
20780         get: function get() {
20781           return trackProps[key];
20782         },
20783         set: function set() {}
20784       });
20785     };
20787     for (var key in trackProps) {
20788       _loop(key);
20789     }
20791     return _ret = track, _possibleConstructorReturn(_this, _ret);
20792   }
20794   return Track;
20795 }(_eventTarget2['default']);
20797 exports['default'] = Track;
20799 },{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){
20800 'use strict';
20802 exports.__esModule = true;
20804 var _trackList = _dereq_(74);
20806 var _trackList2 = _interopRequireDefault(_trackList);
20808 var _browser = _dereq_(78);
20810 var browser = _interopRequireWildcard(_browser);
20812 var _document = _dereq_(94);
20814 var _document2 = _interopRequireDefault(_document);
20816 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20818 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20820 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20822 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20824 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20825                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file video-track-list.js
20826                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20830  * Un-select all other {@link VideoTrack}s that are selected.
20832  * @param {VideoTrackList} list
20833  *        list to work on
20835  * @param {VideoTrack} track
20836  *        The track to skip
20838  * @private
20839  */
20840 var disableOthers = function disableOthers(list, track) {
20841   for (var i = 0; i < list.length; i++) {
20842     if (track.id === list[i].id) {
20843       continue;
20844     }
20845     // another video track is enabled, disable it
20846     list[i].selected = false;
20847   }
20851  * The current list of {@link VideoTrack} for a video.
20853  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
20854  * @extends TrackList
20855  */
20857 var VideoTrackList = function (_TrackList) {
20858   _inherits(VideoTrackList, _TrackList);
20860   /**
20861    * Create an instance of this class.
20862    *
20863    * @param {VideoTrack[]} [tracks=[]]
20864    *        A list of `VideoTrack` to instantiate the list with.
20865    */
20866   function VideoTrackList() {
20867     var _this, _ret;
20869     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20871     _classCallCheck(this, VideoTrackList);
20873     var list = void 0;
20875     // make sure only 1 track is enabled
20876     // sorted from last index to first index
20877     for (var i = tracks.length - 1; i >= 0; i--) {
20878       if (tracks[i].selected) {
20879         disableOthers(tracks, tracks[i]);
20880         break;
20881       }
20882     }
20884     // IE8 forces us to implement inheritance ourselves
20885     // as it does not support Object.defineProperty properly
20886     if (browser.IS_IE8) {
20887       list = _document2['default'].createElement('custom');
20888       for (var prop in _trackList2['default'].prototype) {
20889         if (prop !== 'constructor') {
20890           list[prop] = _trackList2['default'].prototype[prop];
20891         }
20892       }
20893       for (var _prop in VideoTrackList.prototype) {
20894         if (_prop !== 'constructor') {
20895           list[_prop] = VideoTrackList.prototype[_prop];
20896         }
20897       }
20898     }
20900     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
20901     list.changing_ = false;
20903     /**
20904      * @member {number} VideoTrackList#selectedIndex
20905      *         The current index of the selected {@link VideoTrack`}.
20906      */
20907     Object.defineProperty(list, 'selectedIndex', {
20908       get: function get() {
20909         for (var _i = 0; _i < this.length; _i++) {
20910           if (this[_i].selected) {
20911             return _i;
20912           }
20913         }
20914         return -1;
20915       },
20916       set: function set() {}
20917     });
20919     return _ret = list, _possibleConstructorReturn(_this, _ret);
20920   }
20922   /**
20923    * Add a {@link VideoTrack} to the `VideoTrackList`.
20924    *
20925    * @param {VideoTrack} track
20926    *        The VideoTrack to add to the list
20927    *
20928    * @fires TrackList#addtrack
20929    * @private
20930    */
20933   VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
20934     var _this2 = this;
20936     if (track.selected) {
20937       disableOthers(this, track);
20938     }
20940     _TrackList.prototype.addTrack_.call(this, track);
20941     // native tracks don't have this
20942     if (!track.addEventListener) {
20943       return;
20944     }
20946     /**
20947      * @listens VideoTrack#selectedchange
20948      * @fires TrackList#change
20949      */
20950     track.addEventListener('selectedchange', function () {
20951       if (_this2.changing_) {
20952         return;
20953       }
20954       _this2.changing_ = true;
20955       disableOthers(_this2, track);
20956       _this2.changing_ = false;
20957       _this2.trigger('change');
20958     });
20959   };
20961   /**
20962    * Add a {@link VideoTrack} to the `VideoTrackList`.
20963    *
20964    * @param {VideoTrack} track
20965    *        The VideoTrack to add to the list
20966    *
20967    * @fires TrackList#addtrack
20968    */
20971   VideoTrackList.prototype.addTrack = function addTrack(track) {
20972     this.addTrack_(track);
20973   };
20975   /**
20976    * Remove a {@link VideoTrack} to the `VideoTrackList`.
20977    *
20978    * @param {VideoTrack} track
20979    *        The VideoTrack to remove from the list.
20980    *
20981    * @fires TrackList#removetrack
20982    */
20985   VideoTrackList.prototype.removeTrack = function removeTrack(track) {
20986     _TrackList.prototype.removeTrack_.call(this, track);
20987   };
20989   return VideoTrackList;
20990 }(_trackList2['default']);
20992 exports['default'] = VideoTrackList;
20994 },{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){
20995 'use strict';
20997 exports.__esModule = true;
20999 var _trackEnums = _dereq_(73);
21001 var _track = _dereq_(75);
21003 var _track2 = _interopRequireDefault(_track);
21005 var _mergeOptions = _dereq_(87);
21007 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
21009 var _browser = _dereq_(78);
21011 var browser = _interopRequireWildcard(_browser);
21013 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21015 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21017 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21019 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
21021 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
21024  * A representation of a single `VideoTrack`.
21026  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
21027  * @extends Track
21028  */
21029 var VideoTrack = function (_Track) {
21030   _inherits(VideoTrack, _Track);
21032   /**
21033    * Create an instance of this class.
21034    *
21035    * @param {Object} [options={}]
21036    *        Object of option names and values
21037    *
21038    * @param {string} [options.kind='']
21039    *        A valid {@link VideoTrack~Kind}
21040    *
21041    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
21042    *        A unique id for this AudioTrack.
21043    *
21044    * @param {string} [options.label='']
21045    *        The menu label for this track.
21046    *
21047    * @param {string} [options.language='']
21048    *        A valid two character language code.
21049    *
21050    * @param {boolean} [options.selected]
21051    *        If this track is the one that is currently playing.
21052    */
21053   function VideoTrack() {
21054     var _this, _ret;
21056     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21058     _classCallCheck(this, VideoTrack);
21060     var settings = (0, _mergeOptions2['default'])(options, {
21061       kind: _trackEnums.VideoTrackKind[options.kind] || ''
21062     });
21064     // on IE8 this will be a document element
21065     // for every other browser this will be a normal object
21066     var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
21067     var selected = false;
21069     if (browser.IS_IE8) {
21070       for (var prop in VideoTrack.prototype) {
21071         if (prop !== 'constructor') {
21072           track[prop] = VideoTrack.prototype[prop];
21073         }
21074       }
21075     }
21077     /**
21078      * @member {boolean} selected
21079      *         If this `VideoTrack` is selected or not. When setting this will
21080      *         fire {@link VideoTrack#selectedchange} if the state of selected changed.
21081      *
21082      * @fires VideoTrack#selectedchange
21083      */
21084     Object.defineProperty(track, 'selected', {
21085       get: function get() {
21086         return selected;
21087       },
21088       set: function set(newSelected) {
21089         // an invalid or unchanged value
21090         if (typeof newSelected !== 'boolean' || newSelected === selected) {
21091           return;
21092         }
21093         selected = newSelected;
21095         /**
21096          * An event that fires when selected changes on this track. This allows
21097          * the VideoTrackList that holds this track to act accordingly.
21098          *
21099          * > Note: This is not part of the spec! Native tracks will do
21100          *         this internally without an event.
21101          *
21102          * @event VideoTrack#selectedchange
21103          * @type {EventTarget~Event}
21104          */
21105         this.trigger('selectedchange');
21106       }
21107     });
21109     // if the user sets this track to selected then
21110     // set selected to that true value otherwise
21111     // we keep it false
21112     if (settings.selected) {
21113       track.selected = settings.selected;
21114     }
21116     return _ret = track, _possibleConstructorReturn(_this, _ret);
21117   }
21119   return VideoTrack;
21120 }(_track2['default']);
21122 exports['default'] = VideoTrack;
21124 },{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){
21125 'use strict';
21127 exports.__esModule = true;
21128 exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exports.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined;
21130 var _dom = _dereq_(81);
21132 var Dom = _interopRequireWildcard(_dom);
21134 var _window = _dereq_(95);
21136 var _window2 = _interopRequireDefault(_window);
21138 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21140 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21143  * @file browser.js
21144  * @module browser
21145  */
21146 var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
21147 var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
21148 var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
21151  * Device is an iPhone
21153  * @type {Boolean}
21154  * @constant
21155  * @private
21156  */
21157 var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
21159 // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
21160 // to identify iPhones, we need to exclude iPads.
21161 // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
21162 var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
21163 var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
21164 var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
21166 var IOS_VERSION = exports.IOS_VERSION = function () {
21167   var match = USER_AGENT.match(/OS (\d+)_/i);
21169   if (match && match[1]) {
21170     return match[1];
21171   }
21172   return null;
21173 }();
21175 var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
21176 var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
21177   // This matches Android Major.Minor.Patch versions
21178   // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
21179   var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
21181   if (!match) {
21182     return null;
21183   }
21185   var major = match[1] && parseFloat(match[1]);
21186   var minor = match[2] && parseFloat(match[2]);
21188   if (major && minor) {
21189     return parseFloat(match[1] + '.' + match[2]);
21190   } else if (major) {
21191     return major;
21192   }
21193   return null;
21194 }();
21196 // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
21197 var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
21198 var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
21200 var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
21201 var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
21202 var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
21203 var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
21204 var IE_VERSION = exports.IE_VERSION = function (result) {
21205   return result && parseFloat(result[1]);
21206 }(/MSIE\s(\d+)\.\d/.exec(USER_AGENT));
21208 var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
21209 var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
21211 var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
21213 var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
21215 },{"81":81,"95":95}],79:[function(_dereq_,module,exports){
21216 'use strict';
21218 exports.__esModule = true;
21219 exports.bufferedPercent = bufferedPercent;
21221 var _timeRanges = _dereq_(90);
21224  * Compute the percentage of the media that has been buffered.
21226  * @param {TimeRange} buffered
21227  *        The current `TimeRange` object representing buffered time ranges
21229  * @param {number} duration
21230  *        Total duration of the media
21232  * @return {number}
21233  *         Percent buffered of the total duration in decimal form.
21234  */
21235 function bufferedPercent(buffered, duration) {
21236   var bufferedDuration = 0;
21237   var start = void 0;
21238   var end = void 0;
21240   if (!duration) {
21241     return 0;
21242   }
21244   if (!buffered || !buffered.length) {
21245     buffered = (0, _timeRanges.createTimeRange)(0, 0);
21246   }
21248   for (var i = 0; i < buffered.length; i++) {
21249     start = buffered.start(i);
21250     end = buffered.end(i);
21252     // buffered end can be bigger than duration by a very small fraction
21253     if (end > duration) {
21254       end = duration;
21255     }
21257     bufferedDuration += end - start;
21258   }
21260   return bufferedDuration / duration;
21261 } /**
21262    * @file buffer.js
21263    * @module buffer
21264    */
21266 },{"90":90}],80:[function(_dereq_,module,exports){
21267 'use strict';
21269 exports.__esModule = true;
21270 exports['default'] = computedStyle;
21272 var _window = _dereq_(95);
21274 var _window2 = _interopRequireDefault(_window);
21276 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21279  * A safe getComputedStyle with an IE8 fallback.
21281  * This is needed because in Firefox, if the player is loaded in an iframe with
21282  * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
21283  * make sure  that the player doesn't break in these cases.
21285  * @param {Element} el
21286  *        The element you want the computed style of
21288  * @param {string} prop
21289  *        The property name you want
21291  * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
21292  */
21293 function computedStyle(el, prop) {
21294   if (!el || !prop) {
21295     return '';
21296   }
21298   if (typeof _window2['default'].getComputedStyle === 'function') {
21299     var cs = _window2['default'].getComputedStyle(el);
21301     return cs ? cs[prop] : '';
21302   }
21304   return el.currentStyle[prop] || '';
21305 } /**
21306    * @file computed-style.js
21307    * @module computed-style
21308    */
21310 },{"95":95}],81:[function(_dereq_,module,exports){
21311 'use strict';
21313 exports.__esModule = true;
21314 exports.$$ = exports.$ = undefined;
21316 var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n                has been deprecated. Use the third argument instead.\n                createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n                has been deprecated. Use the third argument instead.\n                createEl(type, properties, attributes). Attempting to set ', ' to ', '.']);
21318 exports.isReal = isReal;
21319 exports.isEl = isEl;
21320 exports.getEl = getEl;
21321 exports.createEl = createEl;
21322 exports.textContent = textContent;
21323 exports.insertElFirst = insertElFirst;
21324 exports.getElData = getElData;
21325 exports.hasElData = hasElData;
21326 exports.removeElData = removeElData;
21327 exports.hasElClass = hasElClass;
21328 exports.addElClass = addElClass;
21329 exports.removeElClass = removeElClass;
21330 exports.toggleElClass = toggleElClass;
21331 exports.setElAttributes = setElAttributes;
21332 exports.getElAttributes = getElAttributes;
21333 exports.getAttribute = getAttribute;
21334 exports.setAttribute = setAttribute;
21335 exports.removeAttribute = removeAttribute;
21336 exports.blockTextSelection = blockTextSelection;
21337 exports.unblockTextSelection = unblockTextSelection;
21338 exports.findElPosition = findElPosition;
21339 exports.getPointerPosition = getPointerPosition;
21340 exports.isTextNode = isTextNode;
21341 exports.emptyEl = emptyEl;
21342 exports.normalizeContent = normalizeContent;
21343 exports.appendContent = appendContent;
21344 exports.insertContent = insertContent;
21346 var _document = _dereq_(94);
21348 var _document2 = _interopRequireDefault(_document);
21350 var _window = _dereq_(95);
21352 var _window2 = _interopRequireDefault(_window);
21354 var _guid = _dereq_(85);
21356 var Guid = _interopRequireWildcard(_guid);
21358 var _log = _dereq_(86);
21360 var _log2 = _interopRequireDefault(_log);
21362 var _tsml = _dereq_(98);
21364 var _tsml2 = _interopRequireDefault(_tsml);
21366 var _obj = _dereq_(88);
21368 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21370 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21372 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
21373                                                                                            * @file dom.js
21374                                                                                            * @module dom
21375                                                                                            */
21379  * Detect if a value is a string with any non-whitespace characters.
21381  * @param {string} str
21382  *        The string to check
21384  * @return {boolean}
21385  *         - True if the string is non-blank
21386  *         - False otherwise
21388  */
21389 function isNonBlankString(str) {
21390   return typeof str === 'string' && /\S/.test(str);
21394  * Throws an error if the passed string has whitespace. This is used by
21395  * class methods to be relatively consistent with the classList API.
21397  * @param {string} str
21398  *         The string to check for whitespace.
21400  * @throws {Error}
21401  *         Throws an error if there is whitespace in the string.
21403  */
21404 function throwIfWhitespace(str) {
21405   if (/\s/.test(str)) {
21406     throw new Error('class has illegal whitespace characters');
21407   }
21411  * Produce a regular expression for matching a className within an elements className.
21413  * @param {string} className
21414  *         The className to generate the RegExp for.
21416  * @return {RegExp}
21417  *         The RegExp that will check for a specific `className` in an elements
21418  *         className.
21419  */
21420 function classRegExp(className) {
21421   return new RegExp('(^|\\s)' + className + '($|\\s)');
21425  * Whether the current DOM interface appears to be real.
21427  * @return {Boolean}
21428  */
21429 function isReal() {
21430   return (
21432     // Both document and window will never be undefined thanks to `global`.
21433     _document2['default'] === _window2['default'].document &&
21435     // In IE < 9, DOM methods return "object" as their type, so all we can
21436     // confidently check is that it exists.
21437     typeof _document2['default'].createElement !== 'undefined'
21438   );
21442  * Determines, via duck typing, whether or not a value is a DOM element.
21444  * @param {Mixed} value
21445  *        The thing to check
21447  * @return {boolean}
21448  *         - True if it is a DOM element
21449  *         - False otherwise
21450  */
21451 function isEl(value) {
21452   return (0, _obj.isObject)(value) && value.nodeType === 1;
21456  * Creates functions to query the DOM using a given method.
21458  * @param {string} method
21459  *         The method to create the query with.
21461  * @return {Function}
21462  *         The query method
21463  */
21464 function createQuerier(method) {
21465   return function (selector, context) {
21466     if (!isNonBlankString(selector)) {
21467       return _document2['default'][method](null);
21468     }
21469     if (isNonBlankString(context)) {
21470       context = _document2['default'].querySelector(context);
21471     }
21473     var ctx = isEl(context) ? context : _document2['default'];
21475     return ctx[method] && ctx[method](selector);
21476   };
21480  * Shorthand for document.getElementById()
21481  * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
21483  * @param {string} id
21484  *         The id of the element to get
21486  * @return {Element|null}
21487  *         Element with supplied ID or null if there wasn't one.
21488  */
21489 function getEl(id) {
21490   if (id.indexOf('#') === 0) {
21491     id = id.slice(1);
21492   }
21494   return _document2['default'].getElementById(id);
21498  * Creates an element and applies properties.
21500  * @param {string} [tagName='div']
21501  *         Name of tag to be created.
21503  * @param {Object} [properties={}]
21504  *         Element properties to be applied.
21506  * @param {Object} [attributes={}]
21507  *         Element attributes to be applied.
21509  * @param {String|Element|TextNode|Array|Function} [content]
21510  *         Contents for the element (see: {@link dom:normalizeContent})
21512  * @return {Element}
21513  *         The element that was created.
21514  */
21515 function createEl() {
21516   var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
21517   var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
21518   var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
21519   var content = arguments[3];
21521   var el = _document2['default'].createElement(tagName);
21523   Object.getOwnPropertyNames(properties).forEach(function (propName) {
21524     var val = properties[propName];
21526     // See #2176
21527     // We originally were accepting both properties and attributes in the
21528     // same object, but that doesn't work so well.
21529     if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
21530       _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
21531       el.setAttribute(propName, val);
21533       // Handle textContent since it's not supported everywhere and we have a
21534       // method for it.
21535     } else if (propName === 'textContent') {
21536       textContent(el, val);
21537     } else {
21538       el[propName] = val;
21539     }
21540   });
21542   Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21543     el.setAttribute(attrName, attributes[attrName]);
21544   });
21546   if (content) {
21547     appendContent(el, content);
21548   }
21550   return el;
21554  * Injects text into an element, replacing any existing contents entirely.
21556  * @param {Element} el
21557  *        The element to add text content into
21559  * @param {string} text
21560  *        The text content to add.
21562  * @return {Element}
21563  *         The element with added text content.
21564  */
21565 function textContent(el, text) {
21566   if (typeof el.textContent === 'undefined') {
21567     el.innerText = text;
21568   } else {
21569     el.textContent = text;
21570   }
21571   return el;
21575  * Insert an element as the first child node of another
21577  * @param {Element} child
21578  *        Element to insert
21580  * @param {Element} parent
21581  *        Element to insert child into
21583  */
21584 function insertElFirst(child, parent) {
21585   if (parent.firstChild) {
21586     parent.insertBefore(child, parent.firstChild);
21587   } else {
21588     parent.appendChild(child);
21589   }
21593  * Element Data Store. Allows for binding data to an element without putting it directly on the element.
21594  * Ex. Event listeners are stored here.
21595  * (also from jsninja.com, slightly modified and updated for closure compiler)
21597  * @type {Object}
21598  * @private
21599  */
21600 var elData = {};
21603  * Unique attribute name to store an element's guid in
21605  * @type {string}
21606  * @constant
21607  * @private
21608  */
21609 var elIdAttr = 'vdata' + new Date().getTime();
21612  * Returns the cache object where data for an element is stored
21614  * @param {Element} el
21615  *        Element to store data for.
21617  * @return {Object}
21618  *         The cache object for that el that was passed in.
21619  */
21620 function getElData(el) {
21621   var id = el[elIdAttr];
21623   if (!id) {
21624     id = el[elIdAttr] = Guid.newGUID();
21625   }
21627   if (!elData[id]) {
21628     elData[id] = {};
21629   }
21631   return elData[id];
21635  * Returns whether or not an element has cached data
21637  * @param {Element} el
21638  *        Check if this element has cached data.
21640  * @return {boolean}
21641  *         - True if the DOM element has cached data.
21642  *         - False otherwise.
21643  */
21644 function hasElData(el) {
21645   var id = el[elIdAttr];
21647   if (!id) {
21648     return false;
21649   }
21651   return !!Object.getOwnPropertyNames(elData[id]).length;
21655  * Delete data for the element from the cache and the guid attr from getElementById
21657  * @param {Element} el
21658  *        Remove cached data for this element.
21659  */
21660 function removeElData(el) {
21661   var id = el[elIdAttr];
21663   if (!id) {
21664     return;
21665   }
21667   // Remove all stored data
21668   delete elData[id];
21670   // Remove the elIdAttr property from the DOM node
21671   try {
21672     delete el[elIdAttr];
21673   } catch (e) {
21674     if (el.removeAttribute) {
21675       el.removeAttribute(elIdAttr);
21676     } else {
21677       // IE doesn't appear to support removeAttribute on the document element
21678       el[elIdAttr] = null;
21679     }
21680   }
21684  * Check if an element has a CSS class
21686  * @param {Element} element
21687  *        Element to check
21689  * @param {string} classToCheck
21690  *        Class name to check for
21692  * @return {boolean}
21693  *         - True if the element had the class
21694  *         - False otherwise.
21696  * @throws {Error}
21697  *         Throws an error if `classToCheck` has white space.
21698  */
21699 function hasElClass(element, classToCheck) {
21700   throwIfWhitespace(classToCheck);
21701   if (element.classList) {
21702     return element.classList.contains(classToCheck);
21703   }
21704   return classRegExp(classToCheck).test(element.className);
21708  * Add a CSS class name to an element
21710  * @param {Element} element
21711  *        Element to add class name to.
21713  * @param {string} classToAdd
21714  *        Class name to add.
21716  * @return {Element}
21717  *         The dom element with the added class name.
21718  */
21719 function addElClass(element, classToAdd) {
21720   if (element.classList) {
21721     element.classList.add(classToAdd);
21723     // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
21724     // in the case of classList not being supported.
21725   } else if (!hasElClass(element, classToAdd)) {
21726     element.className = (element.className + ' ' + classToAdd).trim();
21727   }
21729   return element;
21733  * Remove a CSS class name from an element
21735  * @param {Element} element
21736  *        Element to remove a class name from.
21738  * @param {string} classToRemove
21739  *        Class name to remove
21741  * @return {Element}
21742  *         The dom element with class name removed.
21743  */
21744 function removeElClass(element, classToRemove) {
21745   if (element.classList) {
21746     element.classList.remove(classToRemove);
21747   } else {
21748     throwIfWhitespace(classToRemove);
21749     element.className = element.className.split(/\s+/).filter(function (c) {
21750       return c !== classToRemove;
21751     }).join(' ');
21752   }
21754   return element;
21758  * The callback definition for toggleElClass.
21760  * @callback Dom~PredicateCallback
21761  * @param {Element} element
21762  *        The DOM element of the Component.
21764  * @param {string} classToToggle
21765  *        The `className` that wants to be toggled
21767  * @return {boolean|undefined}
21768  *         - If true the `classToToggle` will get added to `element`.
21769  *         - If false the `classToToggle` will get removed from `element`.
21770  *         - If undefined this callback will be ignored
21771  */
21774  * Adds or removes a CSS class name on an element depending on an optional
21775  * condition or the presence/absence of the class name.
21777  * @param {Element} element
21778  *        The element to toggle a class name on.
21780  * @param {string} classToToggle
21781  *        The class that should be toggled
21783  * @param {boolean|PredicateCallback} [predicate]
21784  *        See the return value for {@link Dom~PredicateCallback}
21786  * @return {Element}
21787  *         The element with a class that has been toggled.
21788  */
21789 function toggleElClass(element, classToToggle, predicate) {
21791   // This CANNOT use `classList` internally because IE does not support the
21792   // second parameter to the `classList.toggle()` method! Which is fine because
21793   // `classList` will be used by the add/remove functions.
21794   var has = hasElClass(element, classToToggle);
21796   if (typeof predicate === 'function') {
21797     predicate = predicate(element, classToToggle);
21798   }
21800   if (typeof predicate !== 'boolean') {
21801     predicate = !has;
21802   }
21804   // If the necessary class operation matches the current state of the
21805   // element, no action is required.
21806   if (predicate === has) {
21807     return;
21808   }
21810   if (predicate) {
21811     addElClass(element, classToToggle);
21812   } else {
21813     removeElClass(element, classToToggle);
21814   }
21816   return element;
21820  * Apply attributes to an HTML element.
21822  * @param {Element} el
21823  *        Element to add attributes to.
21825  * @param {Object} [attributes]
21826  *        Attributes to be applied.
21827  */
21828 function setElAttributes(el, attributes) {
21829   Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21830     var attrValue = attributes[attrName];
21832     if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
21833       el.removeAttribute(attrName);
21834     } else {
21835       el.setAttribute(attrName, attrValue === true ? '' : attrValue);
21836     }
21837   });
21841  * Get an element's attribute values, as defined on the HTML tag
21842  * Attributes are not the same as properties. They're defined on the tag
21843  * or with setAttribute (which shouldn't be used with HTML)
21844  * This will return true or false for boolean attributes.
21846  * @param {Element} tag
21847  *        Element from which to get tag attributes.
21849  * @return {Object}
21850  *         All attributes of the element.
21851  */
21852 function getElAttributes(tag) {
21853   var obj = {};
21855   // known boolean attributes
21856   // we can check for matching boolean properties, but older browsers
21857   // won't know about HTML5 boolean attributes that we still read from
21858   var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
21860   if (tag && tag.attributes && tag.attributes.length > 0) {
21861     var attrs = tag.attributes;
21863     for (var i = attrs.length - 1; i >= 0; i--) {
21864       var attrName = attrs[i].name;
21865       var attrVal = attrs[i].value;
21867       // check for known booleans
21868       // the matching element property will return a value for typeof
21869       if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
21870         // the value of an included boolean attribute is typically an empty
21871         // string ('') which would equal false if we just check for a false value.
21872         // we also don't want support bad code like autoplay='false'
21873         attrVal = attrVal !== null ? true : false;
21874       }
21876       obj[attrName] = attrVal;
21877     }
21878   }
21880   return obj;
21884  * Get the value of an element's attribute
21886  * @param {Element} el
21887  *        A DOM element
21889  * @param {string} attribute
21890  *        Attribute to get the value of
21892  * @return {string}
21893  *         value of the attribute
21894  */
21895 function getAttribute(el, attribute) {
21896   return el.getAttribute(attribute);
21900  * Set the value of an element's attribute
21902  * @param {Element} el
21903  *        A DOM element
21905  * @param {string} attribute
21906  *        Attribute to set
21908  * @param {string} value
21909  *        Value to set the attribute to
21910  */
21911 function setAttribute(el, attribute, value) {
21912   el.setAttribute(attribute, value);
21916  * Remove an element's attribute
21918  * @param {Element} el
21919  *        A DOM element
21921  * @param {string} attribute
21922  *        Attribute to remove
21923  */
21924 function removeAttribute(el, attribute) {
21925   el.removeAttribute(attribute);
21929  * Attempt to block the ability to select text while dragging controls
21930  */
21931 function blockTextSelection() {
21932   _document2['default'].body.focus();
21933   _document2['default'].onselectstart = function () {
21934     return false;
21935   };
21939  * Turn off text selection blocking
21940  */
21941 function unblockTextSelection() {
21942   _document2['default'].onselectstart = function () {
21943     return true;
21944   };
21948  * The position of a DOM element on the page.
21950  * @typedef {Object} Dom~Position
21952  * @property {number} left
21953  *           Pixels to the left
21955  * @property {number} top
21956  *           Pixels on top
21957  */
21960  * Offset Left.
21961  * getBoundingClientRect technique from
21962  * John Resig
21964  * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
21966  * @param {Element} el
21967  *        Element from which to get offset
21969  * @return {Dom~Position}
21970  *         The position of the element that was passed in.
21971  */
21972 function findElPosition(el) {
21973   var box = void 0;
21975   if (el.getBoundingClientRect && el.parentNode) {
21976     box = el.getBoundingClientRect();
21977   }
21979   if (!box) {
21980     return {
21981       left: 0,
21982       top: 0
21983     };
21984   }
21986   var docEl = _document2['default'].documentElement;
21987   var body = _document2['default'].body;
21989   var clientLeft = docEl.clientLeft || body.clientLeft || 0;
21990   var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
21991   var left = box.left + scrollLeft - clientLeft;
21993   var clientTop = docEl.clientTop || body.clientTop || 0;
21994   var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
21995   var top = box.top + scrollTop - clientTop;
21997   // Android sometimes returns slightly off decimal values, so need to round
21998   return {
21999     left: Math.round(left),
22000     top: Math.round(top)
22001   };
22005  * x and y coordinates for a dom element or mouse pointer
22007  * @typedef {Object} Dom~Coordinates
22009  * @property {number} x
22010  *           x coordinate in pixels
22012  * @property {number} y
22013  *           y coordinate in pixels
22014  */
22017  * Get pointer position in element
22018  * Returns an object with x and y coordinates.
22019  * The base on the coordinates are the bottom left of the element.
22021  * @param {Element} el
22022  *        Element on which to get the pointer position on
22024  * @param {EventTarget~Event} event
22025  *        Event object
22027  * @return {Dom~Coordinates}
22028  *         A Coordinates object corresponding to the mouse position.
22030  */
22031 function getPointerPosition(el, event) {
22032   var position = {};
22033   var box = findElPosition(el);
22034   var boxW = el.offsetWidth;
22035   var boxH = el.offsetHeight;
22037   var boxY = box.top;
22038   var boxX = box.left;
22039   var pageY = event.pageY;
22040   var pageX = event.pageX;
22042   if (event.changedTouches) {
22043     pageX = event.changedTouches[0].pageX;
22044     pageY = event.changedTouches[0].pageY;
22045   }
22047   position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
22048   position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
22050   return position;
22054  * Determines, via duck typing, whether or not a value is a text node.
22056  * @param {Mixed} value
22057  *        Check if this value is a text node.
22059  * @return {boolean}
22060  *         - True if it is a text node
22061  *         - False otherwise
22062  */
22063 function isTextNode(value) {
22064   return (0, _obj.isObject)(value) && value.nodeType === 3;
22068  * Empties the contents of an element.
22070  * @param {Element} el
22071  *        The element to empty children from
22073  * @return {Element}
22074  *         The element with no children
22075  */
22076 function emptyEl(el) {
22077   while (el.firstChild) {
22078     el.removeChild(el.firstChild);
22079   }
22080   return el;
22084  * Normalizes content for eventual insertion into the DOM.
22086  * This allows a wide range of content definition methods, but protects
22087  * from falling into the trap of simply writing to `innerHTML`, which is
22088  * an XSS concern.
22090  * The content for an element can be passed in multiple types and
22091  * combinations, whose behavior is as follows:
22093  * @param {String|Element|TextNode|Array|Function} content
22094  *        - String: Normalized into a text node.
22095  *        - Element/TextNode: Passed through.
22096  *        - Array: A one-dimensional array of strings, elements, nodes, or functions
22097  *          (which return single strings, elements, or nodes).
22098  *        - Function: If the sole argument, is expected to produce a string, element,
22099  *          node, or array as defined above.
22101  * @return {Array}
22102  *         All of the content that was passed in normalized.
22103  */
22104 function normalizeContent(content) {
22106   // First, invoke content if it is a function. If it produces an array,
22107   // that needs to happen before normalization.
22108   if (typeof content === 'function') {
22109     content = content();
22110   }
22112   // Next up, normalize to an array, so one or many items can be normalized,
22113   // filtered, and returned.
22114   return (Array.isArray(content) ? content : [content]).map(function (value) {
22116     // First, invoke value if it is a function to produce a new value,
22117     // which will be subsequently normalized to a Node of some kind.
22118     if (typeof value === 'function') {
22119       value = value();
22120     }
22122     if (isEl(value) || isTextNode(value)) {
22123       return value;
22124     }
22126     if (typeof value === 'string' && /\S/.test(value)) {
22127       return _document2['default'].createTextNode(value);
22128     }
22129   }).filter(function (value) {
22130     return value;
22131   });
22135  * Normalizes and appends content to an element.
22137  * @param {Element} el
22138  *        Element to append normalized content to.
22141  * @param {String|Element|TextNode|Array|Function} content
22142  *        See the `content` argument of {@link dom:normalizeContent}
22144  * @return {Element}
22145  *         The element with appended normalized content.
22146  */
22147 function appendContent(el, content) {
22148   normalizeContent(content).forEach(function (node) {
22149     return el.appendChild(node);
22150   });
22151   return el;
22155  * Normalizes and inserts content into an element; this is identical to
22156  * `appendContent()`, except it empties the element first.
22158  * @param {Element} el
22159  *        Element to insert normalized content into.
22161  * @param {String|Element|TextNode|Array|Function} content
22162  *        See the `content` argument of {@link dom:normalizeContent}
22164  * @return {Element}
22165  *         The element with inserted normalized content.
22167  */
22168 function insertContent(el, content) {
22169   return appendContent(emptyEl(el), content);
22173  * Finds a single DOM element matching `selector` within the optional
22174  * `context` of another DOM element (defaulting to `document`).
22176  * @param {string} selector
22177  *        A valid CSS selector, which will be passed to `querySelector`.
22179  * @param {Element|String} [context=document]
22180  *        A DOM element within which to query. Can also be a selector
22181  *        string in which case the first matching element will be used
22182  *        as context. If missing (or no element matches selector), falls
22183  *        back to `document`.
22185  * @return {Element|null}
22186  *         The element that was found or null.
22187  */
22188 var $ = exports.$ = createQuerier('querySelector');
22191  * Finds a all DOM elements matching `selector` within the optional
22192  * `context` of another DOM element (defaulting to `document`).
22194  * @param {string} selector
22195  *           A valid CSS selector, which will be passed to `querySelectorAll`.
22197  * @param {Element|String} [context=document]
22198  *           A DOM element within which to query. Can also be a selector
22199  *           string in which case the first matching element will be used
22200  *           as context. If missing (or no element matches selector), falls
22201  *           back to `document`.
22203  * @return {NodeList}
22204  *         A element list of elements that were found. Will be empty if none were found.
22206  */
22207 var $$ = exports.$$ = createQuerier('querySelectorAll');
22209 },{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){
22210 'use strict';
22212 exports.__esModule = true;
22213 exports.fixEvent = fixEvent;
22214 exports.on = on;
22215 exports.off = off;
22216 exports.trigger = trigger;
22217 exports.one = one;
22219 var _dom = _dereq_(81);
22221 var Dom = _interopRequireWildcard(_dom);
22223 var _guid = _dereq_(85);
22225 var Guid = _interopRequireWildcard(_guid);
22227 var _log = _dereq_(86);
22229 var _log2 = _interopRequireDefault(_log);
22231 var _window = _dereq_(95);
22233 var _window2 = _interopRequireDefault(_window);
22235 var _document = _dereq_(94);
22237 var _document2 = _interopRequireDefault(_document);
22239 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22241 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
22244  * Clean up the listener cache and dispatchers
22246  * @param {Element|Object} elem
22247  *        Element to clean up
22249  * @param {string} type
22250  *        Type of event to clean up
22251  */
22252 function _cleanUpEvents(elem, type) {
22253   var data = Dom.getElData(elem);
22255   // Remove the events of a particular type if there are none left
22256   if (data.handlers[type].length === 0) {
22257     delete data.handlers[type];
22258     // data.handlers[type] = null;
22259     // Setting to null was causing an error with data.handlers
22261     // Remove the meta-handler from the element
22262     if (elem.removeEventListener) {
22263       elem.removeEventListener(type, data.dispatcher, false);
22264     } else if (elem.detachEvent) {
22265       elem.detachEvent('on' + type, data.dispatcher);
22266     }
22267   }
22269   // Remove the events object if there are no types left
22270   if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
22271     delete data.handlers;
22272     delete data.dispatcher;
22273     delete data.disabled;
22274   }
22276   // Finally remove the element data if there is no data left
22277   if (Object.getOwnPropertyNames(data).length === 0) {
22278     Dom.removeElData(elem);
22279   }
22283  * Loops through an array of event types and calls the requested method for each type.
22285  * @param {Function} fn
22286  *        The event method we want to use.
22288  * @param {Element|Object} elem
22289  *        Element or object to bind listeners to
22291  * @param {string} type
22292  *        Type of event to bind to.
22294  * @param {EventTarget~EventListener} callback
22295  *        Event listener.
22296  */
22298  * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
22299  * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
22300  * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
22301  * robust as jquery's, so there's probably some differences.
22303  * @module events
22304  */
22306 function _handleMultipleEvents(fn, elem, types, callback) {
22307   types.forEach(function (type) {
22308     // Call the event method for each one of the types
22309     fn(elem, type, callback);
22310   });
22314  * Fix a native event to have standard property values
22316  * @param {Object} event
22317  *        Event object to fix.
22319  * @return {Object}
22320  *         Fixed event object.
22321  */
22322 function fixEvent(event) {
22324   function returnTrue() {
22325     return true;
22326   }
22328   function returnFalse() {
22329     return false;
22330   }
22332   // Test if fixing up is needed
22333   // Used to check if !event.stopPropagation instead of isPropagationStopped
22334   // But native events return true for stopPropagation, but don't have
22335   // other expected methods like isPropagationStopped. Seems to be a problem
22336   // with the Javascript Ninja code. So we're just overriding all events now.
22337   if (!event || !event.isPropagationStopped) {
22338     (function () {
22339       var old = event || _window2['default'].event;
22341       event = {};
22342       // Clone the old object so that we can modify the values event = {};
22343       // IE8 Doesn't like when you mess with native event properties
22344       // Firefox returns false for event.hasOwnProperty('type') and other props
22345       //  which makes copying more difficult.
22346       // TODO: Probably best to create a whitelist of event props
22347       for (var key in old) {
22348         // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
22349         // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
22350         // and webkitMovementX/Y
22351         if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
22352           // Chrome 32+ warns if you try to copy deprecated returnValue, but
22353           // we still want to if preventDefault isn't supported (IE8).
22354           if (!(key === 'returnValue' && old.preventDefault)) {
22355             event[key] = old[key];
22356           }
22357         }
22358       }
22360       // The event occurred on this element
22361       if (!event.target) {
22362         event.target = event.srcElement || _document2['default'];
22363       }
22365       // Handle which other element the event is related to
22366       if (!event.relatedTarget) {
22367         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
22368       }
22370       // Stop the default browser action
22371       event.preventDefault = function () {
22372         if (old.preventDefault) {
22373           old.preventDefault();
22374         }
22375         event.returnValue = false;
22376         old.returnValue = false;
22377         event.defaultPrevented = true;
22378       };
22380       event.defaultPrevented = false;
22382       // Stop the event from bubbling
22383       event.stopPropagation = function () {
22384         if (old.stopPropagation) {
22385           old.stopPropagation();
22386         }
22387         event.cancelBubble = true;
22388         old.cancelBubble = true;
22389         event.isPropagationStopped = returnTrue;
22390       };
22392       event.isPropagationStopped = returnFalse;
22394       // Stop the event from bubbling and executing other handlers
22395       event.stopImmediatePropagation = function () {
22396         if (old.stopImmediatePropagation) {
22397           old.stopImmediatePropagation();
22398         }
22399         event.isImmediatePropagationStopped = returnTrue;
22400         event.stopPropagation();
22401       };
22403       event.isImmediatePropagationStopped = returnFalse;
22405       // Handle mouse position
22406       if (event.clientX !== null && event.clientX !== undefined) {
22407         var doc = _document2['default'].documentElement;
22408         var body = _document2['default'].body;
22410         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
22411         event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
22412       }
22414       // Handle key presses
22415       event.which = event.charCode || event.keyCode;
22417       // Fix button for mouse clicks:
22418       // 0 == left; 1 == middle; 2 == right
22419       if (event.button !== null && event.button !== undefined) {
22421         // The following is disabled because it does not pass videojs-standard
22422         // and... yikes.
22423         /* eslint-disable */
22424         event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
22425         /* eslint-enable */
22426       }
22427     })();
22428   }
22430   // Returns fixed-up instance
22431   return event;
22435  * Add an event listener to element
22436  * It stores the handler function in a separate cache object
22437  * and adds a generic handler to the element's event,
22438  * along with a unique id (guid) to the element.
22440  * @param {Element|Object} elem
22441  *        Element or object to bind listeners to
22443  * @param {string|string[]} type
22444  *        Type of event to bind to.
22446  * @param {EventTarget~EventListener} fn
22447  *        Event listener.
22448  */
22449 function on(elem, type, fn) {
22450   if (Array.isArray(type)) {
22451     return _handleMultipleEvents(on, elem, type, fn);
22452   }
22454   var data = Dom.getElData(elem);
22456   // We need a place to store all our handler data
22457   if (!data.handlers) {
22458     data.handlers = {};
22459   }
22461   if (!data.handlers[type]) {
22462     data.handlers[type] = [];
22463   }
22465   if (!fn.guid) {
22466     fn.guid = Guid.newGUID();
22467   }
22469   data.handlers[type].push(fn);
22471   if (!data.dispatcher) {
22472     data.disabled = false;
22474     data.dispatcher = function (event, hash) {
22476       if (data.disabled) {
22477         return;
22478       }
22480       event = fixEvent(event);
22482       var handlers = data.handlers[event.type];
22484       if (handlers) {
22485         // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
22486         var handlersCopy = handlers.slice(0);
22488         for (var m = 0, n = handlersCopy.length; m < n; m++) {
22489           if (event.isImmediatePropagationStopped()) {
22490             break;
22491           } else {
22492             try {
22493               handlersCopy[m].call(elem, event, hash);
22494             } catch (e) {
22495               _log2['default'].error(e);
22496             }
22497           }
22498         }
22499       }
22500     };
22501   }
22503   if (data.handlers[type].length === 1) {
22504     if (elem.addEventListener) {
22505       elem.addEventListener(type, data.dispatcher, false);
22506     } else if (elem.attachEvent) {
22507       elem.attachEvent('on' + type, data.dispatcher);
22508     }
22509   }
22513  * Removes event listeners from an element
22515  * @param {Element|Object} elem
22516  *        Object to remove listeners from.
22518  * @param {string|string[]} [type]
22519  *        Type of listener to remove. Don't include to remove all events from element.
22521  * @param {EventTarget~EventListener} [fn]
22522  *        Specific listener to remove. Don't include to remove listeners for an event
22523  *        type.
22524  */
22525 function off(elem, type, fn) {
22526   // Don't want to add a cache object through getElData if not needed
22527   if (!Dom.hasElData(elem)) {
22528     return;
22529   }
22531   var data = Dom.getElData(elem);
22533   // If no events exist, nothing to unbind
22534   if (!data.handlers) {
22535     return;
22536   }
22538   if (Array.isArray(type)) {
22539     return _handleMultipleEvents(off, elem, type, fn);
22540   }
22542   // Utility function
22543   var removeType = function removeType(t) {
22544     data.handlers[t] = [];
22545     _cleanUpEvents(elem, t);
22546   };
22548   // Are we removing all bound events?
22549   if (!type) {
22550     for (var t in data.handlers) {
22551       removeType(t);
22552     }
22553     return;
22554   }
22556   var handlers = data.handlers[type];
22558   // If no handlers exist, nothing to unbind
22559   if (!handlers) {
22560     return;
22561   }
22563   // If no listener was provided, remove all listeners for type
22564   if (!fn) {
22565     removeType(type);
22566     return;
22567   }
22569   // We're only removing a single handler
22570   if (fn.guid) {
22571     for (var n = 0; n < handlers.length; n++) {
22572       if (handlers[n].guid === fn.guid) {
22573         handlers.splice(n--, 1);
22574       }
22575     }
22576   }
22578   _cleanUpEvents(elem, type);
22582  * Trigger an event for an element
22584  * @param {Element|Object} elem
22585  *        Element to trigger an event on
22587  * @param {EventTarget~Event|string} event
22588  *        A string (the type) or an event object with a type attribute
22590  * @param {Object} [hash]
22591  *        data hash to pass along with the event
22593  * @return {boolean|undefined}
22594  *         - Returns the opposite of `defaultPrevented` if default was prevented
22595  *         - Otherwise returns undefined
22596  */
22597 function trigger(elem, event, hash) {
22598   // Fetches element data and a reference to the parent (for bubbling).
22599   // Don't want to add a data object to cache for every parent,
22600   // so checking hasElData first.
22601   var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
22602   var parent = elem.parentNode || elem.ownerDocument;
22603   // type = event.type || event,
22604   // handler;
22606   // If an event name was passed as a string, creates an event out of it
22607   if (typeof event === 'string') {
22608     event = { type: event, target: elem };
22609   }
22610   // Normalizes the event properties.
22611   event = fixEvent(event);
22613   // If the passed element has a dispatcher, executes the established handlers.
22614   if (elemData.dispatcher) {
22615     elemData.dispatcher.call(elem, event, hash);
22616   }
22618   // Unless explicitly stopped or the event does not bubble (e.g. media events)
22619   // recursively calls this function to bubble the event up the DOM.
22620   if (parent && !event.isPropagationStopped() && event.bubbles === true) {
22621     trigger.call(null, parent, event, hash);
22623     // If at the top of the DOM, triggers the default action unless disabled.
22624   } else if (!parent && !event.defaultPrevented) {
22625     var targetData = Dom.getElData(event.target);
22627     // Checks if the target has a default action for this event.
22628     if (event.target[event.type]) {
22629       // Temporarily disables event dispatching on the target as we have already executed the handler.
22630       targetData.disabled = true;
22631       // Executes the default action.
22632       if (typeof event.target[event.type] === 'function') {
22633         event.target[event.type]();
22634       }
22635       // Re-enables event dispatching.
22636       targetData.disabled = false;
22637     }
22638   }
22640   // Inform the triggerer if the default was prevented by returning false
22641   return !event.defaultPrevented;
22645  * Trigger a listener only once for an event
22647  * @param {Element|Object} elem
22648  *        Element or object to bind to.
22650  * @param {string|string[]} type
22651  *        Name/type of event
22653  * @param {Event~EventListener} fn
22654  *        Event Listener function
22655  */
22656 function one(elem, type, fn) {
22657   if (Array.isArray(type)) {
22658     return _handleMultipleEvents(one, elem, type, fn);
22659   }
22660   var func = function func() {
22661     off(elem, type, func);
22662     fn.apply(this, arguments);
22663   };
22665   // copy the guid to the new function so it can removed using the original function's ID
22666   func.guid = fn.guid = fn.guid || Guid.newGUID();
22667   on(elem, type, func);
22670 },{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){
22671 'use strict';
22673 exports.__esModule = true;
22674 exports.throttle = exports.bind = undefined;
22676 var _guid = _dereq_(85);
22679  * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
22680  * It also stores a unique id on the function so it can be easily removed from events.
22682  * @param {Mixed} context
22683  *        The object to bind as scope.
22685  * @param {Function} fn
22686  *        The function to be bound to a scope.
22688  * @param {number} [uid]
22689  *        An optional unique ID for the function to be set
22691  * @return {Function}
22692  *         The new function that will be bound into the context given
22693  */
22694 var bind = exports.bind = function bind(context, fn, uid) {
22695   // Make sure the function has a unique ID
22696   if (!fn.guid) {
22697     fn.guid = (0, _guid.newGUID)();
22698   }
22700   // Create the new function that changes the context
22701   var bound = function bound() {
22702     return fn.apply(context, arguments);
22703   };
22705   // Allow for the ability to individualize this function
22706   // Needed in the case where multiple objects might share the same prototype
22707   // IF both items add an event listener with the same function, then you try to remove just one
22708   // it will remove both because they both have the same guid.
22709   // when using this, you need to use the bind method when you remove the listener as well.
22710   // currently used in text tracks
22711   bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
22713   return bound;
22717  * Wraps the given function, `fn`, with a new function that only invokes `fn`
22718  * at most once per every `wait` milliseconds.
22720  * @param  {Function} fn
22721  *         The function to be throttled.
22723  * @param  {Number}   wait
22724  *         The number of milliseconds by which to throttle.
22726  * @return {Function}
22727  */
22729  * @file fn.js
22730  * @module fn
22731  */
22732 var throttle = exports.throttle = function throttle(fn, wait) {
22733   var last = Date.now();
22735   var throttled = function throttled() {
22736     var now = Date.now();
22738     if (now - last >= wait) {
22739       fn.apply(undefined, arguments);
22740       last = now;
22741     }
22742   };
22744   return throttled;
22747 },{"85":85}],84:[function(_dereq_,module,exports){
22748 'use strict';
22750 exports.__esModule = true;
22752  * @file format-time.js
22753  * @module Format-time
22754  */
22757  * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
22758  * will force a number of leading zeros to cover the length of the guide.
22760  * @param {number} seconds
22761  *        Number of seconds to be turned into a string
22763  * @param {number} guide
22764  *        Number (in seconds) to model the string after
22766  * @return {string}
22767  *         Time formatted as H:MM:SS or M:SS
22768  */
22769 function formatTime(seconds) {
22770   var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
22772   seconds = seconds < 0 ? 0 : seconds;
22773   var s = Math.floor(seconds % 60);
22774   var m = Math.floor(seconds / 60 % 60);
22775   var h = Math.floor(seconds / 3600);
22776   var gm = Math.floor(guide / 60 % 60);
22777   var gh = Math.floor(guide / 3600);
22779   // handle invalid times
22780   if (isNaN(seconds) || seconds === Infinity) {
22781     // '-' is false for all relational operators (e.g. <, >=) so this setting
22782     // will add the minimum number of fields specified by the guide
22783     h = m = s = '-';
22784   }
22786   // Check if we need to show hours
22787   h = h > 0 || gh > 0 ? h + ':' : '';
22789   // If hours are showing, we may need to add a leading zero.
22790   // Always show at least one digit of minutes.
22791   m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
22793   // Check if leading zero is need for seconds
22794   s = s < 10 ? '0' + s : s;
22796   return h + m + s;
22799 exports['default'] = formatTime;
22801 },{}],85:[function(_dereq_,module,exports){
22802 "use strict";
22804 exports.__esModule = true;
22805 exports.newGUID = newGUID;
22807  * @file guid.js
22808  * @module guid
22809  */
22812  * Unique ID for an element or function
22813  * @type {Number}
22814  */
22815 var _guid = 1;
22818  * Get a unique auto-incrementing ID by number that has not been returned before.
22820  * @return {number}
22821  *         A new unique ID.
22822  */
22823 function newGUID() {
22824   return _guid++;
22827 },{}],86:[function(_dereq_,module,exports){
22828 'use strict';
22830 exports.__esModule = true;
22831 exports.logByType = undefined;
22833 var _window = _dereq_(95);
22835 var _window2 = _interopRequireDefault(_window);
22837 var _browser = _dereq_(78);
22839 var _obj = _dereq_(88);
22841 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22843 var log = void 0;
22846  * Log messages to the console and history based on the type of message
22848  * @param  {string} type
22849  *         The name of the console method to use.
22851  * @param  {Array} args
22852  *         The arguments to be passed to the matching console method.
22854  * @param  {boolean} [stringify]
22855  *         By default, only old IEs should get console argument stringification,
22856  *         but this is exposed as a parameter to facilitate testing.
22857  */
22859  * @file log.js
22860  * @module log
22861  */
22862 var logByType = exports.logByType = function logByType(type, args) {
22863   var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
22866   if (type !== 'log') {
22868     // add the type to the front of the message when it's not "log"
22869     args.unshift(type.toUpperCase() + ':');
22870   }
22872   // add to history
22873   log.history.push(args);
22875   // add console prefix after adding to history
22876   args.unshift('VIDEOJS:');
22878   // If there's no console then don't try to output messages, but they will
22879   // still be stored in `log.history`.
22880   //
22881   // Was setting these once outside of this function, but containing them
22882   // in the function makes it easier to test cases where console doesn't exist
22883   // when the module is executed.
22884   var fn = _window2['default'].console && _window2['default'].console[type];
22886   // Bail out if there's no console.
22887   if (!fn) {
22888     return;
22889   }
22891   // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
22892   // objects and arrays for those less-capable browsers.
22893   if (stringify) {
22894     args = args.map(function (a) {
22895       if ((0, _obj.isObject)(a) || Array.isArray(a)) {
22896         try {
22897           return JSON.stringify(a);
22898         } catch (x) {
22899           return String(a);
22900         }
22901       }
22903       // Cast to string before joining, so we get null and undefined explicitly
22904       // included in output (as we would in a modern console).
22905       return String(a);
22906     }).join(' ');
22907   }
22909   // Old IE versions do not allow .apply() for console methods (they are
22910   // reported as objects rather than functions).
22911   if (!fn.apply) {
22912     fn(args);
22913   } else {
22914     fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
22915   }
22919  * Log plain debug messages
22921  * @param {Mixed[]} args
22922  *        One or more messages or objects that should be logged.
22923  */
22924 log = function log() {
22925   for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
22926     args[_key] = arguments[_key];
22927   }
22929   logByType('log', args);
22933  * Keep a history of log messages
22935  * @type {Array}
22936  */
22937 log.history = [];
22940  * Log error messages
22942  * @param {Mixed[]} args
22943  *        One or more messages or objects that should be logged as an error
22944  */
22945 log.error = function () {
22946   for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22947     args[_key2] = arguments[_key2];
22948   }
22950   return logByType('error', args);
22954  * Log warning messages
22956  * @param {Mixed[]} args
22957  *        One or more messages or objects that should be logged as a warning.
22958  */
22959 log.warn = function () {
22960   for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
22961     args[_key3] = arguments[_key3];
22962   }
22964   return logByType('warn', args);
22967 exports['default'] = log;
22969 },{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){
22970 'use strict';
22972 exports.__esModule = true;
22973 exports['default'] = mergeOptions;
22975 var _obj = _dereq_(88);
22978  * Deep-merge one or more options objects, recursively merging **only** plain
22979  * object properties.
22981  * @param   {Object[]} sources
22982  *          One or more objects to merge into a new object.
22984  * @returns {Object}
22985  *          A new object that is the merged result of all sources.
22986  */
22987 function mergeOptions() {
22988   var result = {};
22990   for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
22991     sources[_key] = arguments[_key];
22992   }
22994   sources.forEach(function (source) {
22995     if (!source) {
22996       return;
22997     }
22999     (0, _obj.each)(source, function (value, key) {
23000       if (!(0, _obj.isPlain)(value)) {
23001         result[key] = value;
23002         return;
23003       }
23005       if (!(0, _obj.isPlain)(result[key])) {
23006         result[key] = {};
23007       }
23009       result[key] = mergeOptions(result[key], value);
23010     });
23011   });
23013   return result;
23014 } /**
23015    * @file merge-options.js
23016    * @module merge-options
23017    */
23019 },{"88":88}],88:[function(_dereq_,module,exports){
23020 'use strict';
23022 exports.__esModule = true;
23024 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
23026 exports.each = each;
23027 exports.reduce = reduce;
23028 exports.assign = assign;
23029 exports.isObject = isObject;
23030 exports.isPlain = isPlain;
23032  * @file obj.js
23033  * @module obj
23034  */
23037  * @callback obj:EachCallback
23039  * @param {Mixed} value
23040  *        The current key for the object that is being iterated over.
23042  * @param {string} key
23043  *        The current key-value for object that is being iterated over
23044  */
23047  * @callback obj:ReduceCallback
23049  * @param {Mixed} accum
23050  *        The value that is accumulating over the reduce loop.
23052  * @param {Mixed} value
23053  *        The current key for the object that is being iterated over.
23055  * @param {string} key
23056  *        The current key-value for object that is being iterated over
23058  * @return {Mixed}
23059  *         The new accumulated value.
23060  */
23061 var toString = Object.prototype.toString;
23064  * Array-like iteration for objects.
23066  * @param {Object} object
23067  *        The object to iterate over
23069  * @param {obj:EachCallback} fn
23070  *        The callback function which is called for each key in the object.
23071  */
23072 function each(object, fn) {
23073   Object.keys(object).forEach(function (key) {
23074     return fn(object[key], key);
23075   });
23079  * Array-like reduce for objects.
23081  * @param {Object} object
23082  *        The Object that you want to reduce.
23084  * @param {Function} fn
23085  *         A callback function which is called for each key in the object. It
23086  *         receives the accumulated value and the per-iteration value and key
23087  *         as arguments.
23089  * @param {Mixed} [initial = 0]
23090  *        Starting value
23092  * @return {Mixed}
23093  *         The final accumulated value.
23094  */
23095 function reduce(object, fn) {
23096   var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
23098   return Object.keys(object).reduce(function (accum, key) {
23099     return fn(accum, object[key], key);
23100   }, initial);
23104  * Object.assign-style object shallow merge/extend.
23106  * @param  {Object} target
23107  * @param  {Object} ...sources
23108  * @return {Object}
23109  */
23110 function assign(target) {
23111   for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
23112     sources[_key - 1] = arguments[_key];
23113   }
23115   if (Object.assign) {
23116     return Object.assign.apply(Object, [target].concat(sources));
23117   }
23119   sources.forEach(function (source) {
23120     if (!source) {
23121       return;
23122     }
23124     each(source, function (value, key) {
23125       target[key] = value;
23126     });
23127   });
23129   return target;
23133  * Returns whether a value is an object of any kind - including DOM nodes,
23134  * arrays, regular expressions, etc. Not functions, though.
23136  * This avoids the gotcha where using `typeof` on a `null` value
23137  * results in `'object'`.
23139  * @param  {Object} value
23140  * @return {Boolean}
23141  */
23142 function isObject(value) {
23143   return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
23147  * Returns whether an object appears to be a "plain" object - that is, a
23148  * direct instance of `Object`.
23150  * @param  {Object} value
23151  * @return {Boolean}
23152  */
23153 function isPlain(value) {
23154   return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
23157 },{}],89:[function(_dereq_,module,exports){
23158 'use strict';
23160 exports.__esModule = true;
23161 exports.setTextContent = exports.createStyleElement = undefined;
23163 var _document = _dereq_(94);
23165 var _document2 = _interopRequireDefault(_document);
23167 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23170  * Create a DOM style element given a className for it.
23172  * @param {string} className
23173  *        The className to add to the created style element.
23175  * @return {Element}
23176  *         The element that was created.
23177  */
23178 var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
23179   var style = _document2['default'].createElement('style');
23181   style.className = className;
23183   return style;
23187  * Add text to a DOM element.
23189  * @param {Element} el
23190  *        The Element to add text content to.
23192  * @param {string} content
23193  *        The text to add to the element.
23194  */
23196  * @file stylesheet.js
23197  * @module stylesheet
23198  */
23199 var setTextContent = exports.setTextContent = function setTextContent(el, content) {
23200   if (el.styleSheet) {
23201     el.styleSheet.cssText = content;
23202   } else {
23203     el.textContent = content;
23204   }
23207 },{"94":94}],90:[function(_dereq_,module,exports){
23208 'use strict';
23210 exports.__esModule = true;
23211 exports.createTimeRange = undefined;
23212 exports.createTimeRanges = createTimeRanges;
23214 var _log = _dereq_(86);
23216 var _log2 = _interopRequireDefault(_log);
23218 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23221  * Returns the time for the specified index at the start or end
23222  * of a TimeRange object.
23224  * @function time-ranges:indexFunction
23226  * @param {number} [index=0]
23227  *        The range number to return the time for.
23229  * @return {number}
23230  *         The time that offset at the specified index.
23232  * @deprecated index must be set to a value, in the future this will throw an error.
23233  */
23236  * An object that contains ranges of time for various reasons.
23238  * @typedef {Object} TimeRange
23240  * @property {number} length
23241  *           The number of time ranges represented by this Object
23243  * @property {time-ranges:indexFunction} start
23244  *           Returns the time offset at which a specified time range begins.
23246  * @property {time-ranges:indexFunction} end
23247  *           Returns the time offset at which a specified time range begins.
23249  * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
23250  */
23253  * Check if any of the time ranges are over the maximum index.
23255  * @param {string} fnName
23256  *        The function name to use for logging
23258  * @param {number} index
23259  *        The index to check
23261  * @param {number} maxIndex
23262  *        The maximum possible index
23264  * @throws {Error} if the timeRanges provided are over the maxIndex
23265  */
23266 function rangeCheck(fnName, index, maxIndex) {
23267   if (index < 0 || index > maxIndex) {
23268     throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
23269   }
23273  * Check if any of the time ranges are over the maximum index.
23275  * @param {string} fnName
23276  *        The function name to use for logging
23278  * @param {string} valueIndex
23279  *        The proprety that should be used to get the time. should be 'start' or 'end'
23281  * @param {Array} ranges
23282  *        An array of time ranges
23284  * @param {Array} [rangeIndex=0]
23285  *        The index to start the search at
23287  * @return {number}
23288  *         The time that offset at the specified index.
23291  * @deprecated rangeIndex must be set to a value, in the future this will throw an error.
23292  * @throws {Error} if rangeIndex is more than the length of ranges
23293  */
23295  * @file time-ranges.js
23296  * @module time-ranges
23297  */
23298 function getRange(fnName, valueIndex, ranges, rangeIndex) {
23299   if (rangeIndex === undefined) {
23300     _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
23301     rangeIndex = 0;
23302   }
23303   rangeCheck(fnName, rangeIndex, ranges.length - 1);
23304   return ranges[rangeIndex][valueIndex];
23308  * Create a time range object givent ranges of time.
23310  * @param {Array} [ranges]
23311  *        An array of time ranges.
23312  */
23313 function createTimeRangesObj(ranges) {
23314   if (ranges === undefined || ranges.length === 0) {
23315     return {
23316       length: 0,
23317       start: function start() {
23318         throw new Error('This TimeRanges object is empty');
23319       },
23320       end: function end() {
23321         throw new Error('This TimeRanges object is empty');
23322       }
23323     };
23324   }
23325   return {
23326     length: ranges.length,
23327     start: getRange.bind(null, 'start', 0, ranges),
23328     end: getRange.bind(null, 'end', 1, ranges)
23329   };
23333  * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
23335  * @param {number|Array} start
23336  *        The start of a single range or an array of ranges
23338  * @param {number} end
23339  *        The end of a single range.
23341  * @private
23342  */
23343 function createTimeRanges(start, end) {
23344   if (Array.isArray(start)) {
23345     return createTimeRangesObj(start);
23346   } else if (start === undefined || end === undefined) {
23347     return createTimeRangesObj();
23348   }
23349   return createTimeRangesObj([[start, end]]);
23352 exports.createTimeRange = createTimeRanges;
23354 },{"86":86}],91:[function(_dereq_,module,exports){
23355 'use strict';
23357 exports.__esModule = true;
23359  * @file to-title-case.js
23360  * @module to-title-case
23361  */
23364  * Uppercase the first letter of a string.
23366  * @param {string} string
23367  *        String to be uppercased
23369  * @return {string}
23370  *         The string with an uppercased first letter
23371  */
23372 function toTitleCase(string) {
23373   if (typeof string !== 'string') {
23374     return string;
23375   }
23377   return string.charAt(0).toUpperCase() + string.slice(1);
23380 exports['default'] = toTitleCase;
23382 },{}],92:[function(_dereq_,module,exports){
23383 'use strict';
23385 exports.__esModule = true;
23386 exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
23388 var _document = _dereq_(94);
23390 var _document2 = _interopRequireDefault(_document);
23392 var _window = _dereq_(95);
23394 var _window2 = _interopRequireDefault(_window);
23396 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23399  * @typedef {Object} url:URLObject
23401  * @property {string} protocol
23402  *           The protocol of the url that was parsed.
23404  * @property {string} hostname
23405  *           The hostname of the url that was parsed.
23407  * @property {string} port
23408  *           The port of the url that was parsed.
23410  * @property {string} pathname
23411  *           The pathname of the url that was parsed.
23413  * @property {string} search
23414  *           The search query of the url that was parsed.
23416  * @property {string} hash
23417  *           The hash of the url that was parsed.
23419  * @property {string} host
23420  *           The host of the url that was parsed.
23421  */
23424  * Resolve and parse the elements of a URL.
23426  * @param  {String} url
23427  *         The url to parse
23429  * @return {url:URLObject}
23430  *         An object of url details
23431  */
23433  * @file url.js
23434  * @module url
23435  */
23436 var parseUrl = exports.parseUrl = function parseUrl(url) {
23437   var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
23439   // add the url to an anchor and let the browser parse the URL
23440   var a = _document2['default'].createElement('a');
23442   a.href = url;
23444   // IE8 (and 9?) Fix
23445   // ie8 doesn't parse the URL correctly until the anchor is actually
23446   // added to the body, and an innerHTML is needed to trigger the parsing
23447   var addToBody = a.host === '' && a.protocol !== 'file:';
23448   var div = void 0;
23450   if (addToBody) {
23451     div = _document2['default'].createElement('div');
23452     div.innerHTML = '<a href="' + url + '"></a>';
23453     a = div.firstChild;
23454     // prevent the div from affecting layout
23455     div.setAttribute('style', 'display:none; position:absolute;');
23456     _document2['default'].body.appendChild(div);
23457   }
23459   // Copy the specific URL properties to a new object
23460   // This is also needed for IE8 because the anchor loses its
23461   // properties when it's removed from the dom
23462   var details = {};
23464   for (var i = 0; i < props.length; i++) {
23465     details[props[i]] = a[props[i]];
23466   }
23468   // IE9 adds the port to the host property unlike everyone else. If
23469   // a port identifier is added for standard ports, strip it.
23470   if (details.protocol === 'http:') {
23471     details.host = details.host.replace(/:80$/, '');
23472   }
23474   if (details.protocol === 'https:') {
23475     details.host = details.host.replace(/:443$/, '');
23476   }
23478   if (addToBody) {
23479     _document2['default'].body.removeChild(div);
23480   }
23482   return details;
23486  * Get absolute version of relative URL. Used to tell flash correct URL.
23489  * @param  {string} url
23490  *         URL to make absolute
23492  * @return {string}
23493  *         Absolute URL
23495  * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
23496  */
23497 var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
23498   // Check if absolute URL
23499   if (!url.match(/^https?:\/\//)) {
23500     // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
23501     var div = _document2['default'].createElement('div');
23503     div.innerHTML = '<a href="' + url + '">x</a>';
23504     url = div.firstChild.href;
23505   }
23507   return url;
23511  * Returns the extension of the passed file name. It will return an empty string
23512  * if passed an invalid path.
23514  * @param {string} path
23515  *        The fileName path like '/path/to/file.mp4'
23517  * @returns {string}
23518  *          The extension in lower case or an empty string if no
23519  *          extension could be found.
23520  */
23521 var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
23522   if (typeof path === 'string') {
23523     var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
23524     var pathParts = splitPathRe.exec(path);
23526     if (pathParts) {
23527       return pathParts.pop().toLowerCase();
23528     }
23529   }
23531   return '';
23535  * Returns whether the url passed is a cross domain request or not.
23537  * @param {string} url
23538  *        The url to check.
23540  * @return {boolean}
23541  *         Whether it is a cross domain request or not.
23542  */
23543 var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
23544   var winLoc = _window2['default'].location;
23545   var urlInfo = parseUrl(url);
23547   // IE8 protocol relative urls will return ':' for protocol
23548   var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
23550   // Check if url is for another domain/origin
23551   // IE8 doesn't know location.origin, so we won't rely on it here
23552   var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
23554   return crossOrigin;
23557 },{"94":94,"95":95}],93:[function(_dereq_,module,exports){
23558 'use strict';
23560 exports.__esModule = true;
23562 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /**
23563                                                                                                                                                                                                                                                                                * @file video.js
23564                                                                                                                                                                                                                                                                                * @module videojs
23565                                                                                                                                                                                                                                                                                */
23567 /* global define */
23569 // Include the built-in techs
23572 var _window = _dereq_(95);
23574 var _window2 = _interopRequireDefault(_window);
23576 var _document = _dereq_(94);
23578 var _document2 = _interopRequireDefault(_document);
23580 var _setup = _dereq_(56);
23582 var setup = _interopRequireWildcard(_setup);
23584 var _stylesheet = _dereq_(89);
23586 var stylesheet = _interopRequireWildcard(_stylesheet);
23588 var _component = _dereq_(5);
23590 var _component2 = _interopRequireDefault(_component);
23592 var _eventTarget = _dereq_(42);
23594 var _eventTarget2 = _interopRequireDefault(_eventTarget);
23596 var _events = _dereq_(82);
23598 var Events = _interopRequireWildcard(_events);
23600 var _player = _dereq_(51);
23602 var _player2 = _interopRequireDefault(_player);
23604 var _plugins = _dereq_(52);
23606 var _plugins2 = _interopRequireDefault(_plugins);
23608 var _mergeOptions2 = _dereq_(87);
23610 var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
23612 var _fn = _dereq_(83);
23614 var Fn = _interopRequireWildcard(_fn);
23616 var _textTrack = _dereq_(72);
23618 var _textTrack2 = _interopRequireDefault(_textTrack);
23620 var _audioTrack = _dereq_(64);
23622 var _audioTrack2 = _interopRequireDefault(_audioTrack);
23624 var _videoTrack = _dereq_(77);
23626 var _videoTrack2 = _interopRequireDefault(_videoTrack);
23628 var _timeRanges = _dereq_(90);
23630 var _formatTime = _dereq_(84);
23632 var _formatTime2 = _interopRequireDefault(_formatTime);
23634 var _log = _dereq_(86);
23636 var _log2 = _interopRequireDefault(_log);
23638 var _dom = _dereq_(81);
23640 var Dom = _interopRequireWildcard(_dom);
23642 var _browser = _dereq_(78);
23644 var browser = _interopRequireWildcard(_browser);
23646 var _url = _dereq_(92);
23648 var Url = _interopRequireWildcard(_url);
23650 var _obj = _dereq_(88);
23652 var _computedStyle = _dereq_(80);
23654 var _computedStyle2 = _interopRequireDefault(_computedStyle);
23656 var _extend = _dereq_(43);
23658 var _extend2 = _interopRequireDefault(_extend);
23660 var _xhr = _dereq_(99);
23662 var _xhr2 = _interopRequireDefault(_xhr);
23664 var _tech = _dereq_(62);
23666 var _tech2 = _interopRequireDefault(_tech);
23668 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
23670 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23672 // HTML5 Element Shim for IE8
23673 if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
23674   _document2['default'].createElement('video');
23675   _document2['default'].createElement('audio');
23676   _document2['default'].createElement('track');
23680  * Doubles as the main function for users to create a player instance and also
23681  * the main library object.
23682  * The `videojs` function can be used to initialize or retrieve a player.
23683   *
23684  * @param {string|Element} id
23685  *        Video element or video element ID
23687  * @param {Object} [options]
23688  *        Optional options object for config/settings
23690  * @param {Component~ReadyCallback} [ready]
23691  *        Optional ready callback
23693  * @return {Player}
23694  *         A player instance
23696  * @mixes videojs
23697  */
23698 function videojs(id, options, ready) {
23699   var tag = void 0;
23701   // Allow for element or ID to be passed in
23702   // String ID
23703   if (typeof id === 'string') {
23705     // Adjust for jQuery ID syntax
23706     if (id.indexOf('#') === 0) {
23707       id = id.slice(1);
23708     }
23710     // If a player instance has already been created for this ID return it.
23711     if (videojs.getPlayers()[id]) {
23713       // If options or ready function are passed, warn
23714       if (options) {
23715         _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
23716       }
23718       if (ready) {
23719         videojs.getPlayers()[id].ready(ready);
23720       }
23722       return videojs.getPlayers()[id];
23723     }
23725     // Otherwise get element for ID
23726     tag = Dom.getEl(id);
23728     // ID is a media element
23729   } else {
23730     tag = id;
23731   }
23733   // Check for a usable element
23734   // re: nodeName, could be a box div also
23735   if (!tag || !tag.nodeName) {
23736     throw new TypeError('The element or ID supplied is not valid. (videojs)');
23737   }
23739   // Element may have a player attr referring to an already created player instance.
23740   // If so return that otherwise set up a new player below
23741   if (tag.player || _player2['default'].players[tag.playerId]) {
23742     return tag.player || _player2['default'].players[tag.playerId];
23743   }
23745   options = options || {};
23747   videojs.hooks('beforesetup').forEach(function (hookFunction) {
23748     var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
23750     if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
23751       _log2['default'].error('please return an object in beforesetup hooks');
23752       return;
23753     }
23755     options = (0, _mergeOptions3['default'])(options, opts);
23756   });
23758   var PlayerComponent = _component2['default'].getComponent('Player');
23759   // If not, set up a new player
23760   var player = new PlayerComponent(tag, options, ready);
23762   videojs.hooks('setup').forEach(function (hookFunction) {
23763     return hookFunction(player);
23764   });
23766   return player;
23770  * An Object that contains lifecycle hooks as keys which point to an array
23771  * of functions that are run when a lifecycle is triggered
23772  */
23773 videojs.hooks_ = {};
23776  * Get a list of hooks for a specific lifecycle
23778  * @param {string} type
23779  *        the lifecycle to get hooks from
23781  * @param {Function} [fn]
23782  *        Optionally add a hook to the lifecycle that your are getting.
23784  * @return {Array}
23785  *         an array of hooks, or an empty array if there are none.
23786  */
23787 videojs.hooks = function (type, fn) {
23788   videojs.hooks_[type] = videojs.hooks_[type] || [];
23789   if (fn) {
23790     videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
23791   }
23792   return videojs.hooks_[type];
23796  * Add a function hook to a specific videojs lifecycle.
23798  * @param {string} type
23799  *        the lifecycle to hook the function to.
23801  * @param {Function|Function[]}
23802  *        The function or array of functions to attach.
23803  */
23804 videojs.hook = function (type, fn) {
23805   videojs.hooks(type, fn);
23809  * Remove a hook from a specific videojs lifecycle.
23811  * @param {string} type
23812  *        the lifecycle that the function hooked to
23814  * @param {Function} fn
23815  *        The hooked function to remove
23817  * @return {boolean}
23818  *         The function that was removed or undef
23819  */
23820 videojs.removeHook = function (type, fn) {
23821   var index = videojs.hooks(type).indexOf(fn);
23823   if (index <= -1) {
23824     return false;
23825   }
23827   videojs.hooks_[type] = videojs.hooks_[type].slice();
23828   videojs.hooks_[type].splice(index, 1);
23830   return true;
23833 // Add default styles
23834 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
23835   var style = Dom.$('.vjs-styles-defaults');
23837   if (!style) {
23838     style = stylesheet.createStyleElement('vjs-styles-defaults');
23839     var head = Dom.$('head');
23841     if (head) {
23842       head.insertBefore(style, head.firstChild);
23843     }
23844     stylesheet.setTextContent(style, '\n      .video-js {\n        width: 300px;\n        height: 150px;\n      }\n\n      .vjs-fluid {\n        padding-top: 56.25%\n      }\n    ');
23845   }
23848 // Run Auto-load players
23849 // You have to wait at least once in case this script is loaded after your
23850 // video in the DOM (weird behavior only with minified version)
23851 setup.autoSetupTimeout(1, videojs);
23854  * Current software version. Follows semver.
23856  * @type {string}
23857  */
23858 videojs.VERSION = '5.15.1';
23861  * The global options object. These are the settings that take effect
23862  * if no overrides are specified when the player is created.
23864  * @type {Object}
23865  */
23866 videojs.options = _player2['default'].prototype.options_;
23869  * Get an object with the currently created players, keyed by player ID
23871  * @return {Object}
23872  *         The created players
23873  */
23874 videojs.getPlayers = function () {
23875   return _player2['default'].players;
23879  * Expose players object.
23881  * @memberOf videojs
23882  * @property {Object} players
23883  */
23884 videojs.players = _player2['default'].players;
23887  * Get a component class object by name
23889  * @borrows Component.getComponent as videojs.getComponent
23890  */
23891 videojs.getComponent = _component2['default'].getComponent;
23894  * Register a component so it can referred to by name. Used when adding to other
23895  * components, either through addChild `component.addChild('myComponent')` or through
23896  * default children options  `{ children: ['myComponent'] }`.
23898  * > NOTE: You could also just initialize the component before adding.
23899  * `component.addChild(new MyComponent());`
23901  * @param {string} name
23902  *        The class name of the component
23904  * @param {Component} comp
23905  *        The component class
23907  * @return {Component}
23908  *         The newly registered component
23909  */
23910 videojs.registerComponent = function (name, comp) {
23911   if (_tech2['default'].isTech(comp)) {
23912     _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
23913   }
23915   _component2['default'].registerComponent.call(_component2['default'], name, comp);
23919  * Get a Tech class object by name
23921  * @borrows Tech.getTech as videojs.getTech
23922  */
23923 videojs.getTech = _tech2['default'].getTech;
23926  * Register a Tech so it can referred to by name.
23927  * This is used in the tech order for the player.
23929  * @borrows Tech.registerTech as videojs.registerTech
23930  */
23931 videojs.registerTech = _tech2['default'].registerTech;
23934  * A suite of browser and device tests from {@link browser}.
23936  * @type {Object}
23937  * @private
23938  */
23939 videojs.browser = browser;
23942  * Whether or not the browser supports touch events. Included for backward
23943  * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
23944  * instead going forward.
23946  * @deprecated since version 5.0
23947  * @type {boolean}
23948  */
23949 videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
23952  * Subclass an existing class
23953  * Mimics ES6 subclassing with the `extend` keyword
23955  * @borrows extend:extendFn as videojs.extend
23956  */
23957 videojs.extend = _extend2['default'];
23960  * Merge two options objects recursively
23961  * Performs a deep merge like lodash.merge but **only merges plain objects**
23962  * (not arrays, elements, anything else)
23963  * Other values will be copied directly from the second object.
23965  * @borrows merge-options:mergeOptions as videojs.mergeOptions
23966  */
23967 videojs.mergeOptions = _mergeOptions3['default'];
23970  * Change the context (this) of a function
23972  * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
23973  * `function() {}.bind(newContext);` instead of this.
23975  * @borrows fn:bind as videojs.bind
23976  */
23977 videojs.bind = Fn.bind;
23980  * Create a Video.js player plugin.
23981  * Plugins are only initialized when options for the plugin are included
23982  * in the player options, or the plugin function on the player instance is
23983  * called.
23985  * @borrows plugin:plugin as videojs.plugin
23986  */
23987 videojs.plugin = _plugins2['default'];
23990  * Adding languages so that they're available to all players.
23991  * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
23993  * @param {string} code
23994  *        The language code or dictionary property
23996  * @param {Object} data
23997  *        The data values to be translated
23999  * @return {Object}
24000  *         The resulting language dictionary object
24001  */
24002 videojs.addLanguage = function (code, data) {
24003   var _mergeOptions;
24005   code = ('' + code).toLowerCase();
24007   videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
24009   return videojs.options.languages[code];
24013  * Log messages
24015  * @borrows log:log as videojs.log
24016  */
24017 videojs.log = _log2['default'];
24020  * Creates an emulated TimeRange object.
24022  * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
24023  */
24025  * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
24026  */
24027 videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
24030  * Format seconds as a time string, H:MM:SS or M:SS
24031  * Supplying a guide (in seconds) will force a number of leading zeros
24032  * to cover the length of the guide
24034  * @borrows format-time:formatTime as videojs.formatTime
24035  */
24036 videojs.formatTime = _formatTime2['default'];
24039  * Resolve and parse the elements of a URL
24041  * @borrows url:parseUrl as videojs.parseUrl
24042  */
24043 videojs.parseUrl = Url.parseUrl;
24046  * Returns whether the url passed is a cross domain request or not.
24048  * @borrows url:isCrossOrigin as videojs.isCrossOrigin
24049  */
24050 videojs.isCrossOrigin = Url.isCrossOrigin;
24053  * Event target class.
24055  * @borrows EventTarget as videojs.EventTarget
24056  */
24057 videojs.EventTarget = _eventTarget2['default'];
24060  * Add an event listener to element
24061  * It stores the handler function in a separate cache object
24062  * and adds a generic handler to the element's event,
24063  * along with a unique id (guid) to the element.
24065  * @borrows events:on as videojs.on
24066  */
24067 videojs.on = Events.on;
24070  * Trigger a listener only once for an event
24072  * @borrows events:one as videojs.one
24073  */
24074 videojs.one = Events.one;
24077  * Removes event listeners from an element
24079  * @borrows events:off as videojs.off
24080  */
24081 videojs.off = Events.off;
24084  * Trigger an event for an element
24086  * @borrows events:trigger as videojs.trigger
24087  */
24088 videojs.trigger = Events.trigger;
24091  * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
24093  * @param {Object} options
24094  *        settings for the request.
24096  * @return {XMLHttpRequest|XDomainRequest}
24097  *         The request object.
24099  * @see https://github.com/Raynos/xhr
24100  */
24101 videojs.xhr = _xhr2['default'];
24104  * TextTrack class
24106  * @borrows TextTrack as videojs.TextTrack
24107  */
24108 videojs.TextTrack = _textTrack2['default'];
24111  * export the AudioTrack class so that source handlers can create
24112  * AudioTracks and then add them to the players AudioTrackList
24114  * @borrows AudioTrack as videojs.AudioTrack
24115  */
24116 videojs.AudioTrack = _audioTrack2['default'];
24119  * export the VideoTrack class so that source handlers can create
24120  * VideoTracks and then add them to the players VideoTrackList
24122  * @borrows VideoTrack as videojs.VideoTrack
24123  */
24124 videojs.VideoTrack = _videoTrack2['default'];
24127  * Determines, via duck typing, whether or not a value is a DOM element.
24129  * @borrows dom:isEl as videojs.isEl
24130  */
24131 videojs.isEl = Dom.isEl;
24134  * Determines, via duck typing, whether or not a value is a text node.
24136  * @borrows dom:isTextNode as videojs.isTextNode
24137  */
24138 videojs.isTextNode = Dom.isTextNode;
24141  * Creates an element and applies properties.
24143  * @borrows dom:createEl as videojs.createEl
24144  */
24145 videojs.createEl = Dom.createEl;
24148  * Check if an element has a CSS class
24150  * @borrows dom:hasElClass as videojs.hasClass
24151  */
24152 videojs.hasClass = Dom.hasElClass;
24155  * Add a CSS class name to an element
24157  * @borrows dom:addElClass as videojs.addClass
24158  */
24159 videojs.addClass = Dom.addElClass;
24162  * Remove a CSS class name from an element
24164  * @borrows dom:removeElClass as videojs.removeClass
24165  */
24166 videojs.removeClass = Dom.removeElClass;
24169  * Adds or removes a CSS class name on an element depending on an optional
24170  * condition or the presence/absence of the class name.
24172  * @borrows dom:toggleElClass as videojs.toggleClass
24173  */
24174 videojs.toggleClass = Dom.toggleElClass;
24177  * Apply attributes to an HTML element.
24179  * @borrows dom:setElAttributes as videojs.setAttribute
24180  */
24181 videojs.setAttributes = Dom.setElAttributes;
24184  * Get an element's attribute values, as defined on the HTML tag
24185  * Attributes are not the same as properties. They're defined on the tag
24186  * or with setAttribute (which shouldn't be used with HTML)
24187  * This will return true or false for boolean attributes.
24189  * @borrows dom:getElAttributes as videojs.getAttributes
24190  */
24191 videojs.getAttributes = Dom.getElAttributes;
24194  * Empties the contents of an element.
24196  * @borrows dom:emptyEl as videojs.emptyEl
24197  */
24198 videojs.emptyEl = Dom.emptyEl;
24201  * Normalizes and appends content to an element.
24203  * The content for an element can be passed in multiple types and
24204  * combinations, whose behavior is as follows:
24206  * - String
24207  *   Normalized into a text node.
24209  * - Element, TextNode
24210  *   Passed through.
24212  * - Array
24213  *   A one-dimensional array of strings, elements, nodes, or functions (which
24214  *   return single strings, elements, or nodes).
24216  * - Function
24217  *   If the sole argument, is expected to produce a string, element,
24218  *   node, or array.
24220  * @borrows dom:appendContents as videojs.appendContet
24221  */
24222 videojs.appendContent = Dom.appendContent;
24225  * Normalizes and inserts content into an element; this is identical to
24226  * `appendContent()`, except it empties the element first.
24228  * The content for an element can be passed in multiple types and
24229  * combinations, whose behavior is as follows:
24231  * - String
24232  *   Normalized into a text node.
24234  * - Element, TextNode
24235  *   Passed through.
24237  * - Array
24238  *   A one-dimensional array of strings, elements, nodes, or functions (which
24239  *   return single strings, elements, or nodes).
24241  * - Function
24242  *   If the sole argument, is expected to produce a string, element,
24243  *   node, or array.
24245  * @borrows dom:insertContent as videojs.insertContent
24246  */
24247 videojs.insertContent = Dom.insertContent;
24250  * A safe getComputedStyle with an IE8 fallback.
24252  * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
24253  * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
24254  * that the player doesn't break in these cases.
24255  * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
24257  * @borrows computed-style:computedStyle as videojs.computedStyle
24258  */
24259 videojs.computedStyle = _computedStyle2['default'];
24262  * Custom Universal Module Definition (UMD)
24264  * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
24265  * still support requirejs and browserify. This also needs to be closure
24266  * compiler compatible, so string keys are used.
24267  */
24268 if (typeof define === 'function' && define.amd) {
24269   define('videojs', [], function () {
24270     return videojs;
24271   });
24273   // checking that module is an object too because of umdjs/umd#35
24274 } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
24275   module.exports = videojs;
24278 exports['default'] = videojs;
24280 },{"42":42,"43":43,"5":5,"51":51,"52":52,"56":56,"62":62,"64":64,"72":72,"77":77,"78":78,"80":80,"81":81,"82":82,"83":83,"84":84,"86":86,"87":87,"88":88,"89":89,"90":90,"92":92,"94":94,"95":95,"99":99}],94:[function(_dereq_,module,exports){
24281 (function (global){
24282 var topLevel = typeof global !== 'undefined' ? global :
24283     typeof window !== 'undefined' ? window : {}
24284 var minDoc = _dereq_(96);
24286 if (typeof document !== 'undefined') {
24287     module.exports = document;
24288 } else {
24289     var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
24291     if (!doccy) {
24292         doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
24293     }
24295     module.exports = doccy;
24298 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24299 },{"96":96}],95:[function(_dereq_,module,exports){
24300 (function (global){
24301 if (typeof window !== "undefined") {
24302     module.exports = window;
24303 } else if (typeof global !== "undefined") {
24304     module.exports = global;
24305 } else if (typeof self !== "undefined"){
24306     module.exports = self;
24307 } else {
24308     module.exports = {};
24311 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24312 },{}],96:[function(_dereq_,module,exports){
24314 },{}],97:[function(_dereq_,module,exports){
24315 module.exports = SafeParseTuple
24317 function SafeParseTuple(obj, reviver) {
24318     var json
24319     var error = null
24321     try {
24322         json = JSON.parse(obj, reviver)
24323     } catch (err) {
24324         error = err
24325     }
24327     return [error, json]
24330 },{}],98:[function(_dereq_,module,exports){
24331 function clean (s) {
24332   return s.replace(/\n\r?\s*/g, '')
24336 module.exports = function tsml (sa) {
24337   var s = ''
24338     , i = 0
24340   for (; i < arguments.length; i++)
24341     s += clean(sa[i]) + (arguments[i + 1] || '')
24343   return s
24345 },{}],99:[function(_dereq_,module,exports){
24346 "use strict";
24347 var window = _dereq_(95)
24348 var isFunction = _dereq_(100)
24349 var parseHeaders = _dereq_(103)
24350 var xtend = _dereq_(104)
24352 module.exports = createXHR
24353 createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
24354 createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
24356 forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
24357     createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
24358         options = initParams(uri, options, callback)
24359         options.method = method.toUpperCase()
24360         return _createXHR(options)
24361     }
24364 function forEachArray(array, iterator) {
24365     for (var i = 0; i < array.length; i++) {
24366         iterator(array[i])
24367     }
24370 function isEmpty(obj){
24371     for(var i in obj){
24372         if(obj.hasOwnProperty(i)) return false
24373     }
24374     return true
24377 function initParams(uri, options, callback) {
24378     var params = uri
24380     if (isFunction(options)) {
24381         callback = options
24382         if (typeof uri === "string") {
24383             params = {uri:uri}
24384         }
24385     } else {
24386         params = xtend(options, {uri: uri})
24387     }
24389     params.callback = callback
24390     return params
24393 function createXHR(uri, options, callback) {
24394     options = initParams(uri, options, callback)
24395     return _createXHR(options)
24398 function _createXHR(options) {
24399     if(typeof options.callback === "undefined"){
24400         throw new Error("callback argument missing")
24401     }
24403     var called = false
24404     var callback = function cbOnce(err, response, body){
24405         if(!called){
24406             called = true
24407             options.callback(err, response, body)
24408         }
24409     }
24411     function readystatechange() {
24412         if (xhr.readyState === 4) {
24413             loadFunc()
24414         }
24415     }
24417     function getBody() {
24418         // Chrome with requestType=blob throws errors around when even testing access to responseText
24419         var body = undefined
24421         if (xhr.response) {
24422             body = xhr.response
24423         } else {
24424             body = xhr.responseText || getXml(xhr)
24425         }
24427         if (isJson) {
24428             try {
24429                 body = JSON.parse(body)
24430             } catch (e) {}
24431         }
24433         return body
24434     }
24436     var failureResponse = {
24437                 body: undefined,
24438                 headers: {},
24439                 statusCode: 0,
24440                 method: method,
24441                 url: uri,
24442                 rawRequest: xhr
24443             }
24445     function errorFunc(evt) {
24446         clearTimeout(timeoutTimer)
24447         if(!(evt instanceof Error)){
24448             evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
24449         }
24450         evt.statusCode = 0
24451         return callback(evt, failureResponse)
24452     }
24454     // will load the data & process the response in a special response object
24455     function loadFunc() {
24456         if (aborted) return
24457         var status
24458         clearTimeout(timeoutTimer)
24459         if(options.useXDR && xhr.status===undefined) {
24460             //IE8 CORS GET successful response doesn't have a status field, but body is fine
24461             status = 200
24462         } else {
24463             status = (xhr.status === 1223 ? 204 : xhr.status)
24464         }
24465         var response = failureResponse
24466         var err = null
24468         if (status !== 0){
24469             response = {
24470                 body: getBody(),
24471                 statusCode: status,
24472                 method: method,
24473                 headers: {},
24474                 url: uri,
24475                 rawRequest: xhr
24476             }
24477             if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
24478                 response.headers = parseHeaders(xhr.getAllResponseHeaders())
24479             }
24480         } else {
24481             err = new Error("Internal XMLHttpRequest Error")
24482         }
24483         return callback(err, response, response.body)
24484     }
24486     var xhr = options.xhr || null
24488     if (!xhr) {
24489         if (options.cors || options.useXDR) {
24490             xhr = new createXHR.XDomainRequest()
24491         }else{
24492             xhr = new createXHR.XMLHttpRequest()
24493         }
24494     }
24496     var key
24497     var aborted
24498     var uri = xhr.url = options.uri || options.url
24499     var method = xhr.method = options.method || "GET"
24500     var body = options.body || options.data || null
24501     var headers = xhr.headers = options.headers || {}
24502     var sync = !!options.sync
24503     var isJson = false
24504     var timeoutTimer
24506     if ("json" in options) {
24507         isJson = true
24508         headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
24509         if (method !== "GET" && method !== "HEAD") {
24510             headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
24511             body = JSON.stringify(options.json)
24512         }
24513     }
24515     xhr.onreadystatechange = readystatechange
24516     xhr.onload = loadFunc
24517     xhr.onerror = errorFunc
24518     // IE9 must have onprogress be set to a unique function.
24519     xhr.onprogress = function () {
24520         // IE must die
24521     }
24522     xhr.ontimeout = errorFunc
24523     xhr.open(method, uri, !sync, options.username, options.password)
24524     //has to be after open
24525     if(!sync) {
24526         xhr.withCredentials = !!options.withCredentials
24527     }
24528     // Cannot set timeout with sync request
24529     // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
24530     // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
24531     if (!sync && options.timeout > 0 ) {
24532         timeoutTimer = setTimeout(function(){
24533             aborted=true//IE9 may still call readystatechange
24534             xhr.abort("timeout")
24535             var e = new Error("XMLHttpRequest timeout")
24536             e.code = "ETIMEDOUT"
24537             errorFunc(e)
24538         }, options.timeout )
24539     }
24541     if (xhr.setRequestHeader) {
24542         for(key in headers){
24543             if(headers.hasOwnProperty(key)){
24544                 xhr.setRequestHeader(key, headers[key])
24545             }
24546         }
24547     } else if (options.headers && !isEmpty(options.headers)) {
24548         throw new Error("Headers cannot be set on an XDomainRequest object")
24549     }
24551     if ("responseType" in options) {
24552         xhr.responseType = options.responseType
24553     }
24555     if ("beforeSend" in options &&
24556         typeof options.beforeSend === "function"
24557     ) {
24558         options.beforeSend(xhr)
24559     }
24561     xhr.send(body)
24563     return xhr
24568 function getXml(xhr) {
24569     if (xhr.responseType === "document") {
24570         return xhr.responseXML
24571     }
24572     var firefoxBugTakenEffect = xhr.status === 204 && xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
24573     if (xhr.responseType === "" && !firefoxBugTakenEffect) {
24574         return xhr.responseXML
24575     }
24577     return null
24580 function noop() {}
24582 },{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){
24583 module.exports = isFunction
24585 var toString = Object.prototype.toString
24587 function isFunction (fn) {
24588   var string = toString.call(fn)
24589   return string === '[object Function]' ||
24590     (typeof fn === 'function' && string !== '[object RegExp]') ||
24591     (typeof window !== 'undefined' &&
24592      // IE8 and below
24593      (fn === window.setTimeout ||
24594       fn === window.alert ||
24595       fn === window.confirm ||
24596       fn === window.prompt))
24599 },{}],101:[function(_dereq_,module,exports){
24600 var isFunction = _dereq_(100)
24602 module.exports = forEach
24604 var toString = Object.prototype.toString
24605 var hasOwnProperty = Object.prototype.hasOwnProperty
24607 function forEach(list, iterator, context) {
24608     if (!isFunction(iterator)) {
24609         throw new TypeError('iterator must be a function')
24610     }
24612     if (arguments.length < 3) {
24613         context = this
24614     }
24616     if (toString.call(list) === '[object Array]')
24617         forEachArray(list, iterator, context)
24618     else if (typeof list === 'string')
24619         forEachString(list, iterator, context)
24620     else
24621         forEachObject(list, iterator, context)
24624 function forEachArray(array, iterator, context) {
24625     for (var i = 0, len = array.length; i < len; i++) {
24626         if (hasOwnProperty.call(array, i)) {
24627             iterator.call(context, array[i], i, array)
24628         }
24629     }
24632 function forEachString(string, iterator, context) {
24633     for (var i = 0, len = string.length; i < len; i++) {
24634         // no such thing as a sparse string.
24635         iterator.call(context, string.charAt(i), i, string)
24636     }
24639 function forEachObject(object, iterator, context) {
24640     for (var k in object) {
24641         if (hasOwnProperty.call(object, k)) {
24642             iterator.call(context, object[k], k, object)
24643         }
24644     }
24647 },{"100":100}],102:[function(_dereq_,module,exports){
24649 exports = module.exports = trim;
24651 function trim(str){
24652   return str.replace(/^\s*|\s*$/g, '');
24655 exports.left = function(str){
24656   return str.replace(/^\s*/, '');
24659 exports.right = function(str){
24660   return str.replace(/\s*$/, '');
24663 },{}],103:[function(_dereq_,module,exports){
24664 var trim = _dereq_(102)
24665   , forEach = _dereq_(101)
24666   , isArray = function(arg) {
24667       return Object.prototype.toString.call(arg) === '[object Array]';
24668     }
24670 module.exports = function (headers) {
24671   if (!headers)
24672     return {}
24674   var result = {}
24676   forEach(
24677       trim(headers).split('\n')
24678     , function (row) {
24679         var index = row.indexOf(':')
24680           , key = trim(row.slice(0, index)).toLowerCase()
24681           , value = trim(row.slice(index + 1))
24683         if (typeof(result[key]) === 'undefined') {
24684           result[key] = value
24685         } else if (isArray(result[key])) {
24686           result[key].push(value)
24687         } else {
24688           result[key] = [ result[key], value ]
24689         }
24690       }
24691   )
24693   return result
24695 },{"101":101,"102":102}],104:[function(_dereq_,module,exports){
24696 module.exports = extend
24698 var hasOwnProperty = Object.prototype.hasOwnProperty;
24700 function extend() {
24701     var target = {}
24703     for (var i = 0; i < arguments.length; i++) {
24704         var source = arguments[i]
24706         for (var key in source) {
24707             if (hasOwnProperty.call(source, key)) {
24708                 target[key] = source[key]
24709             }
24710         }
24711     }
24713     return target
24716 },{}]},{},[93])(93)
24718 /* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */
24720 (function(root) {
24721   var vttjs = root.vttjs = {};
24722   var cueShim = vttjs.VTTCue;
24723   var regionShim = vttjs.VTTRegion;
24724   var oldVTTCue = root.VTTCue;
24725   var oldVTTRegion = root.VTTRegion;
24727   vttjs.shim = function() {
24728     vttjs.VTTCue = cueShim;
24729     vttjs.VTTRegion = regionShim;
24730   };
24732   vttjs.restore = function() {
24733     vttjs.VTTCue = oldVTTCue;
24734     vttjs.VTTRegion = oldVTTRegion;
24735   };
24736 }(this));
24739  * Copyright 2013 vtt.js Contributors
24741  * Licensed under the Apache License, Version 2.0 (the "License");
24742  * you may not use this file except in compliance with the License.
24743  * You may obtain a copy of the License at
24745  *   http://www.apache.org/licenses/LICENSE-2.0
24747  * Unless required by applicable law or agreed to in writing, software
24748  * distributed under the License is distributed on an "AS IS" BASIS,
24749  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24750  * See the License for the specific language governing permissions and
24751  * limitations under the License.
24752  */
24754 (function(root, vttjs) {
24756   var autoKeyword = "auto";
24757   var directionSetting = {
24758     "": true,
24759     "lr": true,
24760     "rl": true
24761   };
24762   var alignSetting = {
24763     "start": true,
24764     "middle": true,
24765     "end": true,
24766     "left": true,
24767     "right": true
24768   };
24770   function findDirectionSetting(value) {
24771     if (typeof value !== "string") {
24772       return false;
24773     }
24774     var dir = directionSetting[value.toLowerCase()];
24775     return dir ? value.toLowerCase() : false;
24776   }
24778   function findAlignSetting(value) {
24779     if (typeof value !== "string") {
24780       return false;
24781     }
24782     var align = alignSetting[value.toLowerCase()];
24783     return align ? value.toLowerCase() : false;
24784   }
24786   function extend(obj) {
24787     var i = 1;
24788     for (; i < arguments.length; i++) {
24789       var cobj = arguments[i];
24790       for (var p in cobj) {
24791         obj[p] = cobj[p];
24792       }
24793     }
24795     return obj;
24796   }
24798   function VTTCue(startTime, endTime, text) {
24799     var cue = this;
24800     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
24801     var baseObj = {};
24803     if (isIE8) {
24804       cue = document.createElement('custom');
24805     } else {
24806       baseObj.enumerable = true;
24807     }
24809     /**
24810      * Shim implementation specific properties. These properties are not in
24811      * the spec.
24812      */
24814     // Lets us know when the VTTCue's data has changed in such a way that we need
24815     // to recompute its display state. This lets us compute its display state
24816     // lazily.
24817     cue.hasBeenReset = false;
24819     /**
24820      * VTTCue and TextTrackCue properties
24821      * http://dev.w3.org/html5/webvtt/#vttcue-interface
24822      */
24824     var _id = "";
24825     var _pauseOnExit = false;
24826     var _startTime = startTime;
24827     var _endTime = endTime;
24828     var _text = text;
24829     var _region = null;
24830     var _vertical = "";
24831     var _snapToLines = true;
24832     var _line = "auto";
24833     var _lineAlign = "start";
24834     var _position = 50;
24835     var _positionAlign = "middle";
24836     var _size = 50;
24837     var _align = "middle";
24839     Object.defineProperty(cue,
24840       "id", extend({}, baseObj, {
24841         get: function() {
24842           return _id;
24843         },
24844         set: function(value) {
24845           _id = "" + value;
24846         }
24847       }));
24849     Object.defineProperty(cue,
24850       "pauseOnExit", extend({}, baseObj, {
24851         get: function() {
24852           return _pauseOnExit;
24853         },
24854         set: function(value) {
24855           _pauseOnExit = !!value;
24856         }
24857       }));
24859     Object.defineProperty(cue,
24860       "startTime", extend({}, baseObj, {
24861         get: function() {
24862           return _startTime;
24863         },
24864         set: function(value) {
24865           if (typeof value !== "number") {
24866             throw new TypeError("Start time must be set to a number.");
24867           }
24868           _startTime = value;
24869           this.hasBeenReset = true;
24870         }
24871       }));
24873     Object.defineProperty(cue,
24874       "endTime", extend({}, baseObj, {
24875         get: function() {
24876           return _endTime;
24877         },
24878         set: function(value) {
24879           if (typeof value !== "number") {
24880             throw new TypeError("End time must be set to a number.");
24881           }
24882           _endTime = value;
24883           this.hasBeenReset = true;
24884         }
24885       }));
24887     Object.defineProperty(cue,
24888       "text", extend({}, baseObj, {
24889         get: function() {
24890           return _text;
24891         },
24892         set: function(value) {
24893           _text = "" + value;
24894           this.hasBeenReset = true;
24895         }
24896       }));
24898     Object.defineProperty(cue,
24899       "region", extend({}, baseObj, {
24900         get: function() {
24901           return _region;
24902         },
24903         set: function(value) {
24904           _region = value;
24905           this.hasBeenReset = true;
24906         }
24907       }));
24909     Object.defineProperty(cue,
24910       "vertical", extend({}, baseObj, {
24911         get: function() {
24912           return _vertical;
24913         },
24914         set: function(value) {
24915           var setting = findDirectionSetting(value);
24916           // Have to check for false because the setting an be an empty string.
24917           if (setting === false) {
24918             throw new SyntaxError("An invalid or illegal string was specified.");
24919           }
24920           _vertical = setting;
24921           this.hasBeenReset = true;
24922         }
24923       }));
24925     Object.defineProperty(cue,
24926       "snapToLines", extend({}, baseObj, {
24927         get: function() {
24928           return _snapToLines;
24929         },
24930         set: function(value) {
24931           _snapToLines = !!value;
24932           this.hasBeenReset = true;
24933         }
24934       }));
24936     Object.defineProperty(cue,
24937       "line", extend({}, baseObj, {
24938         get: function() {
24939           return _line;
24940         },
24941         set: function(value) {
24942           if (typeof value !== "number" && value !== autoKeyword) {
24943             throw new SyntaxError("An invalid number or illegal string was specified.");
24944           }
24945           _line = value;
24946           this.hasBeenReset = true;
24947         }
24948       }));
24950     Object.defineProperty(cue,
24951       "lineAlign", extend({}, baseObj, {
24952         get: function() {
24953           return _lineAlign;
24954         },
24955         set: function(value) {
24956           var setting = findAlignSetting(value);
24957           if (!setting) {
24958             throw new SyntaxError("An invalid or illegal string was specified.");
24959           }
24960           _lineAlign = setting;
24961           this.hasBeenReset = true;
24962         }
24963       }));
24965     Object.defineProperty(cue,
24966       "position", extend({}, baseObj, {
24967         get: function() {
24968           return _position;
24969         },
24970         set: function(value) {
24971           if (value < 0 || value > 100) {
24972             throw new Error("Position must be between 0 and 100.");
24973           }
24974           _position = value;
24975           this.hasBeenReset = true;
24976         }
24977       }));
24979     Object.defineProperty(cue,
24980       "positionAlign", extend({}, baseObj, {
24981         get: function() {
24982           return _positionAlign;
24983         },
24984         set: function(value) {
24985           var setting = findAlignSetting(value);
24986           if (!setting) {
24987             throw new SyntaxError("An invalid or illegal string was specified.");
24988           }
24989           _positionAlign = setting;
24990           this.hasBeenReset = true;
24991         }
24992       }));
24994     Object.defineProperty(cue,
24995       "size", extend({}, baseObj, {
24996         get: function() {
24997           return _size;
24998         },
24999         set: function(value) {
25000           if (value < 0 || value > 100) {
25001             throw new Error("Size must be between 0 and 100.");
25002           }
25003           _size = value;
25004           this.hasBeenReset = true;
25005         }
25006       }));
25008     Object.defineProperty(cue,
25009       "align", extend({}, baseObj, {
25010         get: function() {
25011           return _align;
25012         },
25013         set: function(value) {
25014           var setting = findAlignSetting(value);
25015           if (!setting) {
25016             throw new SyntaxError("An invalid or illegal string was specified.");
25017           }
25018           _align = setting;
25019           this.hasBeenReset = true;
25020         }
25021       }));
25023     /**
25024      * Other <track> spec defined properties
25025      */
25027     // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
25028     cue.displayState = undefined;
25030     if (isIE8) {
25031       return cue;
25032     }
25033   }
25035   /**
25036    * VTTCue methods
25037    */
25039   VTTCue.prototype.getCueAsHTML = function() {
25040     // Assume WebVTT.convertCueToDOMTree is on the global.
25041     return WebVTT.convertCueToDOMTree(window, this.text);
25042   };
25044   root.VTTCue = root.VTTCue || VTTCue;
25045   vttjs.VTTCue = VTTCue;
25046 }(this, (this.vttjs || {})));
25049  * Copyright 2013 vtt.js Contributors
25051  * Licensed under the Apache License, Version 2.0 (the "License");
25052  * you may not use this file except in compliance with the License.
25053  * You may obtain a copy of the License at
25055  *   http://www.apache.org/licenses/LICENSE-2.0
25057  * Unless required by applicable law or agreed to in writing, software
25058  * distributed under the License is distributed on an "AS IS" BASIS,
25059  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25060  * See the License for the specific language governing permissions and
25061  * limitations under the License.
25062  */
25064 (function(root, vttjs) {
25066   var scrollSetting = {
25067     "": true,
25068     "up": true
25069   };
25071   function findScrollSetting(value) {
25072     if (typeof value !== "string") {
25073       return false;
25074     }
25075     var scroll = scrollSetting[value.toLowerCase()];
25076     return scroll ? value.toLowerCase() : false;
25077   }
25079   function isValidPercentValue(value) {
25080     return typeof value === "number" && (value >= 0 && value <= 100);
25081   }
25083   // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
25084   function VTTRegion() {
25085     var _width = 100;
25086     var _lines = 3;
25087     var _regionAnchorX = 0;
25088     var _regionAnchorY = 100;
25089     var _viewportAnchorX = 0;
25090     var _viewportAnchorY = 100;
25091     var _scroll = "";
25093     Object.defineProperties(this, {
25094       "width": {
25095         enumerable: true,
25096         get: function() {
25097           return _width;
25098         },
25099         set: function(value) {
25100           if (!isValidPercentValue(value)) {
25101             throw new Error("Width must be between 0 and 100.");
25102           }
25103           _width = value;
25104         }
25105       },
25106       "lines": {
25107         enumerable: true,
25108         get: function() {
25109           return _lines;
25110         },
25111         set: function(value) {
25112           if (typeof value !== "number") {
25113             throw new TypeError("Lines must be set to a number.");
25114           }
25115           _lines = value;
25116         }
25117       },
25118       "regionAnchorY": {
25119         enumerable: true,
25120         get: function() {
25121           return _regionAnchorY;
25122         },
25123         set: function(value) {
25124           if (!isValidPercentValue(value)) {
25125             throw new Error("RegionAnchorX must be between 0 and 100.");
25126           }
25127           _regionAnchorY = value;
25128         }
25129       },
25130       "regionAnchorX": {
25131         enumerable: true,
25132         get: function() {
25133           return _regionAnchorX;
25134         },
25135         set: function(value) {
25136           if(!isValidPercentValue(value)) {
25137             throw new Error("RegionAnchorY must be between 0 and 100.");
25138           }
25139           _regionAnchorX = value;
25140         }
25141       },
25142       "viewportAnchorY": {
25143         enumerable: true,
25144         get: function() {
25145           return _viewportAnchorY;
25146         },
25147         set: function(value) {
25148           if (!isValidPercentValue(value)) {
25149             throw new Error("ViewportAnchorY must be between 0 and 100.");
25150           }
25151           _viewportAnchorY = value;
25152         }
25153       },
25154       "viewportAnchorX": {
25155         enumerable: true,
25156         get: function() {
25157           return _viewportAnchorX;
25158         },
25159         set: function(value) {
25160           if (!isValidPercentValue(value)) {
25161             throw new Error("ViewportAnchorX must be between 0 and 100.");
25162           }
25163           _viewportAnchorX = value;
25164         }
25165       },
25166       "scroll": {
25167         enumerable: true,
25168         get: function() {
25169           return _scroll;
25170         },
25171         set: function(value) {
25172           var setting = findScrollSetting(value);
25173           // Have to check for false as an empty string is a legal value.
25174           if (setting === false) {
25175             throw new SyntaxError("An invalid or illegal string was specified.");
25176           }
25177           _scroll = setting;
25178         }
25179       }
25180     });
25181   }
25183   root.VTTRegion = root.VTTRegion || VTTRegion;
25184   vttjs.VTTRegion = VTTRegion;
25185 }(this, (this.vttjs || {})));
25188  * Copyright 2013 vtt.js Contributors
25190  * Licensed under the Apache License, Version 2.0 (the "License");
25191  * you may not use this file except in compliance with the License.
25192  * You may obtain a copy of the License at
25194  *   http://www.apache.org/licenses/LICENSE-2.0
25196  * Unless required by applicable law or agreed to in writing, software
25197  * distributed under the License is distributed on an "AS IS" BASIS,
25198  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25199  * See the License for the specific language governing permissions and
25200  * limitations under the License.
25201  */
25203 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
25204 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
25206 (function(global) {
25208   var _objCreate = Object.create || (function() {
25209     function F() {}
25210     return function(o) {
25211       if (arguments.length !== 1) {
25212         throw new Error('Object.create shim only accepts one parameter.');
25213       }
25214       F.prototype = o;
25215       return new F();
25216     };
25217   })();
25219   // Creates a new ParserError object from an errorData object. The errorData
25220   // object should have default code and message properties. The default message
25221   // property can be overridden by passing in a message parameter.
25222   // See ParsingError.Errors below for acceptable errors.
25223   function ParsingError(errorData, message) {
25224     this.name = "ParsingError";
25225     this.code = errorData.code;
25226     this.message = message || errorData.message;
25227   }
25228   ParsingError.prototype = _objCreate(Error.prototype);
25229   ParsingError.prototype.constructor = ParsingError;
25231   // ParsingError metadata for acceptable ParsingErrors.
25232   ParsingError.Errors = {
25233     BadSignature: {
25234       code: 0,
25235       message: "Malformed WebVTT signature."
25236     },
25237     BadTimeStamp: {
25238       code: 1,
25239       message: "Malformed time stamp."
25240     }
25241   };
25243   // Try to parse input as a time stamp.
25244   function parseTimeStamp(input) {
25246     function computeSeconds(h, m, s, f) {
25247       return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
25248     }
25250     var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
25251     if (!m) {
25252       return null;
25253     }
25255     if (m[3]) {
25256       // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
25257       return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
25258     } else if (m[1] > 59) {
25259       // Timestamp takes the form of [hours]:[minutes].[milliseconds]
25260       // First position is hours as it's over 59.
25261       return computeSeconds(m[1], m[2], 0,  m[4]);
25262     } else {
25263       // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
25264       return computeSeconds(0, m[1], m[2], m[4]);
25265     }
25266   }
25268   // A settings object holds key/value pairs and will ignore anything but the first
25269   // assignment to a specific key.
25270   function Settings() {
25271     this.values = _objCreate(null);
25272   }
25274   Settings.prototype = {
25275     // Only accept the first assignment to any key.
25276     set: function(k, v) {
25277       if (!this.get(k) && v !== "") {
25278         this.values[k] = v;
25279       }
25280     },
25281     // Return the value for a key, or a default value.
25282     // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
25283     // a number of possible default values as properties where 'defaultKey' is
25284     // the key of the property that will be chosen; otherwise it's assumed to be
25285     // a single value.
25286     get: function(k, dflt, defaultKey) {
25287       if (defaultKey) {
25288         return this.has(k) ? this.values[k] : dflt[defaultKey];
25289       }
25290       return this.has(k) ? this.values[k] : dflt;
25291     },
25292     // Check whether we have a value for a key.
25293     has: function(k) {
25294       return k in this.values;
25295     },
25296     // Accept a setting if its one of the given alternatives.
25297     alt: function(k, v, a) {
25298       for (var n = 0; n < a.length; ++n) {
25299         if (v === a[n]) {
25300           this.set(k, v);
25301           break;
25302         }
25303       }
25304     },
25305     // Accept a setting if its a valid (signed) integer.
25306     integer: function(k, v) {
25307       if (/^-?\d+$/.test(v)) { // integer
25308         this.set(k, parseInt(v, 10));
25309       }
25310     },
25311     // Accept a setting if its a valid percentage.
25312     percent: function(k, v) {
25313       var m;
25314       if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
25315         v = parseFloat(v);
25316         if (v >= 0 && v <= 100) {
25317           this.set(k, v);
25318           return true;
25319         }
25320       }
25321       return false;
25322     }
25323   };
25325   // Helper function to parse input into groups separated by 'groupDelim', and
25326   // interpret each group as a key/value pair separated by 'keyValueDelim'.
25327   function parseOptions(input, callback, keyValueDelim, groupDelim) {
25328     var groups = groupDelim ? input.split(groupDelim) : [input];
25329     for (var i in groups) {
25330       if (typeof groups[i] !== "string") {
25331         continue;
25332       }
25333       var kv = groups[i].split(keyValueDelim);
25334       if (kv.length !== 2) {
25335         continue;
25336       }
25337       var k = kv[0];
25338       var v = kv[1];
25339       callback(k, v);
25340     }
25341   }
25343   function parseCue(input, cue, regionList) {
25344     // Remember the original input if we need to throw an error.
25345     var oInput = input;
25346     // 4.1 WebVTT timestamp
25347     function consumeTimeStamp() {
25348       var ts = parseTimeStamp(input);
25349       if (ts === null) {
25350         throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25351                               "Malformed timestamp: " + oInput);
25352       }
25353       // Remove time stamp from input.
25354       input = input.replace(/^[^\sa-zA-Z-]+/, "");
25355       return ts;
25356     }
25358     // 4.4.2 WebVTT cue settings
25359     function consumeCueSettings(input, cue) {
25360       var settings = new Settings();
25362       parseOptions(input, function (k, v) {
25363         switch (k) {
25364         case "region":
25365           // Find the last region we parsed with the same region id.
25366           for (var i = regionList.length - 1; i >= 0; i--) {
25367             if (regionList[i].id === v) {
25368               settings.set(k, regionList[i].region);
25369               break;
25370             }
25371           }
25372           break;
25373         case "vertical":
25374           settings.alt(k, v, ["rl", "lr"]);
25375           break;
25376         case "line":
25377           var vals = v.split(","),
25378               vals0 = vals[0];
25379           settings.integer(k, vals0);
25380           settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
25381           settings.alt(k, vals0, ["auto"]);
25382           if (vals.length === 2) {
25383             settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
25384           }
25385           break;
25386         case "position":
25387           vals = v.split(",");
25388           settings.percent(k, vals[0]);
25389           if (vals.length === 2) {
25390             settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
25391           }
25392           break;
25393         case "size":
25394           settings.percent(k, v);
25395           break;
25396         case "align":
25397           settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
25398           break;
25399         }
25400       }, /:/, /\s/);
25402       // Apply default values for any missing fields.
25403       cue.region = settings.get("region", null);
25404       cue.vertical = settings.get("vertical", "");
25405       cue.line = settings.get("line", "auto");
25406       cue.lineAlign = settings.get("lineAlign", "start");
25407       cue.snapToLines = settings.get("snapToLines", true);
25408       cue.size = settings.get("size", 100);
25409       cue.align = settings.get("align", "middle");
25410       cue.position = settings.get("position", {
25411         start: 0,
25412         left: 0,
25413         middle: 50,
25414         end: 100,
25415         right: 100
25416       }, cue.align);
25417       cue.positionAlign = settings.get("positionAlign", {
25418         start: "start",
25419         left: "start",
25420         middle: "middle",
25421         end: "end",
25422         right: "end"
25423       }, cue.align);
25424     }
25426     function skipWhitespace() {
25427       input = input.replace(/^\s+/, "");
25428     }
25430     // 4.1 WebVTT cue timings.
25431     skipWhitespace();
25432     cue.startTime = consumeTimeStamp();   // (1) collect cue start time
25433     skipWhitespace();
25434     if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
25435       throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25436                              "Malformed time stamp (time stamps must be separated by '-->'): " +
25437                              oInput);
25438     }
25439     input = input.substr(3);
25440     skipWhitespace();
25441     cue.endTime = consumeTimeStamp();     // (5) collect cue end time
25443     // 4.1 WebVTT cue settings list.
25444     skipWhitespace();
25445     consumeCueSettings(input, cue);
25446   }
25448   var ESCAPE = {
25449     "&amp;": "&",
25450     "&lt;": "<",
25451     "&gt;": ">",
25452     "&lrm;": "\u200e",
25453     "&rlm;": "\u200f",
25454     "&nbsp;": "\u00a0"
25455   };
25457   var TAG_NAME = {
25458     c: "span",
25459     i: "i",
25460     b: "b",
25461     u: "u",
25462     ruby: "ruby",
25463     rt: "rt",
25464     v: "span",
25465     lang: "span"
25466   };
25468   var TAG_ANNOTATION = {
25469     v: "title",
25470     lang: "lang"
25471   };
25473   var NEEDS_PARENT = {
25474     rt: "ruby"
25475   };
25477   // Parse content into a document fragment.
25478   function parseContent(window, input) {
25479     function nextToken() {
25480       // Check for end-of-string.
25481       if (!input) {
25482         return null;
25483       }
25485       // Consume 'n' characters from the input.
25486       function consume(result) {
25487         input = input.substr(result.length);
25488         return result;
25489       }
25491       var m = input.match(/^([^<]*)(<[^>]+>?)?/);
25492       // If there is some text before the next tag, return it, otherwise return
25493       // the tag.
25494       return consume(m[1] ? m[1] : m[2]);
25495     }
25497     // Unescape a string 's'.
25498     function unescape1(e) {
25499       return ESCAPE[e];
25500     }
25501     function unescape(s) {
25502       while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
25503         s = s.replace(m[0], unescape1);
25504       }
25505       return s;
25506     }
25508     function shouldAdd(current, element) {
25509       return !NEEDS_PARENT[element.localName] ||
25510              NEEDS_PARENT[element.localName] === current.localName;
25511     }
25513     // Create an element for this tag.
25514     function createElement(type, annotation) {
25515       var tagName = TAG_NAME[type];
25516       if (!tagName) {
25517         return null;
25518       }
25519       var element = window.document.createElement(tagName);
25520       element.localName = tagName;
25521       var name = TAG_ANNOTATION[type];
25522       if (name && annotation) {
25523         element[name] = annotation.trim();
25524       }
25525       return element;
25526     }
25528     var rootDiv = window.document.createElement("div"),
25529         current = rootDiv,
25530         t,
25531         tagStack = [];
25533     while ((t = nextToken()) !== null) {
25534       if (t[0] === '<') {
25535         if (t[1] === "/") {
25536           // If the closing tag matches, move back up to the parent node.
25537           if (tagStack.length &&
25538               tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
25539             tagStack.pop();
25540             current = current.parentNode;
25541           }
25542           // Otherwise just ignore the end tag.
25543           continue;
25544         }
25545         var ts = parseTimeStamp(t.substr(1, t.length - 2));
25546         var node;
25547         if (ts) {
25548           // Timestamps are lead nodes as well.
25549           node = window.document.createProcessingInstruction("timestamp", ts);
25550           current.appendChild(node);
25551           continue;
25552         }
25553         var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
25554         // If we can't parse the tag, skip to the next tag.
25555         if (!m) {
25556           continue;
25557         }
25558         // Try to construct an element, and ignore the tag if we couldn't.
25559         node = createElement(m[1], m[3]);
25560         if (!node) {
25561           continue;
25562         }
25563         // Determine if the tag should be added based on the context of where it
25564         // is placed in the cuetext.
25565         if (!shouldAdd(current, node)) {
25566           continue;
25567         }
25568         // Set the class list (as a list of classes, separated by space).
25569         if (m[2]) {
25570           node.className = m[2].substr(1).replace('.', ' ');
25571         }
25572         // Append the node to the current node, and enter the scope of the new
25573         // node.
25574         tagStack.push(m[1]);
25575         current.appendChild(node);
25576         current = node;
25577         continue;
25578       }
25580       // Text nodes are leaf nodes.
25581       current.appendChild(window.document.createTextNode(unescape(t)));
25582     }
25584     return rootDiv;
25585   }
25587   // This is a list of all the Unicode characters that have a strong
25588   // right-to-left category. What this means is that these characters are
25589   // written right-to-left for sure. It was generated by pulling all the strong
25590   // right-to-left characters out of the Unicode data table. That table can
25591   // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
25592   var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
25593       0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
25594       0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
25595       0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
25596       0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
25597       0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
25598       0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
25599       0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
25600       0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
25601       0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
25602       0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
25603       0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
25604       0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
25605       0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
25606       0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
25607       0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
25608       0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
25609       0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
25610       0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
25611       0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
25612       0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
25613       0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
25614       0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
25615       0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
25616       0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
25617       0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
25618       0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
25619       0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
25620       0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
25621       0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
25622       0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
25623       0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
25624       0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
25625       0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
25626       0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
25627       0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
25628       0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
25629       0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
25630       0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
25631       0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
25632       0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
25633       0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
25634       0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
25635       0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
25636       0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
25637       0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
25638       0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
25639       0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
25640       0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
25641       0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
25642       0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
25643       0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
25644       0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
25645       0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
25646       0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
25647       0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
25648       0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
25649       0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
25650       0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
25651       0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
25652       0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
25653       0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
25654       0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
25655       0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
25656       0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
25657       0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
25658       0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
25659       0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
25660       0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
25661       0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
25662       0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
25663       0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
25664       0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
25665       0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
25666       0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
25667       0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
25668       0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
25669       0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
25670       0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
25671       0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
25672       0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
25673       0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
25674       0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
25675       0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
25676       0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
25677       0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
25678       0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
25679       0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
25680       0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
25681       0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
25682       0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
25683       0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
25684       0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
25685       0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
25686       0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
25687       0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
25688       0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
25689       0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
25690       0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
25691       0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
25692       0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
25693       0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
25694       0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
25695       0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
25696       0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
25697       0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
25698       0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
25699       0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
25700       0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
25701       0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
25702       0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
25703       0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
25704       0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
25705       0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
25706       0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
25707       0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
25708       0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
25709       0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
25710       0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
25711       0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
25712       0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
25713       0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
25714       0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
25715       0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
25716       0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
25717       0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
25718       0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
25719       0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
25720       0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
25721       0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
25722       0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
25723       0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
25724       0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
25725       0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
25726       0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
25727       0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
25728       0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
25729       0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
25730       0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
25731       0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
25732       0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
25733       0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
25734       0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
25735       0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
25736       0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
25737       0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
25738       0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
25739       0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
25740       0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
25741       0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
25742       0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
25743       0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
25744       0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
25745       0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
25746       0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
25747       0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
25748       0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
25749       0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
25750       0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
25751       0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
25752       0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
25753       0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
25754       0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
25755       0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
25756       0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
25757       0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
25758       0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
25759       0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
25760       0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
25761       0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
25762       0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
25763       0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
25764       0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
25765       0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
25766       0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
25767       0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
25768       0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
25769       0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
25770       0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
25771       0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
25772       0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
25773       0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
25774       0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
25775       0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
25776       0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
25777       0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
25778       0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
25779       0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
25780       0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
25781       0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
25782       0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
25783       0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
25784       0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
25785       0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
25786       0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
25787       0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
25788       0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
25789       0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
25790       0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
25791       0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
25792       0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
25793       0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
25794       0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
25795       0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
25796       0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
25797       0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
25798       0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
25799       0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
25800       0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
25801       0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
25802       0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
25803       0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
25804       0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
25805       0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
25806       0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
25807       0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];
25809   function determineBidi(cueDiv) {
25810     var nodeStack = [],
25811         text = "",
25812         charCode;
25814     if (!cueDiv || !cueDiv.childNodes) {
25815       return "ltr";
25816     }
25818     function pushNodes(nodeStack, node) {
25819       for (var i = node.childNodes.length - 1; i >= 0; i--) {
25820         nodeStack.push(node.childNodes[i]);
25821       }
25822     }
25824     function nextTextNode(nodeStack) {
25825       if (!nodeStack || !nodeStack.length) {
25826         return null;
25827       }
25829       var node = nodeStack.pop(),
25830           text = node.textContent || node.innerText;
25831       if (text) {
25832         // TODO: This should match all unicode type B characters (paragraph
25833         // separator characters). See issue #115.
25834         var m = text.match(/^.*(\n|\r)/);
25835         if (m) {
25836           nodeStack.length = 0;
25837           return m[0];
25838         }
25839         return text;
25840       }
25841       if (node.tagName === "ruby") {
25842         return nextTextNode(nodeStack);
25843       }
25844       if (node.childNodes) {
25845         pushNodes(nodeStack, node);
25846         return nextTextNode(nodeStack);
25847       }
25848     }
25850     pushNodes(nodeStack, cueDiv);
25851     while ((text = nextTextNode(nodeStack))) {
25852       for (var i = 0; i < text.length; i++) {
25853         charCode = text.charCodeAt(i);
25854         for (var j = 0; j < strongRTLChars.length; j++) {
25855           if (strongRTLChars[j] === charCode) {
25856             return "rtl";
25857           }
25858         }
25859       }
25860     }
25861     return "ltr";
25862   }
25864   function computeLinePos(cue) {
25865     if (typeof cue.line === "number" &&
25866         (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
25867       return cue.line;
25868     }
25869     if (!cue.track || !cue.track.textTrackList ||
25870         !cue.track.textTrackList.mediaElement) {
25871       return -1;
25872     }
25873     var track = cue.track,
25874         trackList = track.textTrackList,
25875         count = 0;
25876     for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
25877       if (trackList[i].mode === "showing") {
25878         count++;
25879       }
25880     }
25881     return ++count * -1;
25882   }
25884   function StyleBox() {
25885   }
25887   // Apply styles to a div. If there is no div passed then it defaults to the
25888   // div on 'this'.
25889   StyleBox.prototype.applyStyles = function(styles, div) {
25890     div = div || this.div;
25891     for (var prop in styles) {
25892       if (styles.hasOwnProperty(prop)) {
25893         div.style[prop] = styles[prop];
25894       }
25895     }
25896   };
25898   StyleBox.prototype.formatStyle = function(val, unit) {
25899     return val === 0 ? 0 : val + unit;
25900   };
25902   // Constructs the computed display state of the cue (a div). Places the div
25903   // into the overlay which should be a block level element (usually a div).
25904   function CueStyleBox(window, cue, styleOptions) {
25905     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
25906     var color = "rgba(255, 255, 255, 1)";
25907     var backgroundColor = "rgba(0, 0, 0, 0.8)";
25909     if (isIE8) {
25910       color = "rgb(255, 255, 255)";
25911       backgroundColor = "rgb(0, 0, 0)";
25912     }
25914     StyleBox.call(this);
25915     this.cue = cue;
25917     // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
25918     // have inline positioning and will function as the cue background box.
25919     this.cueDiv = parseContent(window, cue.text);
25920     var styles = {
25921       color: color,
25922       backgroundColor: backgroundColor,
25923       position: "relative",
25924       left: 0,
25925       right: 0,
25926       top: 0,
25927       bottom: 0,
25928       display: "inline"
25929     };
25931     if (!isIE8) {
25932       styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25933                                                : cue.vertical === "lr" ? "vertical-lr"
25934                                                                        : "vertical-rl";
25935       styles.unicodeBidi = "plaintext";
25936     }
25937     this.applyStyles(styles, this.cueDiv);
25939     // Create an absolutely positioned div that will be used to position the cue
25940     // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
25941     // mirrors of them except "middle" which is "center" in CSS.
25942     this.div = window.document.createElement("div");
25943     styles = {
25944       textAlign: cue.align === "middle" ? "center" : cue.align,
25945       font: styleOptions.font,
25946       whiteSpace: "pre-line",
25947       position: "absolute"
25948     };
25950     if (!isIE8) {
25951       styles.direction = determineBidi(this.cueDiv);
25952       styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25953                                                : cue.vertical === "lr" ? "vertical-lr"
25954                                                                        : "vertical-rl".
25955       stylesunicodeBidi =  "plaintext";
25956     }
25958     this.applyStyles(styles);
25960     this.div.appendChild(this.cueDiv);
25962     // Calculate the distance from the reference edge of the viewport to the text
25963     // position of the cue box. The reference edge will be resolved later when
25964     // the box orientation styles are applied.
25965     var textPos = 0;
25966     switch (cue.positionAlign) {
25967     case "start":
25968       textPos = cue.position;
25969       break;
25970     case "middle":
25971       textPos = cue.position - (cue.size / 2);
25972       break;
25973     case "end":
25974       textPos = cue.position - cue.size;
25975       break;
25976     }
25978     // Horizontal box orientation; textPos is the distance from the left edge of the
25979     // area to the left edge of the box and cue.size is the distance extending to
25980     // the right from there.
25981     if (cue.vertical === "") {
25982       this.applyStyles({
25983         left:  this.formatStyle(textPos, "%"),
25984         width: this.formatStyle(cue.size, "%")
25985       });
25986     // Vertical box orientation; textPos is the distance from the top edge of the
25987     // area to the top edge of the box and cue.size is the height extending
25988     // downwards from there.
25989     } else {
25990       this.applyStyles({
25991         top: this.formatStyle(textPos, "%"),
25992         height: this.formatStyle(cue.size, "%")
25993       });
25994     }
25996     this.move = function(box) {
25997       this.applyStyles({
25998         top: this.formatStyle(box.top, "px"),
25999         bottom: this.formatStyle(box.bottom, "px"),
26000         left: this.formatStyle(box.left, "px"),
26001         right: this.formatStyle(box.right, "px"),
26002         height: this.formatStyle(box.height, "px"),
26003         width: this.formatStyle(box.width, "px")
26004       });
26005     };
26006   }
26007   CueStyleBox.prototype = _objCreate(StyleBox.prototype);
26008   CueStyleBox.prototype.constructor = CueStyleBox;
26010   // Represents the coordinates of an Element in a way that we can easily
26011   // compute things with such as if it overlaps or intersects with another Element.
26012   // Can initialize it with either a StyleBox or another BoxPosition.
26013   function BoxPosition(obj) {
26014     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
26016     // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
26017     // was passed in and we need to copy the results of 'getBoundingClientRect'
26018     // as the object returned is readonly. All coordinate values are in reference
26019     // to the viewport origin (top left).
26020     var lh, height, width, top;
26021     if (obj.div) {
26022       height = obj.div.offsetHeight;
26023       width = obj.div.offsetWidth;
26024       top = obj.div.offsetTop;
26026       var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
26027                   rects.getClientRects && rects.getClientRects();
26028       obj = obj.div.getBoundingClientRect();
26029       // In certain cases the outer div will be slightly larger then the sum of
26030       // the inner div's lines. This could be due to bold text, etc, on some platforms.
26031       // In this case we should get the average line height and use that. This will
26032       // result in the desired behaviour.
26033       lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
26034                  : 0;
26036     }
26037     this.left = obj.left;
26038     this.right = obj.right;
26039     this.top = obj.top || top;
26040     this.height = obj.height || height;
26041     this.bottom = obj.bottom || (top + (obj.height || height));
26042     this.width = obj.width || width;
26043     this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
26045     if (isIE8 && !this.lineHeight) {
26046       this.lineHeight = 13;
26047     }
26048   }
26050   // Move the box along a particular axis. Optionally pass in an amount to move
26051   // the box. If no amount is passed then the default is the line height of the
26052   // box.
26053   BoxPosition.prototype.move = function(axis, toMove) {
26054     toMove = toMove !== undefined ? toMove : this.lineHeight;
26055     switch (axis) {
26056     case "+x":
26057       this.left += toMove;
26058       this.right += toMove;
26059       break;
26060     case "-x":
26061       this.left -= toMove;
26062       this.right -= toMove;
26063       break;
26064     case "+y":
26065       this.top += toMove;
26066       this.bottom += toMove;
26067       break;
26068     case "-y":
26069       this.top -= toMove;
26070       this.bottom -= toMove;
26071       break;
26072     }
26073   };
26075   // Check if this box overlaps another box, b2.
26076   BoxPosition.prototype.overlaps = function(b2) {
26077     return this.left < b2.right &&
26078            this.right > b2.left &&
26079            this.top < b2.bottom &&
26080            this.bottom > b2.top;
26081   };
26083   // Check if this box overlaps any other boxes in boxes.
26084   BoxPosition.prototype.overlapsAny = function(boxes) {
26085     for (var i = 0; i < boxes.length; i++) {
26086       if (this.overlaps(boxes[i])) {
26087         return true;
26088       }
26089     }
26090     return false;
26091   };
26093   // Check if this box is within another box.
26094   BoxPosition.prototype.within = function(container) {
26095     return this.top >= container.top &&
26096            this.bottom <= container.bottom &&
26097            this.left >= container.left &&
26098            this.right <= container.right;
26099   };
26101   // Check if this box is entirely within the container or it is overlapping
26102   // on the edge opposite of the axis direction passed. For example, if "+x" is
26103   // passed and the box is overlapping on the left edge of the container, then
26104   // return true.
26105   BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
26106     switch (axis) {
26107     case "+x":
26108       return this.left < container.left;
26109     case "-x":
26110       return this.right > container.right;
26111     case "+y":
26112       return this.top < container.top;
26113     case "-y":
26114       return this.bottom > container.bottom;
26115     }
26116   };
26118   // Find the percentage of the area that this box is overlapping with another
26119   // box.
26120   BoxPosition.prototype.intersectPercentage = function(b2) {
26121     var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
26122         y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
26123         intersectArea = x * y;
26124     return intersectArea / (this.height * this.width);
26125   };
26127   // Convert the positions from this box to CSS compatible positions using
26128   // the reference container's positions. This has to be done because this
26129   // box's positions are in reference to the viewport origin, whereas, CSS
26130   // values are in reference to their respective edges.
26131   BoxPosition.prototype.toCSSCompatValues = function(reference) {
26132     return {
26133       top: this.top - reference.top,
26134       bottom: reference.bottom - this.bottom,
26135       left: this.left - reference.left,
26136       right: reference.right - this.right,
26137       height: this.height,
26138       width: this.width
26139     };
26140   };
26142   // Get an object that represents the box's position without anything extra.
26143   // Can pass a StyleBox, HTMLElement, or another BoxPositon.
26144   BoxPosition.getSimpleBoxPosition = function(obj) {
26145     var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
26146     var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
26147     var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
26149     obj = obj.div ? obj.div.getBoundingClientRect() :
26150                   obj.tagName ? obj.getBoundingClientRect() : obj;
26151     var ret = {
26152       left: obj.left,
26153       right: obj.right,
26154       top: obj.top || top,
26155       height: obj.height || height,
26156       bottom: obj.bottom || (top + (obj.height || height)),
26157       width: obj.width || width
26158     };
26159     return ret;
26160   };
26162   // Move a StyleBox to its specified, or next best, position. The containerBox
26163   // is the box that contains the StyleBox, such as a div. boxPositions are
26164   // a list of other boxes that the styleBox can't overlap with.
26165   function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
26167     // Find the best position for a cue box, b, on the video. The axis parameter
26168     // is a list of axis, the order of which, it will move the box along. For example:
26169     // Passing ["+x", "-x"] will move the box first along the x axis in the positive
26170     // direction. If it doesn't find a good position for it there it will then move
26171     // it along the x axis in the negative direction.
26172     function findBestPosition(b, axis) {
26173       var bestPosition,
26174           specifiedPosition = new BoxPosition(b),
26175           percentage = 1; // Highest possible so the first thing we get is better.
26177       for (var i = 0; i < axis.length; i++) {
26178         while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
26179                (b.within(containerBox) && b.overlapsAny(boxPositions))) {
26180           b.move(axis[i]);
26181         }
26182         // We found a spot where we aren't overlapping anything. This is our
26183         // best position.
26184         if (b.within(containerBox)) {
26185           return b;
26186         }
26187         var p = b.intersectPercentage(containerBox);
26188         // If we're outside the container box less then we were on our last try
26189         // then remember this position as the best position.
26190         if (percentage > p) {
26191           bestPosition = new BoxPosition(b);
26192           percentage = p;
26193         }
26194         // Reset the box position to the specified position.
26195         b = new BoxPosition(specifiedPosition);
26196       }
26197       return bestPosition || specifiedPosition;
26198     }
26200     var boxPosition = new BoxPosition(styleBox),
26201         cue = styleBox.cue,
26202         linePos = computeLinePos(cue),
26203         axis = [];
26205     // If we have a line number to align the cue to.
26206     if (cue.snapToLines) {
26207       var size;
26208       switch (cue.vertical) {
26209       case "":
26210         axis = [ "+y", "-y" ];
26211         size = "height";
26212         break;
26213       case "rl":
26214         axis = [ "+x", "-x" ];
26215         size = "width";
26216         break;
26217       case "lr":
26218         axis = [ "-x", "+x" ];
26219         size = "width";
26220         break;
26221       }
26223       var step = boxPosition.lineHeight,
26224           position = step * Math.round(linePos),
26225           maxPosition = containerBox[size] + step,
26226           initialAxis = axis[0];
26228       // If the specified initial position is greater then the max position then
26229       // clamp the box to the amount of steps it would take for the box to
26230       // reach the max position.
26231       if (Math.abs(position) > maxPosition) {
26232         position = position < 0 ? -1 : 1;
26233         position *= Math.ceil(maxPosition / step) * step;
26234       }
26236       // If computed line position returns negative then line numbers are
26237       // relative to the bottom of the video instead of the top. Therefore, we
26238       // need to increase our initial position by the length or width of the
26239       // video, depending on the writing direction, and reverse our axis directions.
26240       if (linePos < 0) {
26241         position += cue.vertical === "" ? containerBox.height : containerBox.width;
26242         axis = axis.reverse();
26243       }
26245       // Move the box to the specified position. This may not be its best
26246       // position.
26247       boxPosition.move(initialAxis, position);
26249     } else {
26250       // If we have a percentage line value for the cue.
26251       var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
26253       switch (cue.lineAlign) {
26254       case "middle":
26255         linePos -= (calculatedPercentage / 2);
26256         break;
26257       case "end":
26258         linePos -= calculatedPercentage;
26259         break;
26260       }
26262       // Apply initial line position to the cue box.
26263       switch (cue.vertical) {
26264       case "":
26265         styleBox.applyStyles({
26266           top: styleBox.formatStyle(linePos, "%")
26267         });
26268         break;
26269       case "rl":
26270         styleBox.applyStyles({
26271           left: styleBox.formatStyle(linePos, "%")
26272         });
26273         break;
26274       case "lr":
26275         styleBox.applyStyles({
26276           right: styleBox.formatStyle(linePos, "%")
26277         });
26278         break;
26279       }
26281       axis = [ "+y", "-x", "+x", "-y" ];
26283       // Get the box position again after we've applied the specified positioning
26284       // to it.
26285       boxPosition = new BoxPosition(styleBox);
26286     }
26288     var bestPosition = findBestPosition(boxPosition, axis);
26289     styleBox.move(bestPosition.toCSSCompatValues(containerBox));
26290   }
26292   function WebVTT() {
26293     // Nothing
26294   }
26296   // Helper to allow strings to be decoded instead of the default binary utf8 data.
26297   WebVTT.StringDecoder = function() {
26298     return {
26299       decode: function(data) {
26300         if (!data) {
26301           return "";
26302         }
26303         if (typeof data !== "string") {
26304           throw new Error("Error - expected string data.");
26305         }
26306         return decodeURIComponent(encodeURIComponent(data));
26307       }
26308     };
26309   };
26311   WebVTT.convertCueToDOMTree = function(window, cuetext) {
26312     if (!window || !cuetext) {
26313       return null;
26314     }
26315     return parseContent(window, cuetext);
26316   };
26318   var FONT_SIZE_PERCENT = 0.05;
26319   var FONT_STYLE = "sans-serif";
26320   var CUE_BACKGROUND_PADDING = "1.5%";
26322   // Runs the processing model over the cues and regions passed to it.
26323   // @param overlay A block level element (usually a div) that the computed cues
26324   //                and regions will be placed into.
26325   WebVTT.processCues = function(window, cues, overlay) {
26326     if (!window || !cues || !overlay) {
26327       return null;
26328     }
26330     // Remove all previous children.
26331     while (overlay.firstChild) {
26332       overlay.removeChild(overlay.firstChild);
26333     }
26335     var paddedOverlay = window.document.createElement("div");
26336     paddedOverlay.style.position = "absolute";
26337     paddedOverlay.style.left = "0";
26338     paddedOverlay.style.right = "0";
26339     paddedOverlay.style.top = "0";
26340     paddedOverlay.style.bottom = "0";
26341     paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
26342     overlay.appendChild(paddedOverlay);
26344     // Determine if we need to compute the display states of the cues. This could
26345     // be the case if a cue's state has been changed since the last computation or
26346     // if it has not been computed yet.
26347     function shouldCompute(cues) {
26348       for (var i = 0; i < cues.length; i++) {
26349         if (cues[i].hasBeenReset || !cues[i].displayState) {
26350           return true;
26351         }
26352       }
26353       return false;
26354     }
26356     // We don't need to recompute the cues' display states. Just reuse them.
26357     if (!shouldCompute(cues)) {
26358       for (var i = 0; i < cues.length; i++) {
26359         paddedOverlay.appendChild(cues[i].displayState);
26360       }
26361       return;
26362     }
26364     var boxPositions = [],
26365         containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
26366         fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
26367     var styleOptions = {
26368       font: fontSize + "px " + FONT_STYLE
26369     };
26371     (function() {
26372       var styleBox, cue;
26374       for (var i = 0; i < cues.length; i++) {
26375         cue = cues[i];
26377         // Compute the initial position and styles of the cue div.
26378         styleBox = new CueStyleBox(window, cue, styleOptions);
26379         paddedOverlay.appendChild(styleBox.div);
26381         // Move the cue div to it's correct line position.
26382         moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
26384         // Remember the computed div so that we don't have to recompute it later
26385         // if we don't have too.
26386         cue.displayState = styleBox.div;
26388         boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
26389       }
26390     })();
26391   };
26393   WebVTT.Parser = function(window, vttjs, decoder) {
26394     if (!decoder) {
26395       decoder = vttjs;
26396       vttjs = {};
26397     }
26398     if (!vttjs) {
26399       vttjs = {};
26400     }
26402     this.window = window;
26403     this.vttjs = vttjs;
26404     this.state = "INITIAL";
26405     this.buffer = "";
26406     this.decoder = decoder || new TextDecoder("utf8");
26407     this.regionList = [];
26408   };
26410   WebVTT.Parser.prototype = {
26411     // If the error is a ParsingError then report it to the consumer if
26412     // possible. If it's not a ParsingError then throw it like normal.
26413     reportOrThrowError: function(e) {
26414       if (e instanceof ParsingError) {
26415         this.onparsingerror && this.onparsingerror(e);
26416       } else {
26417         throw e;
26418       }
26419     },
26420     parse: function (data) {
26421       var self = this;
26423       // If there is no data then we won't decode it, but will just try to parse
26424       // whatever is in buffer already. This may occur in circumstances, for
26425       // example when flush() is called.
26426       if (data) {
26427         // Try to decode the data that we received.
26428         self.buffer += self.decoder.decode(data, {stream: true});
26429       }
26431       function collectNextLine() {
26432         var buffer = self.buffer;
26433         var pos = 0;
26434         while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
26435           ++pos;
26436         }
26437         var line = buffer.substr(0, pos);
26438         // Advance the buffer early in case we fail below.
26439         if (buffer[pos] === '\r') {
26440           ++pos;
26441         }
26442         if (buffer[pos] === '\n') {
26443           ++pos;
26444         }
26445         self.buffer = buffer.substr(pos);
26446         return line;
26447       }
26449       // 3.4 WebVTT region and WebVTT region settings syntax
26450       function parseRegion(input) {
26451         var settings = new Settings();
26453         parseOptions(input, function (k, v) {
26454           switch (k) {
26455           case "id":
26456             settings.set(k, v);
26457             break;
26458           case "width":
26459             settings.percent(k, v);
26460             break;
26461           case "lines":
26462             settings.integer(k, v);
26463             break;
26464           case "regionanchor":
26465           case "viewportanchor":
26466             var xy = v.split(',');
26467             if (xy.length !== 2) {
26468               break;
26469             }
26470             // We have to make sure both x and y parse, so use a temporary
26471             // settings object here.
26472             var anchor = new Settings();
26473             anchor.percent("x", xy[0]);
26474             anchor.percent("y", xy[1]);
26475             if (!anchor.has("x") || !anchor.has("y")) {
26476               break;
26477             }
26478             settings.set(k + "X", anchor.get("x"));
26479             settings.set(k + "Y", anchor.get("y"));
26480             break;
26481           case "scroll":
26482             settings.alt(k, v, ["up"]);
26483             break;
26484           }
26485         }, /=/, /\s/);
26487         // Create the region, using default values for any values that were not
26488         // specified.
26489         if (settings.has("id")) {
26490           var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
26491           region.width = settings.get("width", 100);
26492           region.lines = settings.get("lines", 3);
26493           region.regionAnchorX = settings.get("regionanchorX", 0);
26494           region.regionAnchorY = settings.get("regionanchorY", 100);
26495           region.viewportAnchorX = settings.get("viewportanchorX", 0);
26496           region.viewportAnchorY = settings.get("viewportanchorY", 100);
26497           region.scroll = settings.get("scroll", "");
26498           // Register the region.
26499           self.onregion && self.onregion(region);
26500           // Remember the VTTRegion for later in case we parse any VTTCues that
26501           // reference it.
26502           self.regionList.push({
26503             id: settings.get("id"),
26504             region: region
26505           });
26506         }
26507       }
26509       // 3.2 WebVTT metadata header syntax
26510       function parseHeader(input) {
26511         parseOptions(input, function (k, v) {
26512           switch (k) {
26513           case "Region":
26514             // 3.3 WebVTT region metadata header syntax
26515             parseRegion(v);
26516             break;
26517           }
26518         }, /:/);
26519       }
26521       // 5.1 WebVTT file parsing.
26522       try {
26523         var line;
26524         if (self.state === "INITIAL") {
26525           // We can't start parsing until we have the first line.
26526           if (!/\r\n|\n/.test(self.buffer)) {
26527             return this;
26528           }
26530           line = collectNextLine();
26532           var m = line.match(/^WEBVTT([ \t].*)?$/);
26533           if (!m || !m[0]) {
26534             throw new ParsingError(ParsingError.Errors.BadSignature);
26535           }
26537           self.state = "HEADER";
26538         }
26540         var alreadyCollectedLine = false;
26541         while (self.buffer) {
26542           // We can't parse a line until we have the full line.
26543           if (!/\r\n|\n/.test(self.buffer)) {
26544             return this;
26545           }
26547           if (!alreadyCollectedLine) {
26548             line = collectNextLine();
26549           } else {
26550             alreadyCollectedLine = false;
26551           }
26553           switch (self.state) {
26554           case "HEADER":
26555             // 13-18 - Allow a header (metadata) under the WEBVTT line.
26556             if (/:/.test(line)) {
26557               parseHeader(line);
26558             } else if (!line) {
26559               // An empty line terminates the header and starts the body (cues).
26560               self.state = "ID";
26561             }
26562             continue;
26563           case "NOTE":
26564             // Ignore NOTE blocks.
26565             if (!line) {
26566               self.state = "ID";
26567             }
26568             continue;
26569           case "ID":
26570             // Check for the start of NOTE blocks.
26571             if (/^NOTE($|[ \t])/.test(line)) {
26572               self.state = "NOTE";
26573               break;
26574             }
26575             // 19-29 - Allow any number of line terminators, then initialize new cue values.
26576             if (!line) {
26577               continue;
26578             }
26579             self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
26580             self.state = "CUE";
26581             // 30-39 - Check if self line contains an optional identifier or timing data.
26582             if (line.indexOf("-->") === -1) {
26583               self.cue.id = line;
26584               continue;
26585             }
26586             // Process line as start of a cue.
26587             /*falls through*/
26588           case "CUE":
26589             // 40 - Collect cue timings and settings.
26590             try {
26591               parseCue(line, self.cue, self.regionList);
26592             } catch (e) {
26593               self.reportOrThrowError(e);
26594               // In case of an error ignore rest of the cue.
26595               self.cue = null;
26596               self.state = "BADCUE";
26597               continue;
26598             }
26599             self.state = "CUETEXT";
26600             continue;
26601           case "CUETEXT":
26602             var hasSubstring = line.indexOf("-->") !== -1;
26603             // 34 - If we have an empty line then report the cue.
26604             // 35 - If we have the special substring '-->' then report the cue,
26605             // but do not collect the line as we need to process the current
26606             // one as a new cue.
26607             if (!line || hasSubstring && (alreadyCollectedLine = true)) {
26608               // We are done parsing self cue.
26609               self.oncue && self.oncue(self.cue);
26610               self.cue = null;
26611               self.state = "ID";
26612               continue;
26613             }
26614             if (self.cue.text) {
26615               self.cue.text += "\n";
26616             }
26617             self.cue.text += line;
26618             continue;
26619           case "BADCUE": // BADCUE
26620             // 54-62 - Collect and discard the remaining cue.
26621             if (!line) {
26622               self.state = "ID";
26623             }
26624             continue;
26625           }
26626         }
26627       } catch (e) {
26628         self.reportOrThrowError(e);
26630         // If we are currently parsing a cue, report what we have.
26631         if (self.state === "CUETEXT" && self.cue && self.oncue) {
26632           self.oncue(self.cue);
26633         }
26634         self.cue = null;
26635         // Enter BADWEBVTT state if header was not parsed correctly otherwise
26636         // another exception occurred so enter BADCUE state.
26637         self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
26638       }
26639       return this;
26640     },
26641     flush: function () {
26642       var self = this;
26643       try {
26644         // Finish decoding the stream.
26645         self.buffer += self.decoder.decode();
26646         // Synthesize the end of the current cue or region.
26647         if (self.cue || self.state === "HEADER") {
26648           self.buffer += "\n\n";
26649           self.parse();
26650         }
26651         // If we've flushed, parsed, and we're still on the INITIAL state then
26652         // that means we don't have enough of the stream to parse the first
26653         // line.
26654         if (self.state === "INITIAL") {
26655           throw new ParsingError(ParsingError.Errors.BadSignature);
26656         }
26657       } catch(e) {
26658         self.reportOrThrowError(e);
26659       }
26660       self.onflush && self.onflush();
26661       return this;
26662     }
26663   };
26665   global.WebVTT = WebVTT;
26667 }(this, (this.vttjs || {})));