c37fda1edc7a5184b05509620a1fa10f0965296e
[yaffs-website] / node_modules / video.js / dist / video.js
1 /**
2  * @license
3  * Video.js 5.19.2 <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  */
12
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';
15
16 exports.__esModule = true;
17
18 var _button = _dereq_(2);
19
20 var _button2 = _interopRequireDefault(_button);
21
22 var _component = _dereq_(5);
23
24 var _component2 = _interopRequireDefault(_component);
25
26 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
27
28 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
29
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; }
31
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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
35
36
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);
45
46   function BigPlayButton() {
47     _classCallCheck(this, BigPlayButton);
48
49     return _possibleConstructorReturn(this, _Button.apply(this, arguments));
50   }
51
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   };
61
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    */
73
74
75   BigPlayButton.prototype.handleClick = function handleClick(event) {
76     this.player_.play();
77
78     var cb = this.player_.getChild('controlBar');
79     var playToggle = cb && cb.getChild('playToggle');
80
81     if (!playToggle) {
82       this.player_.focus();
83       return;
84     }
85
86     this.setTimeout(function () {
87       playToggle.focus();
88     }, 1);
89   };
90
91   return BigPlayButton;
92 }(_button2['default']);
93
94 /**
95  * The text that should display over the `BigPlayButton`s controls. Added to for localization.
96  *
97  * @type {string}
98  * @private
99  */
100
101
102 BigPlayButton.prototype.controlText_ = 'Play Video';
103
104 _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
105 exports['default'] = BigPlayButton;
106
107 },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
108 'use strict';
109
110 exports.__esModule = true;
111
112 var _clickableComponent = _dereq_(3);
113
114 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
115
116 var _component = _dereq_(5);
117
118 var _component2 = _interopRequireDefault(_component);
119
120 var _log = _dereq_(86);
121
122 var _log2 = _interopRequireDefault(_log);
123
124 var _obj = _dereq_(88);
125
126 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
127
128 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
129
130 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; }
131
132 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; } /**
133                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file button.js
134                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
135
136
137 /**
138  * Base class for all buttons.
139  *
140  * @extends ClickableComponent
141  */
142 var Button = function (_ClickableComponent) {
143   _inherits(Button, _ClickableComponent);
144
145   function Button() {
146     _classCallCheck(this, Button);
147
148     return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
149   }
150
151   /**
152    * Create the `Button`s DOM element.
153    *
154    * @param {string} [tag=button]
155    *        Element's node type. e.g. 'button'
156    *
157    * @param {Object} [props={}]
158    *        An object of properties that should be set on the element.
159    *
160    * @param {Object} [attributes={}]
161    *        An object of attributes that should be set on the element.
162    *
163    * @return {Element}
164    *         The element that gets created.
165    */
166   Button.prototype.createEl = function createEl() {
167     var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
168     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
169     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
170
171     props = (0, _obj.assign)({
172       className: this.buildCSSClass()
173     }, props);
174
175     if (tag !== 'button') {
176       _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
177
178       // Add properties for clickable element which is not a native HTML button
179       props = (0, _obj.assign)({
180         tabIndex: 0
181       }, props);
182
183       // Add ARIA attributes for clickable element which is not a native HTML button
184       attributes = (0, _obj.assign)({
185         role: 'button'
186       }, attributes);
187     }
188
189     // Add attributes for button element
190     attributes = (0, _obj.assign)({
191
192       // Necessary since the default button type is "submit"
193       'type': 'button',
194
195       // let the screen reader user know that the text of the button may change
196       'aria-live': 'polite'
197     }, attributes);
198
199     var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
200
201     this.createControlTextEl(el);
202
203     return el;
204   };
205
206   /**
207    * Add a child `Component` inside of this `Button`.
208    *
209    * @param {string|Component} child
210    *        The name or instance of a child to add.
211    *
212    * @param {Object} [options={}]
213    *        The key/value store of options that will get passed to children of
214    *        the child.
215    *
216    * @return {Component}
217    *         The `Component` that gets added as a child. When using a string the
218    *         `Component` will get created by this process.
219    *
220    * @deprecated since version 5
221    */
222
223
224   Button.prototype.addChild = function addChild(child) {
225     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
226
227     var className = this.constructor.name;
228
229     _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
230
231     // Avoid the error message generated by ClickableComponent's addChild method
232     return _component2['default'].prototype.addChild.call(this, child, options);
233   };
234
235   /**
236    * Enable the `Button` element so that it can be activated or clicked. Use this with
237    * {@link Button#disable}.
238    */
239
240
241   Button.prototype.enable = function enable() {
242     _ClickableComponent.prototype.enable.call(this);
243     this.el_.removeAttribute('disabled');
244   };
245
246   /**
247    * Enable the `Button` element so that it cannot be activated or clicked. Use this with
248    * {@link Button#enable}.
249    */
250
251
252   Button.prototype.disable = function disable() {
253     _ClickableComponent.prototype.disable.call(this);
254     this.el_.setAttribute('disabled', 'disabled');
255   };
256
257   /**
258    * This gets called when a `Button` has focus and `keydown` is triggered via a key
259    * press.
260    *
261    * @param {EventTarget~Event} event
262    *        The event that caused this function to get called.
263    *
264    * @listens keydown
265    */
266
267
268   Button.prototype.handleKeyPress = function handleKeyPress(event) {
269
270     // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
271     if (event.which === 32 || event.which === 13) {
272       return;
273     }
274
275     // Pass keypress handling up for unsupported keys
276     _ClickableComponent.prototype.handleKeyPress.call(this, event);
277   };
278
279   return Button;
280 }(_clickableComponent2['default']);
281
282 _component2['default'].registerComponent('Button', Button);
283 exports['default'] = Button;
284
285 },{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){
286 'use strict';
287
288 exports.__esModule = true;
289
290 var _component = _dereq_(5);
291
292 var _component2 = _interopRequireDefault(_component);
293
294 var _dom = _dereq_(81);
295
296 var Dom = _interopRequireWildcard(_dom);
297
298 var _events = _dereq_(82);
299
300 var Events = _interopRequireWildcard(_events);
301
302 var _fn = _dereq_(83);
303
304 var Fn = _interopRequireWildcard(_fn);
305
306 var _log = _dereq_(86);
307
308 var _log2 = _interopRequireDefault(_log);
309
310 var _document = _dereq_(94);
311
312 var _document2 = _interopRequireDefault(_document);
313
314 var _obj = _dereq_(88);
315
316 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; } }
317
318 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
319
320 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
321
322 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; }
323
324 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; } /**
325                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file button.js
326                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
327
328
329 /**
330  * Clickable Component which is clickable or keyboard actionable,
331  * but is not a native HTML button.
332  *
333  * @extends Component
334  */
335 var ClickableComponent = function (_Component) {
336   _inherits(ClickableComponent, _Component);
337
338   /**
339    * Creates an instance of this class.
340    *
341    * @param  {Player} player
342    *         The `Player` that this class should be attached to.
343    *
344    * @param  {Object} [options]
345    *         The key/value store of player options.
346    */
347   function ClickableComponent(player, options) {
348     _classCallCheck(this, ClickableComponent);
349
350     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
351
352     _this.emitTapEvents();
353
354     _this.enable();
355     return _this;
356   }
357
358   /**
359    * Create the `Component`s DOM element.
360    *
361    * @param {string} [tag=div]
362    *        The element's node type.
363    *
364    * @param {Object} [props={}]
365    *        An object of properties that should be set on the element.
366    *
367    * @param {Object} [attributes={}]
368    *        An object of attributes that should be set on the element.
369    *
370    * @return {Element}
371    *         The element that gets created.
372    */
373
374
375   ClickableComponent.prototype.createEl = function createEl() {
376     var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
377     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
378     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
379
380     props = (0, _obj.assign)({
381       className: this.buildCSSClass(),
382       tabIndex: 0
383     }, props);
384
385     if (tag === 'button') {
386       _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
387     }
388
389     // Add ARIA attributes for clickable element which is not a native HTML button
390     attributes = (0, _obj.assign)({
391       'role': 'button',
392
393       // let the screen reader user know that the text of the element may change
394       'aria-live': 'polite'
395     }, attributes);
396
397     this.tabIndex_ = props.tabIndex;
398
399     var el = _Component.prototype.createEl.call(this, tag, props, attributes);
400
401     this.createControlTextEl(el);
402
403     return el;
404   };
405
406   /**
407    * Create a control text element on this `Component`
408    *
409    * @param {Element} [el]
410    *        Parent element for the control text.
411    *
412    * @return {Element}
413    *         The control text element that gets created.
414    */
415
416
417   ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
418     this.controlTextEl_ = Dom.createEl('span', {
419       className: 'vjs-control-text'
420     });
421
422     if (el) {
423       el.appendChild(this.controlTextEl_);
424     }
425
426     this.controlText(this.controlText_, el);
427
428     return this.controlTextEl_;
429   };
430
431   /**
432    * Get or set the localize text to use for the controls on the `Component`.
433    *
434    * @param {string} [text]
435    *        Control text for element.
436    *
437    * @param {Element} [el=this.el()]
438    *        Element to set the title on.
439    *
440    * @return {string|ClickableComponent}
441    *         - The control text when getting
442    *         - Returns itself when setting; method can be chained.
443    */
444
445
446   ClickableComponent.prototype.controlText = function controlText(text) {
447     var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
448
449     if (!text) {
450       return this.controlText_ || 'Need Text';
451     }
452
453     var localizedText = this.localize(text);
454
455     this.controlText_ = text;
456     this.controlTextEl_.innerHTML = localizedText;
457
458     if (!this.nonIconControl) {
459       // Set title attribute if only an icon is shown
460       el.setAttribute('title', localizedText);
461     }
462
463     return this;
464   };
465
466   /**
467    * Builds the default DOM `className`.
468    *
469    * @return {string}
470    *         The DOM `className` for this object.
471    */
472
473
474   ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
475     return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
476   };
477
478   /**
479    * Enable this `Component`s element.
480    *
481    * @return {ClickableComponent}
482    *         Returns itself; method can be chained.
483    */
484
485
486   ClickableComponent.prototype.enable = function enable() {
487     this.removeClass('vjs-disabled');
488     this.el_.setAttribute('aria-disabled', 'false');
489     if (typeof this.tabIndex_ !== 'undefined') {
490       this.el_.setAttribute('tabIndex', this.tabIndex_);
491     }
492     this.on('tap', this.handleClick);
493     this.on('click', this.handleClick);
494     this.on('focus', this.handleFocus);
495     this.on('blur', this.handleBlur);
496     return this;
497   };
498
499   /**
500    * Disable this `Component`s element.
501    *
502    * @return {ClickableComponent}
503    *         Returns itself; method can be chained.
504    */
505
506
507   ClickableComponent.prototype.disable = function disable() {
508     this.addClass('vjs-disabled');
509     this.el_.setAttribute('aria-disabled', 'true');
510     if (typeof this.tabIndex_ !== 'undefined') {
511       this.el_.removeAttribute('tabIndex');
512     }
513     this.off('tap', this.handleClick);
514     this.off('click', this.handleClick);
515     this.off('focus', this.handleFocus);
516     this.off('blur', this.handleBlur);
517     return this;
518   };
519
520   /**
521    * This gets called when a `ClickableComponent` gets:
522    * - Clicked (via the `click` event, listening starts in the constructor)
523    * - Tapped (via the `tap` event, listening starts in the constructor)
524    * - The following things happen in order:
525    *   1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
526    *      `ClickableComponent`.
527    *   2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
528    *      {@link ClickableComponent#handleKeyPress}.
529    *   3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
530    *      the space or enter key.
531    *   4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
532    *      event as a parameter.
533    *
534    * @param {EventTarget~Event} event
535    *        The `keydown`, `tap`, or `click` event that caused this function to be
536    *        called.
537    *
538    * @listens tap
539    * @listens click
540    * @abstract
541    */
542
543
544   ClickableComponent.prototype.handleClick = function handleClick(event) {};
545
546   /**
547    * This gets called when a `ClickableComponent` gains focus via a `focus` event.
548    * Turns on listening for `keydown` events. When they happen it
549    * calls `this.handleKeyPress`.
550    *
551    * @param {EventTarget~Event} event
552    *        The `focus` event that caused this function to be called.
553    *
554    * @listens focus
555    */
556
557
558   ClickableComponent.prototype.handleFocus = function handleFocus(event) {
559     Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
560   };
561
562   /**
563    * Called when this ClickableComponent has focus and a key gets pressed down. By
564    * default it will call `this.handleClick` when the key is space or enter.
565    *
566    * @param {EventTarget~Event} event
567    *        The `keydown` event that caused this function to be called.
568    *
569    * @listens keydown
570    */
571
572
573   ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
574
575     // Support Space (32) or Enter (13) key operation to fire a click event
576     if (event.which === 32 || event.which === 13) {
577       event.preventDefault();
578       this.handleClick(event);
579     } else if (_Component.prototype.handleKeyPress) {
580
581       // Pass keypress handling up for unsupported keys
582       _Component.prototype.handleKeyPress.call(this, event);
583     }
584   };
585
586   /**
587    * Called when a `ClickableComponent` loses focus. Turns off the listener for
588    * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
589    *
590    * @param {EventTarget~Event} event
591    *        The `blur` event that caused this function to be called.
592    *
593    * @listens blur
594    */
595
596
597   ClickableComponent.prototype.handleBlur = function handleBlur(event) {
598     Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
599   };
600
601   return ClickableComponent;
602 }(_component2['default']);
603
604 _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
605 exports['default'] = ClickableComponent;
606
607 },{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){
608 'use strict';
609
610 exports.__esModule = true;
611
612 var _button = _dereq_(2);
613
614 var _button2 = _interopRequireDefault(_button);
615
616 var _component = _dereq_(5);
617
618 var _component2 = _interopRequireDefault(_component);
619
620 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
621
622 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
623
624 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; }
625
626 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; } /**
627                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file close-button.js
628                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
629
630
631 /**
632  * The `CloseButton` is a `{@link Button}` that fires a `close` event when
633  * it gets clicked.
634  *
635  * @extends Button
636  */
637 var CloseButton = function (_Button) {
638   _inherits(CloseButton, _Button);
639
640   /**
641    * Creates an instance of the this class.
642    *
643    * @param  {Player} player
644    *         The `Player` that this class should be attached to.
645    *
646    * @param  {Object} [options]
647    *         The key/value store of player options.
648    */
649   function CloseButton(player, options) {
650     _classCallCheck(this, CloseButton);
651
652     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
653
654     _this.controlText(options && options.controlText || _this.localize('Close'));
655     return _this;
656   }
657
658   /**
659    * Builds the default DOM `className`.
660    *
661    * @return {string}
662    *         The DOM `className` for this object.
663    */
664
665
666   CloseButton.prototype.buildCSSClass = function buildCSSClass() {
667     return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
668   };
669
670   /**
671    * This gets called when a `CloseButton` gets clicked. See
672    * {@link ClickableComponent#handleClick} for more information on when this will be
673    * triggered
674    *
675    * @param {EventTarget~Event} event
676    *        The `keydown`, `tap`, or `click` event that caused this function to be
677    *        called.
678    *
679    * @listens tap
680    * @listens click
681    * @fires CloseButton#close
682    */
683
684
685   CloseButton.prototype.handleClick = function handleClick(event) {
686
687     /**
688      * Triggered when the a `CloseButton` is clicked.
689      *
690      * @event CloseButton#close
691      * @type {EventTarget~Event}
692      *
693      * @property {boolean} [bubbles=false]
694      *           set to false so that the close event does not
695      *           bubble up to parents if there is no listener
696      */
697     this.trigger({ type: 'close', bubbles: false });
698   };
699
700   return CloseButton;
701 }(_button2['default']);
702
703 _component2['default'].registerComponent('CloseButton', CloseButton);
704 exports['default'] = CloseButton;
705
706 },{"2":2,"5":5}],5:[function(_dereq_,module,exports){
707 'use strict';
708
709 exports.__esModule = true;
710
711 var _window = _dereq_(95);
712
713 var _window2 = _interopRequireDefault(_window);
714
715 var _dom = _dereq_(81);
716
717 var Dom = _interopRequireWildcard(_dom);
718
719 var _fn = _dereq_(83);
720
721 var Fn = _interopRequireWildcard(_fn);
722
723 var _guid = _dereq_(85);
724
725 var Guid = _interopRequireWildcard(_guid);
726
727 var _events = _dereq_(82);
728
729 var Events = _interopRequireWildcard(_events);
730
731 var _log = _dereq_(86);
732
733 var _log2 = _interopRequireDefault(_log);
734
735 var _toTitleCase = _dereq_(91);
736
737 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
738
739 var _mergeOptions = _dereq_(87);
740
741 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
742
743 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; } }
744
745 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
746
747 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
748                                                                                                                                                            * Player Component - Base class for all UI objects
749                                                                                                                                                            *
750                                                                                                                                                            * @file component.js
751                                                                                                                                                            */
752
753
754 /**
755  * Base class for all UI Components.
756  * Components are UI objects which represent both a javascript object and an element
757  * in the DOM. They can be children of other components, and can have
758  * children themselves.
759  *
760  * Components can also use methods from {@link EventTarget}
761  */
762 var Component = function () {
763
764   /**
765    * A callback that is called when a component is ready. Does not have any
766    * paramters and any callback value will be ignored.
767    *
768    * @callback Component~ReadyCallback
769    * @this Component
770    */
771
772   /**
773    * Creates an instance of this class.
774    *
775    * @param {Player} player
776    *        The `Player` that this class should be attached to.
777    *
778    * @param {Object} [options]
779    *        The key/value store of player options.
780    #
781    * @param {Object[]} [options.children]
782    *        An array of children objects to intialize this component with. Children objects have
783    *        a name property that will be used if more than one component of the same type needs to be
784    *        added.
785    *
786    * @param {Component~ReadyCallback} [ready]
787    *        Function that gets called when the `Component` is ready.
788    */
789   function Component(player, options, ready) {
790     _classCallCheck(this, Component);
791
792     // The component might be the player itself and we can't pass `this` to super
793     if (!player && this.play) {
794       this.player_ = player = this; // eslint-disable-line
795     } else {
796       this.player_ = player;
797     }
798
799     // Make a copy of prototype.options_ to protect against overriding defaults
800     this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
801
802     // Updated options with supplied options
803     options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
804
805     // Get ID from options or options element if one is supplied
806     this.id_ = options.id || options.el && options.el.id;
807
808     // If there was no ID from the options, generate one
809     if (!this.id_) {
810       // Don't require the player ID function in the case of mock players
811       var id = player && player.id && player.id() || 'no_player';
812
813       this.id_ = id + '_component_' + Guid.newGUID();
814     }
815
816     this.name_ = options.name || null;
817
818     // Create element if one wasn't provided in options
819     if (options.el) {
820       this.el_ = options.el;
821     } else if (options.createEl !== false) {
822       this.el_ = this.createEl();
823     }
824
825     this.children_ = [];
826     this.childIndex_ = {};
827     this.childNameIndex_ = {};
828
829     // Add any child components in options
830     if (options.initChildren !== false) {
831       this.initChildren();
832     }
833
834     this.ready(ready);
835     // Don't want to trigger ready here or it will before init is actually
836     // finished for all children that run this constructor
837
838     if (options.reportTouchActivity !== false) {
839       this.enableTouchActivity();
840     }
841   }
842
843   /**
844    * Dispose of the `Component` and all child components.
845    *
846    * @fires Component#dispose
847    */
848
849
850   Component.prototype.dispose = function dispose() {
851
852     /**
853      * Triggered when a `Component` is disposed.
854      *
855      * @event Component#dispose
856      * @type {EventTarget~Event}
857      *
858      * @property {boolean} [bubbles=false]
859      *           set to false so that the close event does not
860      *           bubble up
861      */
862     this.trigger({ type: 'dispose', bubbles: false });
863
864     // Dispose all children.
865     if (this.children_) {
866       for (var i = this.children_.length - 1; i >= 0; i--) {
867         if (this.children_[i].dispose) {
868           this.children_[i].dispose();
869         }
870       }
871     }
872
873     // Delete child references
874     this.children_ = null;
875     this.childIndex_ = null;
876     this.childNameIndex_ = null;
877
878     // Remove all event listeners.
879     this.off();
880
881     // Remove element from DOM
882     if (this.el_.parentNode) {
883       this.el_.parentNode.removeChild(this.el_);
884     }
885
886     Dom.removeElData(this.el_);
887     this.el_ = null;
888   };
889
890   /**
891    * Return the {@link Player} that the `Component` has attached to.
892    *
893    * @return {Player}
894    *         The player that this `Component` has attached to.
895    */
896
897
898   Component.prototype.player = function player() {
899     return this.player_;
900   };
901
902   /**
903    * Deep merge of options objects with new options.
904    * > Note: When both `obj` and `options` contain properties whose values are objects.
905    *         The two properties get merged using {@link module:mergeOptions}
906    *
907    * @param {Object} obj
908    *        The object that contains new options.
909    *
910    * @return {Object}
911    *         A new object of `this.options_` and `obj` merged together.
912    *
913    * @deprecated since version 5
914    */
915
916
917   Component.prototype.options = function options(obj) {
918     _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
919
920     if (!obj) {
921       return this.options_;
922     }
923
924     this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
925     return this.options_;
926   };
927
928   /**
929    * Get the `Component`s DOM element
930    *
931    * @return {Element}
932    *         The DOM element for this `Component`.
933    */
934
935
936   Component.prototype.el = function el() {
937     return this.el_;
938   };
939
940   /**
941    * Create the `Component`s DOM element.
942    *
943    * @param {string} [tagName]
944    *        Element's DOM node type. e.g. 'div'
945    *
946    * @param {Object} [properties]
947    *        An object of properties that should be set.
948    *
949    * @param {Object} [attributes]
950    *        An object of attributes that should be set.
951    *
952    * @return {Element}
953    *         The element that gets created.
954    */
955
956
957   Component.prototype.createEl = function createEl(tagName, properties, attributes) {
958     return Dom.createEl(tagName, properties, attributes);
959   };
960
961   /**
962    * Localize a string given the string in english.
963    *
964    * @param {string} string
965    *        The string to localize.
966    *
967    * @return {string}
968    *         The localized string or if no localization exists the english string.
969    */
970
971
972   Component.prototype.localize = function localize(string) {
973     var code = this.player_.language && this.player_.language();
974     var languages = this.player_.languages && this.player_.languages();
975
976     if (!code || !languages) {
977       return string;
978     }
979
980     var language = languages[code];
981
982     if (language && language[string]) {
983       return language[string];
984     }
985
986     var primaryCode = code.split('-')[0];
987     var primaryLang = languages[primaryCode];
988
989     if (primaryLang && primaryLang[string]) {
990       return primaryLang[string];
991     }
992
993     return string;
994   };
995
996   /**
997    * Return the `Component`s DOM element. This is where children get inserted.
998    * This will usually be the the same as the element returned in {@link Component#el}.
999    *
1000    * @return {Element}
1001    *         The content element for this `Component`.
1002    */
1003
1004
1005   Component.prototype.contentEl = function contentEl() {
1006     return this.contentEl_ || this.el_;
1007   };
1008
1009   /**
1010    * Get this `Component`s ID
1011    *
1012    * @return {string}
1013    *         The id of this `Component`
1014    */
1015
1016
1017   Component.prototype.id = function id() {
1018     return this.id_;
1019   };
1020
1021   /**
1022    * Get the `Component`s name. The name gets used to reference the `Component`
1023    * and is set during registration.
1024    *
1025    * @return {string}
1026    *         The name of this `Component`.
1027    */
1028
1029
1030   Component.prototype.name = function name() {
1031     return this.name_;
1032   };
1033
1034   /**
1035    * Get an array of all child components
1036    *
1037    * @return {Array}
1038    *         The children
1039    */
1040
1041
1042   Component.prototype.children = function children() {
1043     return this.children_;
1044   };
1045
1046   /**
1047    * Returns the child `Component` with the given `id`.
1048    *
1049    * @param {string} id
1050    *        The id of the child `Component` to get.
1051    *
1052    * @return {Component|undefined}
1053    *         The child `Component` with the given `id` or undefined.
1054    */
1055
1056
1057   Component.prototype.getChildById = function getChildById(id) {
1058     return this.childIndex_[id];
1059   };
1060
1061   /**
1062    * Returns the child `Component` with the given `name`.
1063    *
1064    * @param {string} name
1065    *        The name of the child `Component` to get.
1066    *
1067    * @return {Component|undefined}
1068    *         The child `Component` with the given `name` or undefined.
1069    */
1070
1071
1072   Component.prototype.getChild = function getChild(name) {
1073     if (!name) {
1074       return;
1075     }
1076
1077     name = (0, _toTitleCase2['default'])(name);
1078
1079     return this.childNameIndex_[name];
1080   };
1081
1082   /**
1083    * Add a child `Component` inside the current `Component`.
1084    *
1085    *
1086    * @param {string|Component} child
1087    *        The name or instance of a child to add.
1088    *
1089    * @param {Object} [options={}]
1090    *        The key/value store of options that will get passed to children of
1091    *        the child.
1092    *
1093    * @param {number} [index=this.children_.length]
1094    *        The index to attempt to add a child into.
1095    *
1096    * @return {Component}
1097    *         The `Component` that gets added as a child. When using a string the
1098    *         `Component` will get created by this process.
1099    */
1100
1101
1102   Component.prototype.addChild = function addChild(child) {
1103     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1104     var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
1105
1106     var component = void 0;
1107     var componentName = void 0;
1108
1109     // If child is a string, create component with options
1110     if (typeof child === 'string') {
1111       componentName = (0, _toTitleCase2['default'])(child);
1112
1113       // Options can also be specified as a boolean,
1114       // so convert to an empty object if false.
1115       if (!options) {
1116         options = {};
1117       }
1118
1119       // Same as above, but true is deprecated so show a warning.
1120       if (options === true) {
1121         _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`.');
1122         options = {};
1123       }
1124
1125       var componentClassName = options.componentClass || componentName;
1126
1127       // Set name through options
1128       options.name = componentName;
1129
1130       // Create a new object & element for this controls set
1131       // If there's no .player_, this is a player
1132       var ComponentClass = Component.getComponent(componentClassName);
1133
1134       if (!ComponentClass) {
1135         throw new Error('Component ' + componentClassName + ' does not exist');
1136       }
1137
1138       // data stored directly on the videojs object may be
1139       // misidentified as a component to retain
1140       // backwards-compatibility with 4.x. check to make sure the
1141       // component class can be instantiated.
1142       if (typeof ComponentClass !== 'function') {
1143         return null;
1144       }
1145
1146       component = new ComponentClass(this.player_ || this, options);
1147
1148       // child is a component instance
1149     } else {
1150       component = child;
1151     }
1152
1153     this.children_.splice(index, 0, component);
1154
1155     if (typeof component.id === 'function') {
1156       this.childIndex_[component.id()] = component;
1157     }
1158
1159     // If a name wasn't used to create the component, check if we can use the
1160     // name function of the component
1161     componentName = componentName || component.name && (0, _toTitleCase2['default'])(component.name());
1162
1163     if (componentName) {
1164       this.childNameIndex_[componentName] = component;
1165     }
1166
1167     // Add the UI object's element to the container div (box)
1168     // Having an element is not required
1169     if (typeof component.el === 'function' && component.el()) {
1170       var childNodes = this.contentEl().children;
1171       var refNode = childNodes[index] || null;
1172
1173       this.contentEl().insertBefore(component.el(), refNode);
1174     }
1175
1176     // Return so it can stored on parent object if desired.
1177     return component;
1178   };
1179
1180   /**
1181    * Remove a child `Component` from this `Component`s list of children. Also removes
1182    * the child `Component`s element from this `Component`s element.
1183    *
1184    * @param {Component} component
1185    *        The child `Component` to remove.
1186    */
1187
1188
1189   Component.prototype.removeChild = function removeChild(component) {
1190     if (typeof component === 'string') {
1191       component = this.getChild(component);
1192     }
1193
1194     if (!component || !this.children_) {
1195       return;
1196     }
1197
1198     var childFound = false;
1199
1200     for (var i = this.children_.length - 1; i >= 0; i--) {
1201       if (this.children_[i] === component) {
1202         childFound = true;
1203         this.children_.splice(i, 1);
1204         break;
1205       }
1206     }
1207
1208     if (!childFound) {
1209       return;
1210     }
1211
1212     this.childIndex_[component.id()] = null;
1213     this.childNameIndex_[component.name()] = null;
1214
1215     var compEl = component.el();
1216
1217     if (compEl && compEl.parentNode === this.contentEl()) {
1218       this.contentEl().removeChild(component.el());
1219     }
1220   };
1221
1222   /**
1223    * Add and initialize default child `Component`s based upon options.
1224    */
1225
1226
1227   Component.prototype.initChildren = function initChildren() {
1228     var _this = this;
1229
1230     var children = this.options_.children;
1231
1232     if (children) {
1233       // `this` is `parent`
1234       var parentOptions = this.options_;
1235
1236       var handleAdd = function handleAdd(child) {
1237         var name = child.name;
1238         var opts = child.opts;
1239
1240         // Allow options for children to be set at the parent options
1241         // e.g. videojs(id, { controlBar: false });
1242         // instead of videojs(id, { children: { controlBar: false });
1243         if (parentOptions[name] !== undefined) {
1244           opts = parentOptions[name];
1245         }
1246
1247         // Allow for disabling default components
1248         // e.g. options['children']['posterImage'] = false
1249         if (opts === false) {
1250           return;
1251         }
1252
1253         // Allow options to be passed as a simple boolean if no configuration
1254         // is necessary.
1255         if (opts === true) {
1256           opts = {};
1257         }
1258
1259         // We also want to pass the original player options
1260         // to each component as well so they don't need to
1261         // reach back into the player for options later.
1262         opts.playerOptions = _this.options_.playerOptions;
1263
1264         // Create and add the child component.
1265         // Add a direct reference to the child by name on the parent instance.
1266         // If two of the same component are used, different names should be supplied
1267         // for each
1268         var newChild = _this.addChild(name, opts);
1269
1270         if (newChild) {
1271           _this[name] = newChild;
1272         }
1273       };
1274
1275       // Allow for an array of children details to passed in the options
1276       var workingChildren = void 0;
1277       var Tech = Component.getComponent('Tech');
1278
1279       if (Array.isArray(children)) {
1280         workingChildren = children;
1281       } else {
1282         workingChildren = Object.keys(children);
1283       }
1284
1285       workingChildren
1286       // children that are in this.options_ but also in workingChildren  would
1287       // give us extra children we do not want. So, we want to filter them out.
1288       .concat(Object.keys(this.options_).filter(function (child) {
1289         return !workingChildren.some(function (wchild) {
1290           if (typeof wchild === 'string') {
1291             return child === wchild;
1292           }
1293           return child === wchild.name;
1294         });
1295       })).map(function (child) {
1296         var name = void 0;
1297         var opts = void 0;
1298
1299         if (typeof child === 'string') {
1300           name = child;
1301           opts = children[name] || _this.options_[name] || {};
1302         } else {
1303           name = child.name;
1304           opts = child;
1305         }
1306
1307         return { name: name, opts: opts };
1308       }).filter(function (child) {
1309         // we have to make sure that child.name isn't in the techOrder since
1310         // techs are registerd as Components but can't aren't compatible
1311         // See https://github.com/videojs/video.js/issues/2772
1312         var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
1313
1314         return c && !Tech.isTech(c);
1315       }).forEach(handleAdd);
1316     }
1317   };
1318
1319   /**
1320    * Builds the default DOM class name. Should be overriden by sub-components.
1321    *
1322    * @return {string}
1323    *         The DOM class name for this object.
1324    *
1325    * @abstract
1326    */
1327
1328
1329   Component.prototype.buildCSSClass = function buildCSSClass() {
1330     // Child classes can include a function that does:
1331     // return 'CLASS NAME' + this._super();
1332     return '';
1333   };
1334
1335   /**
1336    * Add an `event listener` to this `Component`s element.
1337    *
1338    * The benefit of using this over the following:
1339    * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
1340    * - `otherComponent.on('eventName', myFunc)`
1341    *
1342    * 1. Is that the listeners will get cleaned up when either component gets disposed.
1343    * 1. It will also bind `myComponent` as the context of `myFunc`.
1344    * > NOTE: If you remove the element from the DOM that has used `on` you need to
1345    *         clean up references using: `myComponent.trigger(el, 'dispose')`
1346    *         This will also allow the browser to garbage collect it. In special
1347    *         cases such as with `window` and `document`, which are both permanent,
1348    *         this is not necessary.
1349    *
1350    * @param {string|Component|string[]} [first]
1351    *        The event name, and array of event names, or another `Component`.
1352    *
1353    * @param {EventTarget~EventListener|string|string[]} [second]
1354    *        The listener function, an event name, or an Array of events names.
1355    *
1356    * @param {EventTarget~EventListener} [third]
1357    *        The event handler if `first` is a `Component` and `second` is an event name
1358    *        or an Array of event names.
1359    *
1360    * @return {Component}
1361    *         Returns itself; method can be chained.
1362    *
1363    * @listens Component#dispose
1364    */
1365
1366
1367   Component.prototype.on = function on(first, second, third) {
1368     var _this2 = this;
1369
1370     if (typeof first === 'string' || Array.isArray(first)) {
1371       Events.on(this.el_, first, Fn.bind(this, second));
1372
1373       // Targeting another component or element
1374     } else {
1375       var target = first;
1376       var type = second;
1377       var fn = Fn.bind(this, third);
1378
1379       // When this component is disposed, remove the listener from the other component
1380       var removeOnDispose = function removeOnDispose() {
1381         return _this2.off(target, type, fn);
1382       };
1383
1384       // Use the same function ID so we can remove it later it using the ID
1385       // of the original listener
1386       removeOnDispose.guid = fn.guid;
1387       this.on('dispose', removeOnDispose);
1388
1389       // If the other component is disposed first we need to clean the reference
1390       // to the other component in this component's removeOnDispose listener
1391       // Otherwise we create a memory leak.
1392       var cleanRemover = function cleanRemover() {
1393         return _this2.off('dispose', removeOnDispose);
1394       };
1395
1396       // Add the same function ID so we can easily remove it later
1397       cleanRemover.guid = fn.guid;
1398
1399       // Check if this is a DOM node
1400       if (first.nodeName) {
1401         // Add the listener to the other element
1402         Events.on(target, type, fn);
1403         Events.on(target, 'dispose', cleanRemover);
1404
1405         // Should be a component
1406         // Not using `instanceof Component` because it makes mock players difficult
1407       } else if (typeof first.on === 'function') {
1408         // Add the listener to the other component
1409         target.on(type, fn);
1410         target.on('dispose', cleanRemover);
1411       }
1412     }
1413
1414     return this;
1415   };
1416
1417   /**
1418    * Remove an event listener from this `Component`s element. If the second argument is
1419    * exluded all listeners for the type passed in as the first argument will be removed.
1420    *
1421    * @param {string|Component|string[]} [first]
1422    *        The event name, and array of event names, or another `Component`.
1423    *
1424    * @param {EventTarget~EventListener|string|string[]} [second]
1425    *        The listener function, an event name, or an Array of events names.
1426    *
1427    * @param {EventTarget~EventListener} [third]
1428    *        The event handler if `first` is a `Component` and `second` is an event name
1429    *        or an Array of event names.
1430    *
1431    * @return {Component}
1432    *         Returns itself; method can be chained.
1433    */
1434
1435
1436   Component.prototype.off = function off(first, second, third) {
1437     if (!first || typeof first === 'string' || Array.isArray(first)) {
1438       Events.off(this.el_, first, second);
1439     } else {
1440       var target = first;
1441       var type = second;
1442       // Ensure there's at least a guid, even if the function hasn't been used
1443       var fn = Fn.bind(this, third);
1444
1445       // Remove the dispose listener on this component,
1446       // which was given the same guid as the event listener
1447       this.off('dispose', fn);
1448
1449       if (first.nodeName) {
1450         // Remove the listener
1451         Events.off(target, type, fn);
1452         // Remove the listener for cleaning the dispose listener
1453         Events.off(target, 'dispose', fn);
1454       } else {
1455         target.off(type, fn);
1456         target.off('dispose', fn);
1457       }
1458     }
1459
1460     return this;
1461   };
1462
1463   /**
1464    * Add an event listener that gets triggered only once and then gets removed.
1465    *
1466    * @param {string|Component|string[]} [first]
1467    *        The event name, and array of event names, or another `Component`.
1468    *
1469    * @param {EventTarget~EventListener|string|string[]} [second]
1470    *        The listener function, an event name, or an Array of events names.
1471    *
1472    * @param {EventTarget~EventListener} [third]
1473    *        The event handler if `first` is a `Component` and `second` is an event name
1474    *        or an Array of event names.
1475    *
1476    * @return {Component}
1477    *         Returns itself; method can be chained.
1478    */
1479
1480
1481   Component.prototype.one = function one(first, second, third) {
1482     var _this3 = this,
1483         _arguments = arguments;
1484
1485     if (typeof first === 'string' || Array.isArray(first)) {
1486       Events.one(this.el_, first, Fn.bind(this, second));
1487     } else {
1488       var target = first;
1489       var type = second;
1490       var fn = Fn.bind(this, third);
1491
1492       var newFunc = function newFunc() {
1493         _this3.off(target, type, newFunc);
1494         fn.apply(null, _arguments);
1495       };
1496
1497       // Keep the same function ID so we can remove it later
1498       newFunc.guid = fn.guid;
1499
1500       this.on(target, type, newFunc);
1501     }
1502
1503     return this;
1504   };
1505
1506   /**
1507    * Trigger an event on an element.
1508    *
1509    * @param {EventTarget~Event|Object|string} event
1510    *        The event name, and Event, or an event-like object with a type attribute
1511    *        set to the event name.
1512    *
1513    * @param {Object} [hash]
1514    *        Data hash to pass along with the event
1515    *
1516    * @return {Component}
1517    *         Returns itself; method can be chained.
1518    */
1519
1520
1521   Component.prototype.trigger = function trigger(event, hash) {
1522     Events.trigger(this.el_, event, hash);
1523     return this;
1524   };
1525
1526   /**
1527    * Bind a listener to the component's ready state. If the ready event has already
1528    * happened it will trigger the function immediately.
1529    *
1530    * @param  {Component~ReadyCallback} fn
1531    *         A function to call when ready is triggered.
1532    *
1533    * @param  {boolean} [sync=false]
1534    *         Execute the listener synchronously if `Component` is ready.
1535    *
1536    * @return {Component}
1537    *         Returns itself; method can be chained.
1538    */
1539
1540
1541   Component.prototype.ready = function ready(fn) {
1542     var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1543
1544     if (fn) {
1545       if (this.isReady_) {
1546         if (sync) {
1547           fn.call(this);
1548         } else {
1549           // Call the function asynchronously by default for consistency
1550           this.setTimeout(fn, 1);
1551         }
1552       } else {
1553         this.readyQueue_ = this.readyQueue_ || [];
1554         this.readyQueue_.push(fn);
1555       }
1556     }
1557     return this;
1558   };
1559
1560   /**
1561    * Trigger all the ready listeners for this `Component`.
1562    *
1563    * @fires Component#ready
1564    */
1565
1566
1567   Component.prototype.triggerReady = function triggerReady() {
1568     this.isReady_ = true;
1569
1570     // Ensure ready is triggerd asynchronously
1571     this.setTimeout(function () {
1572       var readyQueue = this.readyQueue_;
1573
1574       // Reset Ready Queue
1575       this.readyQueue_ = [];
1576
1577       if (readyQueue && readyQueue.length > 0) {
1578         readyQueue.forEach(function (fn) {
1579           fn.call(this);
1580         }, this);
1581       }
1582
1583       // Allow for using event listeners also
1584       /**
1585        * Triggered when a `Component` is ready.
1586        *
1587        * @event Component#ready
1588        * @type {EventTarget~Event}
1589        */
1590       this.trigger('ready');
1591     }, 1);
1592   };
1593
1594   /**
1595    * Find a single DOM element matching a `selector`. This can be within the `Component`s
1596    * `contentEl()` or another custom context.
1597    *
1598    * @param {string} selector
1599    *        A valid CSS selector, which will be passed to `querySelector`.
1600    *
1601    * @param {Element|string} [context=this.contentEl()]
1602    *        A DOM element within which to query. Can also be a selector string in
1603    *        which case the first matching element will get used as context. If
1604    *        missing `this.contentEl()` gets used. If  `this.contentEl()` returns
1605    *        nothing it falls back to `document`.
1606    *
1607    * @return {Element|null}
1608    *         the dom element that was found, or null
1609    *
1610    * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1611    */
1612
1613
1614   Component.prototype.$ = function $(selector, context) {
1615     return Dom.$(selector, context || this.contentEl());
1616   };
1617
1618   /**
1619    * Finds all DOM element matching a `selector`. This can be within the `Component`s
1620    * `contentEl()` or another custom context.
1621    *
1622    * @param {string} selector
1623    *        A valid CSS selector, which will be passed to `querySelectorAll`.
1624    *
1625    * @param {Element|string} [context=this.contentEl()]
1626    *        A DOM element within which to query. Can also be a selector string in
1627    *        which case the first matching element will get used as context. If
1628    *        missing `this.contentEl()` gets used. If  `this.contentEl()` returns
1629    *        nothing it falls back to `document`.
1630    *
1631    * @return {NodeList}
1632    *         a list of dom elements that were found
1633    *
1634    * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1635    */
1636
1637
1638   Component.prototype.$$ = function $$(selector, context) {
1639     return Dom.$$(selector, context || this.contentEl());
1640   };
1641
1642   /**
1643    * Check if a component's element has a CSS class name.
1644    *
1645    * @param {string} classToCheck
1646    *        CSS class name to check.
1647    *
1648    * @return {boolean}
1649    *         - True if the `Component` has the class.
1650    *         - False if the `Component` does not have the class`
1651    */
1652
1653
1654   Component.prototype.hasClass = function hasClass(classToCheck) {
1655     return Dom.hasElClass(this.el_, classToCheck);
1656   };
1657
1658   /**
1659    * Add a CSS class name to the `Component`s element.
1660    *
1661    * @param {string} classToAdd
1662    *        CSS class name to add
1663    *
1664    * @return {Component}
1665    *         Returns itself; method can be chained.
1666    */
1667
1668
1669   Component.prototype.addClass = function addClass(classToAdd) {
1670     Dom.addElClass(this.el_, classToAdd);
1671     return this;
1672   };
1673
1674   /**
1675    * Remove a CSS class name from the `Component`s element.
1676    *
1677    * @param {string} classToRemove
1678    *        CSS class name to remove
1679    *
1680    * @return {Component}
1681    *         Returns itself; method can be chained.
1682    */
1683
1684
1685   Component.prototype.removeClass = function removeClass(classToRemove) {
1686     Dom.removeElClass(this.el_, classToRemove);
1687     return this;
1688   };
1689
1690   /**
1691    * Add or remove a CSS class name from the component's element.
1692    * - `classToToggle` gets added when {@link Component#hasClass} would return false.
1693    * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
1694    *
1695    * @param  {string} classToToggle
1696    *         The class to add or remove based on (@link Component#hasClass}
1697    *
1698    * @param  {boolean|Dom~predicate} [predicate]
1699    *         An {@link Dom~predicate} function or a boolean
1700    *
1701    * @return {Component}
1702    *         Returns itself; method can be chained.
1703    */
1704
1705
1706   Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
1707     Dom.toggleElClass(this.el_, classToToggle, predicate);
1708     return this;
1709   };
1710
1711   /**
1712    * Show the `Component`s element if it is hidden by removing the
1713    * 'vjs-hidden' class name from it.
1714    *
1715    * @return {Component}
1716    *         Returns itself; method can be chained.
1717    */
1718
1719
1720   Component.prototype.show = function show() {
1721     this.removeClass('vjs-hidden');
1722     return this;
1723   };
1724
1725   /**
1726    * Hide the `Component`s element if it is currently showing by adding the
1727    * 'vjs-hidden` class name to it.
1728    *
1729    * @return {Component}
1730    *         Returns itself; method can be chained.
1731    */
1732
1733
1734   Component.prototype.hide = function hide() {
1735     this.addClass('vjs-hidden');
1736     return this;
1737   };
1738
1739   /**
1740    * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
1741    * class name to it. Used during fadeIn/fadeOut.
1742    *
1743    * @return {Component}
1744    *         Returns itself; method can be chained.
1745    *
1746    * @private
1747    */
1748
1749
1750   Component.prototype.lockShowing = function lockShowing() {
1751     this.addClass('vjs-lock-showing');
1752     return this;
1753   };
1754
1755   /**
1756    * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
1757    * class name from it. Used during fadeIn/fadeOut.
1758    *
1759    * @return {Component}
1760    *         Returns itself; method can be chained.
1761    *
1762    * @private
1763    */
1764
1765
1766   Component.prototype.unlockShowing = function unlockShowing() {
1767     this.removeClass('vjs-lock-showing');
1768     return this;
1769   };
1770
1771   /**
1772    * Get the value of an attribute on the `Component`s element.
1773    *
1774    * @param {string} attribute
1775    *        Name of the attribute to get the value from.
1776    *
1777    * @return {string|null}
1778    *         - The value of the attribute that was asked for.
1779    *         - Can be an empty string on some browsers if the attribute does not exist
1780    *           or has no value
1781    *         - Most browsers will return null if the attibute does not exist or has
1782    *           no value.
1783    *
1784    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
1785    */
1786
1787
1788   Component.prototype.getAttribute = function getAttribute(attribute) {
1789     return Dom.getAttribute(this.el_, attribute);
1790   };
1791
1792   /**
1793    * Set the value of an attribute on the `Component`'s element
1794    *
1795    * @param {string} attribute
1796    *        Name of the attribute to set.
1797    *
1798    * @param {string} value
1799    *        Value to set the attribute to.
1800    *
1801    * @return {Component}
1802    *         Returns itself; method can be chained.
1803    *
1804    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
1805    */
1806
1807
1808   Component.prototype.setAttribute = function setAttribute(attribute, value) {
1809     Dom.setAttribute(this.el_, attribute, value);
1810     return this;
1811   };
1812
1813   /**
1814    * Remove an attribute from the `Component`s element.
1815    *
1816    * @param {string} attribute
1817    *        Name of the attribute to remove.
1818    *
1819    * @return {Component}
1820    *         Returns itself; method can be chained.
1821    *
1822    * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
1823    */
1824
1825
1826   Component.prototype.removeAttribute = function removeAttribute(attribute) {
1827     Dom.removeAttribute(this.el_, attribute);
1828     return this;
1829   };
1830
1831   /**
1832    * Get or set the width of the component based upon the CSS styles.
1833    * See {@link Component#dimension} for more detailed information.
1834    *
1835    * @param {number|string} [num]
1836    *        The width that you want to set postfixed with '%', 'px' or nothing.
1837    *
1838    * @param {boolean} [skipListeners]
1839    *        Skip the resize event trigger
1840    *
1841    * @return {Component|number|string}
1842    *         - The width when getting, zero if there is no width. Can be a string
1843    *           postpixed with '%' or 'px'.
1844    *         - Returns itself when setting; method can be chained.
1845    */
1846
1847
1848   Component.prototype.width = function width(num, skipListeners) {
1849     return this.dimension('width', num, skipListeners);
1850   };
1851
1852   /**
1853    * Get or set the height of the component based upon the CSS styles.
1854    * See {@link Component#dimension} for more detailed information.
1855    *
1856    * @param {number|string} [num]
1857    *        The height that you want to set postfixed with '%', 'px' or nothing.
1858    *
1859    * @param {boolean} [skipListeners]
1860    *        Skip the resize event trigger
1861    *
1862    * @return {Component|number|string}
1863    *         - The width when getting, zero if there is no width. Can be a string
1864    *           postpixed with '%' or 'px'.
1865    *         - Returns itself when setting; method can be chained.
1866    */
1867
1868
1869   Component.prototype.height = function height(num, skipListeners) {
1870     return this.dimension('height', num, skipListeners);
1871   };
1872
1873   /**
1874    * Set both the width and height of the `Component` element at the same time.
1875    *
1876    * @param  {number|string} width
1877    *         Width to set the `Component`s element to.
1878    *
1879    * @param  {number|string} height
1880    *         Height to set the `Component`s element to.
1881    *
1882    * @return {Component}
1883    *         Returns itself; method can be chained.
1884    */
1885
1886
1887   Component.prototype.dimensions = function dimensions(width, height) {
1888     // Skip resize listeners on width for optimization
1889     return this.width(width, true).height(height);
1890   };
1891
1892   /**
1893    * Get or set width or height of the `Component` element. This is the shared code
1894    * for the {@link Component#width} and {@link Component#height}.
1895    *
1896    * Things to know:
1897    * - If the width or height in an number this will return the number postfixed with 'px'.
1898    * - If the width/height is a percent this will return the percent postfixed with '%'
1899    * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
1900    *   defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
1901    *   See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
1902    *   for more information
1903    * - If you want the computed style of the component, use {@link Component#currentWidth}
1904    *   and {@link {Component#currentHeight}
1905    *
1906    * @fires Component#resize
1907    *
1908    * @param {string} widthOrHeight
1909    8        'width' or 'height'
1910    *
1911    * @param  {number|string} [num]
1912    8         New dimension
1913    *
1914    * @param  {boolean} [skipListeners]
1915    *         Skip resize event trigger
1916    *
1917    * @return {Component}
1918    *         - the dimension when getting or 0 if unset
1919    *         - Returns itself when setting; method can be chained.
1920    */
1921
1922
1923   Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
1924     if (num !== undefined) {
1925       // Set to zero if null or literally NaN (NaN !== NaN)
1926       if (num === null || num !== num) {
1927         num = 0;
1928       }
1929
1930       // Check if using css width/height (% or px) and adjust
1931       if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
1932         this.el_.style[widthOrHeight] = num;
1933       } else if (num === 'auto') {
1934         this.el_.style[widthOrHeight] = '';
1935       } else {
1936         this.el_.style[widthOrHeight] = num + 'px';
1937       }
1938
1939       // skipListeners allows us to avoid triggering the resize event when setting both width and height
1940       if (!skipListeners) {
1941         /**
1942          * Triggered when a component is resized.
1943          *
1944          * @event Component#resize
1945          * @type {EventTarget~Event}
1946          */
1947         this.trigger('resize');
1948       }
1949
1950       // Return component
1951       return this;
1952     }
1953
1954     // Not setting a value, so getting it
1955     // Make sure element exists
1956     if (!this.el_) {
1957       return 0;
1958     }
1959
1960     // Get dimension value from style
1961     var val = this.el_.style[widthOrHeight];
1962     var pxIndex = val.indexOf('px');
1963
1964     if (pxIndex !== -1) {
1965       // Return the pixel value with no 'px'
1966       return parseInt(val.slice(0, pxIndex), 10);
1967     }
1968
1969     // No px so using % or no style was set, so falling back to offsetWidth/height
1970     // If component has display:none, offset will return 0
1971     // TODO: handle display:none and no dimension style using px
1972     return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
1973   };
1974
1975   /**
1976    * Get the width or the height of the `Component` elements computed style. Uses
1977    * `window.getComputedStyle`.
1978    *
1979    * @param {string} widthOrHeight
1980    *        A string containing 'width' or 'height'. Whichever one you want to get.
1981    *
1982    * @return {number}
1983    *         The dimension that gets asked for or 0 if nothing was set
1984    *         for that dimension.
1985    */
1986
1987
1988   Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
1989     var computedWidthOrHeight = 0;
1990
1991     if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
1992       throw new Error('currentDimension only accepts width or height value');
1993     }
1994
1995     if (typeof _window2['default'].getComputedStyle === 'function') {
1996       var computedStyle = _window2['default'].getComputedStyle(this.el_);
1997
1998       computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
1999     }
2000
2001     // remove 'px' from variable and parse as integer
2002     computedWidthOrHeight = parseFloat(computedWidthOrHeight);
2003
2004     // if the computed value is still 0, it's possible that the browser is lying
2005     // and we want to check the offset values.
2006     // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
2007     if (computedWidthOrHeight === 0) {
2008       var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
2009
2010       computedWidthOrHeight = this.el_[rule];
2011     }
2012
2013     return computedWidthOrHeight;
2014   };
2015
2016   /**
2017    * An object that contains width and height values of the `Component`s
2018    * computed style. Uses `window.getComputedStyle`.
2019    *
2020    * @typedef {Object} Component~DimensionObject
2021    *
2022    * @property {number} width
2023    *           The width of the `Component`s computed style.
2024    *
2025    * @property {number} height
2026    *           The height of the `Component`s computed style.
2027    */
2028
2029   /**
2030    * Get an object that contains width and height values of the `Component`s
2031    * computed style.
2032    *
2033    * @return {Component~DimensionObject}
2034    *         The dimensions of the components element
2035    */
2036
2037
2038   Component.prototype.currentDimensions = function currentDimensions() {
2039     return {
2040       width: this.currentDimension('width'),
2041       height: this.currentDimension('height')
2042     };
2043   };
2044
2045   /**
2046    * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
2047    *
2048    * @return {number} width
2049    *           The width of the `Component`s computed style.
2050    */
2051
2052
2053   Component.prototype.currentWidth = function currentWidth() {
2054     return this.currentDimension('width');
2055   };
2056
2057   /**
2058    * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
2059    *
2060    * @return {number} height
2061    *           The height of the `Component`s computed style.
2062    */
2063
2064
2065   Component.prototype.currentHeight = function currentHeight() {
2066     return this.currentDimension('height');
2067   };
2068
2069   /**
2070    * Set the focus to this component
2071    */
2072
2073
2074   Component.prototype.focus = function focus() {
2075     this.el_.focus();
2076   };
2077
2078   /**
2079    * Remove the focus from this component
2080    */
2081
2082
2083   Component.prototype.blur = function blur() {
2084     this.el_.blur();
2085   };
2086
2087   /**
2088    * Emit a 'tap' events when touch event support gets detected. This gets used to
2089    * support toggling the controls through a tap on the video. They get enabled
2090    * because every sub-component would have extra overhead otherwise.
2091    *
2092    * @private
2093    * @fires Component#tap
2094    * @listens Component#touchstart
2095    * @listens Component#touchmove
2096    * @listens Component#touchleave
2097    * @listens Component#touchcancel
2098    * @listens Component#touchend
2099     */
2100
2101
2102   Component.prototype.emitTapEvents = function emitTapEvents() {
2103     // Track the start time so we can determine how long the touch lasted
2104     var touchStart = 0;
2105     var firstTouch = null;
2106
2107     // Maximum movement allowed during a touch event to still be considered a tap
2108     // Other popular libs use anywhere from 2 (hammer.js) to 15,
2109     // so 10 seems like a nice, round number.
2110     var tapMovementThreshold = 10;
2111
2112     // The maximum length a touch can be while still being considered a tap
2113     var touchTimeThreshold = 200;
2114
2115     var couldBeTap = void 0;
2116
2117     this.on('touchstart', function (event) {
2118       // If more than one finger, don't consider treating this as a click
2119       if (event.touches.length === 1) {
2120         // Copy pageX/pageY from the object
2121         firstTouch = {
2122           pageX: event.touches[0].pageX,
2123           pageY: event.touches[0].pageY
2124         };
2125         // Record start time so we can detect a tap vs. "touch and hold"
2126         touchStart = new Date().getTime();
2127         // Reset couldBeTap tracking
2128         couldBeTap = true;
2129       }
2130     });
2131
2132     this.on('touchmove', function (event) {
2133       // If more than one finger, don't consider treating this as a click
2134       if (event.touches.length > 1) {
2135         couldBeTap = false;
2136       } else if (firstTouch) {
2137         // Some devices will throw touchmoves for all but the slightest of taps.
2138         // So, if we moved only a small distance, this could still be a tap
2139         var xdiff = event.touches[0].pageX - firstTouch.pageX;
2140         var ydiff = event.touches[0].pageY - firstTouch.pageY;
2141         var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
2142
2143         if (touchDistance > tapMovementThreshold) {
2144           couldBeTap = false;
2145         }
2146       }
2147     });
2148
2149     var noTap = function noTap() {
2150       couldBeTap = false;
2151     };
2152
2153     // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
2154     this.on('touchleave', noTap);
2155     this.on('touchcancel', noTap);
2156
2157     // When the touch ends, measure how long it took and trigger the appropriate
2158     // event
2159     this.on('touchend', function (event) {
2160       firstTouch = null;
2161       // Proceed only if the touchmove/leave/cancel event didn't happen
2162       if (couldBeTap === true) {
2163         // Measure how long the touch lasted
2164         var touchTime = new Date().getTime() - touchStart;
2165
2166         // Make sure the touch was less than the threshold to be considered a tap
2167         if (touchTime < touchTimeThreshold) {
2168           // Don't let browser turn this into a click
2169           event.preventDefault();
2170           /**
2171            * Triggered when a `Component` is tapped.
2172            *
2173            * @event Component#tap
2174            * @type {EventTarget~Event}
2175            */
2176           this.trigger('tap');
2177           // It may be good to copy the touchend event object and change the
2178           // type to tap, if the other event properties aren't exact after
2179           // Events.fixEvent runs (e.g. event.target)
2180         }
2181       }
2182     });
2183   };
2184
2185   /**
2186    * This function reports user activity whenever touch events happen. This can get
2187    * turned off by any sub-components that wants touch events to act another way.
2188    *
2189    * Report user touch activity when touch events occur. User activity gets used to
2190    * determine when controls should show/hide. It is simple when it comes to mouse
2191    * events, because any mouse event should show the controls. So we capture mouse
2192    * events that bubble up to the player and report activity when that happens.
2193    * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
2194    * controls. So touch events can't help us at the player level either.
2195    *
2196    * User activity gets checked asynchronously. So what could happen is a tap event
2197    * on the video turns the controls off. Then the `touchend` event bubbles up to
2198    * the player. Which, if it reported user activity, would turn the controls right
2199    * back on. We also don't want to completely block touch events from bubbling up.
2200    * Furthermore a `touchmove` event and anything other than a tap, should not turn
2201    * controls back on.
2202    *
2203    * @listens Component#touchstart
2204    * @listens Component#touchmove
2205    * @listens Component#touchend
2206    * @listens Component#touchcancel
2207    */
2208
2209
2210   Component.prototype.enableTouchActivity = function enableTouchActivity() {
2211     // Don't continue if the root player doesn't support reporting user activity
2212     if (!this.player() || !this.player().reportUserActivity) {
2213       return;
2214     }
2215
2216     // listener for reporting that the user is active
2217     var report = Fn.bind(this.player(), this.player().reportUserActivity);
2218
2219     var touchHolding = void 0;
2220
2221     this.on('touchstart', function () {
2222       report();
2223       // For as long as the they are touching the device or have their mouse down,
2224       // we consider them active even if they're not moving their finger or mouse.
2225       // So we want to continue to update that they are active
2226       this.clearInterval(touchHolding);
2227       // report at the same interval as activityCheck
2228       touchHolding = this.setInterval(report, 250);
2229     });
2230
2231     var touchEnd = function touchEnd(event) {
2232       report();
2233       // stop the interval that maintains activity if the touch is holding
2234       this.clearInterval(touchHolding);
2235     };
2236
2237     this.on('touchmove', report);
2238     this.on('touchend', touchEnd);
2239     this.on('touchcancel', touchEnd);
2240   };
2241
2242   /**
2243    * A callback that has no parameters and is bound into `Component`s context.
2244    *
2245    * @callback Component~GenericCallback
2246    * @this Component
2247    */
2248
2249   /**
2250    * Creates a function that runs after an `x` millisecond timeout. This function is a
2251    * wrapper around `window.setTimeout`. There are a few reasons to use this one
2252    * instead though:
2253    * 1. It gets cleared via  {@link Component#clearTimeout} when
2254    *    {@link Component#dispose} gets called.
2255    * 2. The function callback will gets turned into a {@link Component~GenericCallback}
2256    *
2257    * > Note: You can use `window.clearTimeout` on the id returned by this function. This
2258    *         will cause its dispose listener not to get cleaned up! Please use
2259    *         {@link Component#clearTimeout} or {@link Component#dispose}.
2260    *
2261    * @param {Component~GenericCallback} fn
2262    *        The function that will be run after `timeout`.
2263    *
2264    * @param {number} timeout
2265    *        Timeout in milliseconds to delay before executing the specified function.
2266    *
2267    * @return {number}
2268    *         Returns a timeout ID that gets used to identify the timeout. It can also
2269    *         get used in {@link Component#clearTimeout} to clear the timeout that
2270    *         was set.
2271    *
2272    * @listens Component#dispose
2273    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
2274    */
2275
2276
2277   Component.prototype.setTimeout = function setTimeout(fn, timeout) {
2278     fn = Fn.bind(this, fn);
2279
2280     var timeoutId = _window2['default'].setTimeout(fn, timeout);
2281     var disposeFn = function disposeFn() {
2282       this.clearTimeout(timeoutId);
2283     };
2284
2285     disposeFn.guid = 'vjs-timeout-' + timeoutId;
2286
2287     this.on('dispose', disposeFn);
2288
2289     return timeoutId;
2290   };
2291
2292   /**
2293    * Clears a timeout that gets created via `window.setTimeout` or
2294    * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
2295    * use this function instead of `window.clearTimout`. If you don't your dispose
2296    * listener will not get cleaned up until {@link Component#dispose}!
2297    *
2298    * @param {number} timeoutId
2299    *        The id of the timeout to clear. The return value of
2300    *        {@link Component#setTimeout} or `window.setTimeout`.
2301    *
2302    * @return {number}
2303    *         Returns the timeout id that was cleared.
2304    *
2305    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
2306    */
2307
2308
2309   Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
2310     _window2['default'].clearTimeout(timeoutId);
2311
2312     var disposeFn = function disposeFn() {};
2313
2314     disposeFn.guid = 'vjs-timeout-' + timeoutId;
2315
2316     this.off('dispose', disposeFn);
2317
2318     return timeoutId;
2319   };
2320
2321   /**
2322    * Creates a function that gets run every `x` milliseconds. This function is a wrapper
2323    * around `window.setInterval`. There are a few reasons to use this one instead though.
2324    * 1. It gets cleared via  {@link Component#clearInterval} when
2325    *    {@link Component#dispose} gets called.
2326    * 2. The function callback will be a {@link Component~GenericCallback}
2327    *
2328    * @param {Component~GenericCallback} fn
2329    *        The function to run every `x` seconds.
2330    *
2331    * @param {number} interval
2332    *        Execute the specified function every `x` milliseconds.
2333    *
2334    * @return {number}
2335    *         Returns an id that can be used to identify the interval. It can also be be used in
2336    *         {@link Component#clearInterval} to clear the interval.
2337    *
2338    * @listens Component#dispose
2339    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
2340    */
2341
2342
2343   Component.prototype.setInterval = function setInterval(fn, interval) {
2344     fn = Fn.bind(this, fn);
2345
2346     var intervalId = _window2['default'].setInterval(fn, interval);
2347
2348     var disposeFn = function disposeFn() {
2349       this.clearInterval(intervalId);
2350     };
2351
2352     disposeFn.guid = 'vjs-interval-' + intervalId;
2353
2354     this.on('dispose', disposeFn);
2355
2356     return intervalId;
2357   };
2358
2359   /**
2360    * Clears an interval that gets created via `window.setInterval` or
2361    * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
2362    * use this function instead of `window.clearInterval`. If you don't your dispose
2363    * listener will not get cleaned up until {@link Component#dispose}!
2364    *
2365    * @param {number} intervalId
2366    *        The id of the interval to clear. The return value of
2367    *        {@link Component#setInterval} or `window.setInterval`.
2368    *
2369    * @return {number}
2370    *         Returns the interval id that was cleared.
2371    *
2372    * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
2373    */
2374
2375
2376   Component.prototype.clearInterval = function clearInterval(intervalId) {
2377     _window2['default'].clearInterval(intervalId);
2378
2379     var disposeFn = function disposeFn() {};
2380
2381     disposeFn.guid = 'vjs-interval-' + intervalId;
2382
2383     this.off('dispose', disposeFn);
2384
2385     return intervalId;
2386   };
2387
2388   /**
2389    * Register a `Component` with `videojs` given the name and the component.
2390    *
2391    * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
2392    *         should be registered using {@link Tech.registerTech} or
2393    *         {@link videojs:videojs.registerTech}.
2394    *
2395    * > NOTE: This function can also be seen on videojs as
2396    *         {@link videojs:videojs.registerComponent}.
2397    *
2398    * @param {string} name
2399    *        The name of the `Component` to register.
2400    *
2401    * @param {Component} comp
2402    *        The `Component` class to register.
2403    *
2404    * @return {Component}
2405    *         The `Component` that was registered.
2406    */
2407
2408
2409   Component.registerComponent = function registerComponent(name, comp) {
2410     if (!name) {
2411       return;
2412     }
2413
2414     name = (0, _toTitleCase2['default'])(name);
2415
2416     if (!Component.components_) {
2417       Component.components_ = {};
2418     }
2419
2420     if (name === 'Player' && Component.components_[name]) {
2421       var Player = Component.components_[name];
2422
2423       // If we have players that were disposed, then their name will still be
2424       // in Players.players. So, we must loop through and verify that the value
2425       // for each item is not null. This allows registration of the Player component
2426       // after all players have been disposed or before any were created.
2427       if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) {
2428         return Player.players[playerName];
2429       }).every(Boolean)) {
2430         throw new Error('Can not register Player component after player has been created');
2431       }
2432     }
2433
2434     Component.components_[name] = comp;
2435
2436     return comp;
2437   };
2438
2439   /**
2440    * Get a `Component` based on the name it was registered with.
2441    *
2442    * @param {string} name
2443    *        The Name of the component to get.
2444    *
2445    * @return {Component}
2446    *         The `Component` that got registered under the given name.
2447    *
2448    * @deprecated In `videojs` 6 this will not return `Component`s that were not
2449    *             registered using {@link Component.registerComponent}. Currently we
2450    *             check the global `videojs` object for a `Component` name and
2451    *             return that if it exists.
2452    */
2453
2454
2455   Component.getComponent = function getComponent(name) {
2456     if (!name) {
2457       return;
2458     }
2459
2460     name = (0, _toTitleCase2['default'])(name);
2461
2462     if (Component.components_ && Component.components_[name]) {
2463       return Component.components_[name];
2464     }
2465
2466     if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
2467       _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
2468
2469       return _window2['default'].videojs[name];
2470     }
2471   };
2472
2473   /**
2474    * Sets up the constructor using the supplied init method or uses the init of the
2475    * parent object.
2476    *
2477    * @param {Object} [props={}]
2478    *        An object of properties.
2479    *
2480    * @return {Object}
2481    *         the extended object.
2482    *
2483    * @deprecated since version 5
2484    */
2485
2486
2487   Component.extend = function extend(props) {
2488     props = props || {};
2489
2490     _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead');
2491
2492     // Set up the constructor using the supplied init method
2493     // or using the init of the parent object
2494     // Make sure to check the unobfuscated version for external libs
2495     var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
2496     // In Resig's simple class inheritance (previously used) the constructor
2497     //  is a function that calls `this.init.apply(arguments)`
2498     // However that would prevent us from using `ParentObject.call(this);`
2499     //  in a Child constructor because the `this` in `this.init`
2500     //  would still refer to the Child and cause an infinite loop.
2501     // We would instead have to do
2502     //    `ParentObject.prototype.init.apply(this, arguments);`
2503     //  Bleh. We're not creating a _super() function, so it's good to keep
2504     //  the parent constructor reference simple.
2505     var subObj = function subObj() {
2506       init.apply(this, arguments);
2507     };
2508
2509     // Inherit from this object's prototype
2510     subObj.prototype = Object.create(this.prototype);
2511     // Reset the constructor property for subObj otherwise
2512     // instances of subObj would have the constructor of the parent Object
2513     subObj.prototype.constructor = subObj;
2514
2515     // Make the class extendable
2516     subObj.extend = Component.extend;
2517
2518     // Extend subObj's prototype with functions and other properties from props
2519     for (var name in props) {
2520       if (props.hasOwnProperty(name)) {
2521         subObj.prototype[name] = props[name];
2522       }
2523     }
2524
2525     return subObj;
2526   };
2527
2528   return Component;
2529 }();
2530
2531 Component.registerComponent('Component', Component);
2532 exports['default'] = Component;
2533
2534 },{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){
2535 'use strict';
2536
2537 exports.__esModule = true;
2538
2539 var _trackButton = _dereq_(36);
2540
2541 var _trackButton2 = _interopRequireDefault(_trackButton);
2542
2543 var _component = _dereq_(5);
2544
2545 var _component2 = _interopRequireDefault(_component);
2546
2547 var _audioTrackMenuItem = _dereq_(7);
2548
2549 var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
2550
2551 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2552
2553 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2554
2555 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; }
2556
2557 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; } /**
2558                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-button.js
2559                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2560
2561
2562 /**
2563  * The base class for buttons that toggle specific {@link AudioTrack} types.
2564  *
2565  * @extends TrackButton
2566  */
2567 var AudioTrackButton = function (_TrackButton) {
2568   _inherits(AudioTrackButton, _TrackButton);
2569
2570   /**
2571    * Creates an instance of this class.
2572    *
2573    * @param {Player} player
2574    *        The `Player` that this class should be attached to.
2575    *
2576    * @param {Object} [options={}]
2577    *        The key/value store of player options.
2578    */
2579   function AudioTrackButton(player) {
2580     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2581
2582     _classCallCheck(this, AudioTrackButton);
2583
2584     options.tracks = player.audioTracks && player.audioTracks();
2585
2586     var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
2587
2588     _this.el_.setAttribute('aria-label', 'Audio Menu');
2589     return _this;
2590   }
2591
2592   /**
2593    * Builds the default DOM `className`.
2594    *
2595    * @return {string}
2596    *         The DOM `className` for this object.
2597    */
2598
2599
2600   AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
2601     return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
2602   };
2603
2604   /**
2605    * Create a menu item for each audio track
2606    *
2607    * @param {AudioTrackMenuItem[]} [items=[]]
2608    *        An array of existing menu items to use.
2609    *
2610    * @return {AudioTrackMenuItem[]}
2611    *         An array of menu items
2612    */
2613
2614
2615   AudioTrackButton.prototype.createItems = function createItems() {
2616     var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
2617
2618     // if there's only one audio track, there no point in showing it
2619     this.hideThreshold_ = 1;
2620
2621     var tracks = this.player_.audioTracks && this.player_.audioTracks();
2622
2623     if (!tracks) {
2624       return items;
2625     }
2626
2627     for (var i = 0; i < tracks.length; i++) {
2628       var track = tracks[i];
2629
2630       items.push(new _audioTrackMenuItem2['default'](this.player_, {
2631         track: track,
2632         // MenuItem is selectable
2633         selectable: true
2634       }));
2635     }
2636
2637     return items;
2638   };
2639
2640   return AudioTrackButton;
2641 }(_trackButton2['default']);
2642
2643 /**
2644  * The text that should display over the `AudioTrackButton`s controls. Added for localization.
2645  *
2646  * @type {string}
2647  * @private
2648  */
2649
2650
2651 AudioTrackButton.prototype.controlText_ = 'Audio Track';
2652 _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
2653 exports['default'] = AudioTrackButton;
2654
2655 },{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){
2656 'use strict';
2657
2658 exports.__esModule = true;
2659
2660 var _menuItem = _dereq_(48);
2661
2662 var _menuItem2 = _interopRequireDefault(_menuItem);
2663
2664 var _component = _dereq_(5);
2665
2666 var _component2 = _interopRequireDefault(_component);
2667
2668 var _fn = _dereq_(83);
2669
2670 var Fn = _interopRequireWildcard(_fn);
2671
2672 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; } }
2673
2674 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2675
2676 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2677
2678 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; }
2679
2680 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; } /**
2681                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-menu-item.js
2682                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2683
2684
2685 /**
2686  * An {@link AudioTrack} {@link MenuItem}
2687  *
2688  * @extends MenuItem
2689  */
2690 var AudioTrackMenuItem = function (_MenuItem) {
2691   _inherits(AudioTrackMenuItem, _MenuItem);
2692
2693   /**
2694    * Creates an instance of this class.
2695    *
2696    * @param {Player} player
2697    *        The `Player` that this class should be attached to.
2698    *
2699    * @param {Object} [options]
2700    *        The key/value store of player options.
2701    */
2702   function AudioTrackMenuItem(player, options) {
2703     _classCallCheck(this, AudioTrackMenuItem);
2704
2705     var track = options.track;
2706     var tracks = player.audioTracks();
2707
2708     // Modify options for parent MenuItem class's init.
2709     options.label = track.label || track.language || 'Unknown';
2710     options.selected = track.enabled;
2711
2712     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
2713
2714     _this.track = track;
2715
2716     if (tracks) {
2717       var changeHandler = Fn.bind(_this, _this.handleTracksChange);
2718
2719       tracks.addEventListener('change', changeHandler);
2720       _this.on('dispose', function () {
2721         tracks.removeEventListener('change', changeHandler);
2722       });
2723     }
2724     return _this;
2725   }
2726
2727   /**
2728    * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
2729    * for more detailed information on what a click can be.
2730    *
2731    * @param {EventTarget~Event} [event]
2732    *        The `keydown`, `tap`, or `click` event that caused this function to be
2733    *        called.
2734    *
2735    * @listens tap
2736    * @listens click
2737    */
2738
2739
2740   AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
2741     var tracks = this.player_.audioTracks();
2742
2743     _MenuItem.prototype.handleClick.call(this, event);
2744
2745     if (!tracks) {
2746       return;
2747     }
2748
2749     for (var i = 0; i < tracks.length; i++) {
2750       var track = tracks[i];
2751
2752       track.enabled = track === this.track;
2753     }
2754   };
2755
2756   /**
2757    * Handle any {@link AudioTrack} change.
2758    *
2759    * @param {EventTarget~Event} [event]
2760    *        The {@link AudioTrackList#change} event that caused this to run.
2761    *
2762    * @listens AudioTrackList#change
2763    */
2764
2765
2766   AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
2767     this.selected(this.track.enabled);
2768   };
2769
2770   return AudioTrackMenuItem;
2771 }(_menuItem2['default']);
2772
2773 _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
2774 exports['default'] = AudioTrackMenuItem;
2775
2776 },{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){
2777 'use strict';
2778
2779 exports.__esModule = true;
2780
2781 var _component = _dereq_(5);
2782
2783 var _component2 = _interopRequireDefault(_component);
2784
2785 _dereq_(12);
2786
2787 _dereq_(32);
2788
2789 _dereq_(33);
2790
2791 _dereq_(35);
2792
2793 _dereq_(34);
2794
2795 _dereq_(10);
2796
2797 _dereq_(18);
2798
2799 _dereq_(9);
2800
2801 _dereq_(38);
2802
2803 _dereq_(40);
2804
2805 _dereq_(11);
2806
2807 _dereq_(25);
2808
2809 _dereq_(27);
2810
2811 _dereq_(29);
2812
2813 _dereq_(24);
2814
2815 _dereq_(6);
2816
2817 _dereq_(13);
2818
2819 _dereq_(21);
2820
2821 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2822
2823 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2824
2825 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; }
2826
2827 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; } /**
2828                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file control-bar.js
2829                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2830
2831
2832 // Required children
2833
2834
2835 /**
2836  * Container of main controls.
2837  *
2838  * @extends Component
2839  */
2840 var ControlBar = function (_Component) {
2841   _inherits(ControlBar, _Component);
2842
2843   function ControlBar() {
2844     _classCallCheck(this, ControlBar);
2845
2846     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
2847   }
2848
2849   /**
2850    * Create the `Component`'s DOM element
2851    *
2852    * @return {Element}
2853    *         The element that was created.
2854    */
2855   ControlBar.prototype.createEl = function createEl() {
2856     return _Component.prototype.createEl.call(this, 'div', {
2857       className: 'vjs-control-bar',
2858       dir: 'ltr'
2859     }, {
2860       // The control bar is a group, so it can contain menuitems
2861       role: 'group'
2862     });
2863   };
2864
2865   return ControlBar;
2866 }(_component2['default']);
2867
2868 /**
2869  * Default options for `ControlBar`
2870  *
2871  * @type {Object}
2872  * @private
2873  */
2874
2875
2876 ControlBar.prototype.options_ = {
2877   children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
2878 };
2879
2880 _component2['default'].registerComponent('ControlBar', ControlBar);
2881 exports['default'] = ControlBar;
2882
2883 },{"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){
2884 'use strict';
2885
2886 exports.__esModule = true;
2887
2888 var _button = _dereq_(2);
2889
2890 var _button2 = _interopRequireDefault(_button);
2891
2892 var _component = _dereq_(5);
2893
2894 var _component2 = _interopRequireDefault(_component);
2895
2896 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2897
2898 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2899
2900 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; }
2901
2902 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; } /**
2903                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file fullscreen-toggle.js
2904                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
2905
2906
2907 /**
2908  * Toggle fullscreen video
2909  *
2910  * @extends Button
2911  */
2912 var FullscreenToggle = function (_Button) {
2913   _inherits(FullscreenToggle, _Button);
2914
2915   /**
2916    * Creates an instance of this class.
2917    *
2918    * @param {Player} player
2919    *        The `Player` that this class should be attached to.
2920    *
2921    * @param {Object} [options]
2922    *        The key/value store of player options.
2923    */
2924   function FullscreenToggle(player, options) {
2925     _classCallCheck(this, FullscreenToggle);
2926
2927     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
2928
2929     _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
2930     return _this;
2931   }
2932
2933   /**
2934    * Builds the default DOM `className`.
2935    *
2936    * @return {string}
2937    *         The DOM `className` for this object.
2938    */
2939
2940
2941   FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
2942     return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
2943   };
2944
2945   /**
2946    * Handles fullscreenchange on the player and change control text accordingly.
2947    *
2948    * @param {EventTarget~Event} [event]
2949    *        The {@link Player#fullscreenchange} event that caused this function to be
2950    *        called.
2951    *
2952    * @listens Player#fullscreenchange
2953    */
2954
2955
2956   FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
2957     if (this.player_.isFullscreen()) {
2958       this.controlText('Non-Fullscreen');
2959     } else {
2960       this.controlText('Fullscreen');
2961     }
2962   };
2963
2964   /**
2965    * This gets called when an `FullscreenToggle` is "clicked". See
2966    * {@link ClickableComponent} for more detailed information on what a click can be.
2967    *
2968    * @param {EventTarget~Event} [event]
2969    *        The `keydown`, `tap`, or `click` event that caused this function to be
2970    *        called.
2971    *
2972    * @listens tap
2973    * @listens click
2974    */
2975
2976
2977   FullscreenToggle.prototype.handleClick = function handleClick(event) {
2978     if (!this.player_.isFullscreen()) {
2979       this.player_.requestFullscreen();
2980     } else {
2981       this.player_.exitFullscreen();
2982     }
2983   };
2984
2985   return FullscreenToggle;
2986 }(_button2['default']);
2987
2988 /**
2989  * The text that should display over the `FullscreenToggle`s controls. Added for localization.
2990  *
2991  * @type {string}
2992  * @private
2993  */
2994
2995
2996 FullscreenToggle.prototype.controlText_ = 'Fullscreen';
2997
2998 _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
2999 exports['default'] = FullscreenToggle;
3000
3001 },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
3002 'use strict';
3003
3004 exports.__esModule = true;
3005
3006 var _component = _dereq_(5);
3007
3008 var _component2 = _interopRequireDefault(_component);
3009
3010 var _dom = _dereq_(81);
3011
3012 var Dom = _interopRequireWildcard(_dom);
3013
3014 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; } }
3015
3016 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3017
3018 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3019
3020 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; }
3021
3022 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; } /**
3023                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file live-display.js
3024                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3025
3026
3027 // TODO - Future make it click to snap to live
3028
3029 /**
3030  * Displays the live indicator when duration is Infinity.
3031  *
3032  * @extends Component
3033  */
3034 var LiveDisplay = function (_Component) {
3035   _inherits(LiveDisplay, _Component);
3036
3037   /**
3038    * Creates an instance of this class.
3039    *
3040    * @param {Player} player
3041    *        The `Player` that this class should be attached to.
3042    *
3043    * @param {Object} [options]
3044    *        The key/value store of player options.
3045    */
3046   function LiveDisplay(player, options) {
3047     _classCallCheck(this, LiveDisplay);
3048
3049     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3050
3051     _this.updateShowing();
3052     _this.on(_this.player(), 'durationchange', _this.updateShowing);
3053     return _this;
3054   }
3055
3056   /**
3057    * Create the `Component`'s DOM element
3058    *
3059    * @return {Element}
3060    *         The element that was created.
3061    */
3062
3063
3064   LiveDisplay.prototype.createEl = function createEl() {
3065     var el = _Component.prototype.createEl.call(this, 'div', {
3066       className: 'vjs-live-control vjs-control'
3067     });
3068
3069     this.contentEl_ = Dom.createEl('div', {
3070       className: 'vjs-live-display',
3071       innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
3072     }, {
3073       'aria-live': 'off'
3074     });
3075
3076     el.appendChild(this.contentEl_);
3077     return el;
3078   };
3079
3080   /**
3081    * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
3082    * it accordingly
3083    *
3084    * @param {EventTarget~Event} [event]
3085    *        The {@link Player#durationchange} event that caused this function to run.
3086    *
3087    * @listens Player#durationchange
3088    */
3089
3090
3091   LiveDisplay.prototype.updateShowing = function updateShowing(event) {
3092     if (this.player().duration() === Infinity) {
3093       this.show();
3094     } else {
3095       this.hide();
3096     }
3097   };
3098
3099   return LiveDisplay;
3100 }(_component2['default']);
3101
3102 _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
3103 exports['default'] = LiveDisplay;
3104
3105 },{"5":5,"81":81}],11:[function(_dereq_,module,exports){
3106 'use strict';
3107
3108 exports.__esModule = true;
3109
3110 var _button = _dereq_(2);
3111
3112 var _button2 = _interopRequireDefault(_button);
3113
3114 var _component = _dereq_(5);
3115
3116 var _component2 = _interopRequireDefault(_component);
3117
3118 var _dom = _dereq_(81);
3119
3120 var Dom = _interopRequireWildcard(_dom);
3121
3122 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; } }
3123
3124 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3125
3126 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3127
3128 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; }
3129
3130 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; } /**
3131                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file mute-toggle.js
3132                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3133
3134
3135 /**
3136  * A button component for muting the audio.
3137  *
3138  * @extends Button
3139  */
3140 var MuteToggle = function (_Button) {
3141   _inherits(MuteToggle, _Button);
3142
3143   /**
3144    * Creates an instance of this class.
3145    *
3146    * @param {Player} player
3147    *        The `Player` that this class should be attached to.
3148    *
3149    * @param {Object} [options]
3150    *        The key/value store of player options.
3151    */
3152   function MuteToggle(player, options) {
3153     _classCallCheck(this, MuteToggle);
3154
3155     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3156
3157     _this.on(player, 'volumechange', _this.update);
3158
3159     // hide mute toggle if the current tech doesn't support volume control
3160     if (player.tech_ && player.tech_.featuresVolumeControl === false) {
3161       _this.addClass('vjs-hidden');
3162     }
3163
3164     _this.on(player, 'loadstart', function () {
3165       // We need to update the button to account for a default muted state.
3166       this.update();
3167
3168       if (player.tech_.featuresVolumeControl === false) {
3169         this.addClass('vjs-hidden');
3170       } else {
3171         this.removeClass('vjs-hidden');
3172       }
3173     });
3174     return _this;
3175   }
3176
3177   /**
3178    * Builds the default DOM `className`.
3179    *
3180    * @return {string}
3181    *         The DOM `className` for this object.
3182    */
3183
3184
3185   MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
3186     return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
3187   };
3188
3189   /**
3190    * This gets called when an `MuteToggle` is "clicked". See
3191    * {@link ClickableComponent} for more detailed information on what a click can be.
3192    *
3193    * @param {EventTarget~Event} [event]
3194    *        The `keydown`, `tap`, or `click` event that caused this function to be
3195    *        called.
3196    *
3197    * @listens tap
3198    * @listens click
3199    */
3200
3201
3202   MuteToggle.prototype.handleClick = function handleClick(event) {
3203     this.player_.muted(this.player_.muted() ? false : true);
3204   };
3205
3206   /**
3207    * Update the state of volume.
3208    *
3209    * @param {EventTarget~Event} [event]
3210    *        The {@link Player#loadstart} event if this function was called through an
3211    *        event.
3212    *
3213    * @listens Player#loadstart
3214    */
3215
3216
3217   MuteToggle.prototype.update = function update(event) {
3218     var vol = this.player_.volume();
3219     var level = 3;
3220
3221     if (vol === 0 || this.player_.muted()) {
3222       level = 0;
3223     } else if (vol < 0.33) {
3224       level = 1;
3225     } else if (vol < 0.67) {
3226       level = 2;
3227     }
3228
3229     // Don't rewrite the button text if the actual text doesn't change.
3230     // This causes unnecessary and confusing information for screen reader users.
3231     // This check is needed because this function gets called every time the volume level is changed.
3232     var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
3233
3234     if (this.controlText() !== toMute) {
3235       this.controlText(toMute);
3236     }
3237
3238     // TODO improve muted icon classes
3239     for (var i = 0; i < 4; i++) {
3240       Dom.removeElClass(this.el_, 'vjs-vol-' + i);
3241     }
3242     Dom.addElClass(this.el_, 'vjs-vol-' + level);
3243   };
3244
3245   return MuteToggle;
3246 }(_button2['default']);
3247
3248 /**
3249  * The text that should display over the `MuteToggle`s controls. Added for localization.
3250  *
3251  * @type {string}
3252  * @private
3253  */
3254
3255
3256 MuteToggle.prototype.controlText_ = 'Mute';
3257
3258 _component2['default'].registerComponent('MuteToggle', MuteToggle);
3259 exports['default'] = MuteToggle;
3260
3261 },{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){
3262 'use strict';
3263
3264 exports.__esModule = true;
3265
3266 var _button = _dereq_(2);
3267
3268 var _button2 = _interopRequireDefault(_button);
3269
3270 var _component = _dereq_(5);
3271
3272 var _component2 = _interopRequireDefault(_component);
3273
3274 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3275
3276 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3277
3278 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; }
3279
3280 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; } /**
3281                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-toggle.js
3282                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3283
3284
3285 /**
3286  * Button to toggle between play and pause.
3287  *
3288  * @extends Button
3289  */
3290 var PlayToggle = function (_Button) {
3291   _inherits(PlayToggle, _Button);
3292
3293   /**
3294    * Creates an instance of this class.
3295    *
3296    * @param {Player} player
3297    *        The `Player` that this class should be attached to.
3298    *
3299    * @param {Object} [options]
3300    *        The key/value store of player options.
3301    */
3302   function PlayToggle(player, options) {
3303     _classCallCheck(this, PlayToggle);
3304
3305     var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3306
3307     _this.on(player, 'play', _this.handlePlay);
3308     _this.on(player, 'pause', _this.handlePause);
3309     return _this;
3310   }
3311
3312   /**
3313    * Builds the default DOM `className`.
3314    *
3315    * @return {string}
3316    *         The DOM `className` for this object.
3317    */
3318
3319
3320   PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
3321     return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
3322   };
3323
3324   /**
3325    * This gets called when an `PlayToggle` is "clicked". See
3326    * {@link ClickableComponent} for more detailed information on what a click can be.
3327    *
3328    * @param {EventTarget~Event} [event]
3329    *        The `keydown`, `tap`, or `click` event that caused this function to be
3330    *        called.
3331    *
3332    * @listens tap
3333    * @listens click
3334    */
3335
3336
3337   PlayToggle.prototype.handleClick = function handleClick(event) {
3338     if (this.player_.paused()) {
3339       this.player_.play();
3340     } else {
3341       this.player_.pause();
3342     }
3343   };
3344
3345   /**
3346    * Add the vjs-playing class to the element so it can change appearance.
3347    *
3348    * @param {EventTarget~Event} [event]
3349    *        The event that caused this function to run.
3350    *
3351    * @listens Player#play
3352    */
3353
3354
3355   PlayToggle.prototype.handlePlay = function handlePlay(event) {
3356     this.removeClass('vjs-paused');
3357     this.addClass('vjs-playing');
3358     // change the button text to "Pause"
3359     this.controlText('Pause');
3360   };
3361
3362   /**
3363    * Add the vjs-paused class to the element so it can change appearance.
3364    *
3365    * @param {EventTarget~Event} [event]
3366    *        The event that caused this function to run.
3367    *
3368    * @listens Player#pause
3369    */
3370
3371
3372   PlayToggle.prototype.handlePause = function handlePause(event) {
3373     this.removeClass('vjs-playing');
3374     this.addClass('vjs-paused');
3375     // change the button text to "Play"
3376     this.controlText('Play');
3377   };
3378
3379   return PlayToggle;
3380 }(_button2['default']);
3381
3382 /**
3383  * The text that should display over the `PlayToggle`s controls. Added for localization.
3384  *
3385  * @type {string}
3386  * @private
3387  */
3388
3389
3390 PlayToggle.prototype.controlText_ = 'Play';
3391
3392 _component2['default'].registerComponent('PlayToggle', PlayToggle);
3393 exports['default'] = PlayToggle;
3394
3395 },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
3396 'use strict';
3397
3398 exports.__esModule = true;
3399
3400 var _menuButton = _dereq_(47);
3401
3402 var _menuButton2 = _interopRequireDefault(_menuButton);
3403
3404 var _menu = _dereq_(49);
3405
3406 var _menu2 = _interopRequireDefault(_menu);
3407
3408 var _playbackRateMenuItem = _dereq_(14);
3409
3410 var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
3411
3412 var _component = _dereq_(5);
3413
3414 var _component2 = _interopRequireDefault(_component);
3415
3416 var _dom = _dereq_(81);
3417
3418 var Dom = _interopRequireWildcard(_dom);
3419
3420 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; } }
3421
3422 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3423
3424 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3425
3426 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; }
3427
3428 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; } /**
3429                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file playback-rate-menu-button.js
3430                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3431
3432
3433 /**
3434  * The component for controlling the playback rate.
3435  *
3436  * @extends MenuButton
3437  */
3438 var PlaybackRateMenuButton = function (_MenuButton) {
3439   _inherits(PlaybackRateMenuButton, _MenuButton);
3440
3441   /**
3442    * Creates an instance of this class.
3443    *
3444    * @param {Player} player
3445    *        The `Player` that this class should be attached to.
3446    *
3447    * @param {Object} [options]
3448    *        The key/value store of player options.
3449    */
3450   function PlaybackRateMenuButton(player, options) {
3451     _classCallCheck(this, PlaybackRateMenuButton);
3452
3453     var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
3454
3455     _this.updateVisibility();
3456     _this.updateLabel();
3457
3458     _this.on(player, 'loadstart', _this.updateVisibility);
3459     _this.on(player, 'ratechange', _this.updateLabel);
3460     return _this;
3461   }
3462
3463   /**
3464    * Create the `Component`'s DOM element
3465    *
3466    * @return {Element}
3467    *         The element that was created.
3468    */
3469
3470
3471   PlaybackRateMenuButton.prototype.createEl = function createEl() {
3472     var el = _MenuButton.prototype.createEl.call(this);
3473
3474     this.labelEl_ = Dom.createEl('div', {
3475       className: 'vjs-playback-rate-value',
3476       innerHTML: 1.0
3477     });
3478
3479     el.appendChild(this.labelEl_);
3480
3481     return el;
3482   };
3483
3484   /**
3485    * Builds the default DOM `className`.
3486    *
3487    * @return {string}
3488    *         The DOM `className` for this object.
3489    */
3490
3491
3492   PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
3493     return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
3494   };
3495
3496   /**
3497    * Create the playback rate menu
3498    *
3499    * @return {Menu}
3500    *         Menu object populated with {@link PlaybackRateMenuItem}s
3501    */
3502
3503
3504   PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
3505     var menu = new _menu2['default'](this.player());
3506     var rates = this.playbackRates();
3507
3508     if (rates) {
3509       for (var i = rates.length - 1; i >= 0; i--) {
3510         menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
3511       }
3512     }
3513
3514     return menu;
3515   };
3516
3517   /**
3518    * Updates ARIA accessibility attributes
3519    */
3520
3521
3522   PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
3523     // Current playback rate
3524     this.el().setAttribute('aria-valuenow', this.player().playbackRate());
3525   };
3526
3527   /**
3528    * This gets called when an `PlaybackRateMenuButton` is "clicked". See
3529    * {@link ClickableComponent} for more detailed information on what a click can be.
3530    *
3531    * @param {EventTarget~Event} [event]
3532    *        The `keydown`, `tap`, or `click` event that caused this function to be
3533    *        called.
3534    *
3535    * @listens tap
3536    * @listens click
3537    */
3538
3539
3540   PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
3541     // select next rate option
3542     var currentRate = this.player().playbackRate();
3543     var rates = this.playbackRates();
3544
3545     // this will select first one if the last one currently selected
3546     var newRate = rates[0];
3547
3548     for (var i = 0; i < rates.length; i++) {
3549       if (rates[i] > currentRate) {
3550         newRate = rates[i];
3551         break;
3552       }
3553     }
3554     this.player().playbackRate(newRate);
3555   };
3556
3557   /**
3558    * Get possible playback rates
3559    *
3560    * @return {Array}
3561    *         All possible playback rates
3562    */
3563
3564
3565   PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
3566     return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
3567   };
3568
3569   /**
3570    * Get whether playback rates is supported by the tech
3571    * and an array of playback rates exists
3572    *
3573    * @return {boolean}
3574    *         Whether changing playback rate is supported
3575    */
3576
3577
3578   PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
3579     return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
3580   };
3581
3582   /**
3583    * Hide playback rate controls when they're no playback rate options to select
3584    *
3585    * @param {EventTarget~Event} [event]
3586    *        The event that caused this function to run.
3587    *
3588    * @listens Player#loadstart
3589    */
3590
3591
3592   PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
3593     if (this.playbackRateSupported()) {
3594       this.removeClass('vjs-hidden');
3595     } else {
3596       this.addClass('vjs-hidden');
3597     }
3598   };
3599
3600   /**
3601    * Update button label when rate changed
3602    *
3603    * @param {EventTarget~Event} [event]
3604    *        The event that caused this function to run.
3605    *
3606    * @listens Player#ratechange
3607    */
3608
3609
3610   PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
3611     if (this.playbackRateSupported()) {
3612       this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
3613     }
3614   };
3615
3616   return PlaybackRateMenuButton;
3617 }(_menuButton2['default']);
3618
3619 /**
3620  * The text that should display over the `FullscreenToggle`s controls. Added for localization.
3621  *
3622  * @type {string}
3623  * @private
3624  */
3625
3626
3627 PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
3628
3629 _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
3630 exports['default'] = PlaybackRateMenuButton;
3631
3632 },{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){
3633 'use strict';
3634
3635 exports.__esModule = true;
3636
3637 var _menuItem = _dereq_(48);
3638
3639 var _menuItem2 = _interopRequireDefault(_menuItem);
3640
3641 var _component = _dereq_(5);
3642
3643 var _component2 = _interopRequireDefault(_component);
3644
3645 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3646
3647 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3648
3649 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; }
3650
3651 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; } /**
3652                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file playback-rate-menu-item.js
3653                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3654
3655
3656 /**
3657  * The specific menu item type for selecting a playback rate.
3658  *
3659  * @extends MenuItem
3660  */
3661 var PlaybackRateMenuItem = function (_MenuItem) {
3662   _inherits(PlaybackRateMenuItem, _MenuItem);
3663
3664   /**
3665    * Creates an instance of this class.
3666    *
3667    * @param {Player} player
3668    *        The `Player` that this class should be attached to.
3669    *
3670    * @param {Object} [options]
3671    *        The key/value store of player options.
3672    */
3673   function PlaybackRateMenuItem(player, options) {
3674     _classCallCheck(this, PlaybackRateMenuItem);
3675
3676     var label = options.rate;
3677     var rate = parseFloat(label, 10);
3678
3679     // Modify options for parent MenuItem class's init.
3680     options.label = label;
3681     options.selected = rate === 1;
3682     options.selectable = true;
3683
3684     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
3685
3686     _this.label = label;
3687     _this.rate = rate;
3688
3689     _this.on(player, 'ratechange', _this.update);
3690     return _this;
3691   }
3692
3693   /**
3694    * This gets called when an `PlaybackRateMenuItem` is "clicked". See
3695    * {@link ClickableComponent} for more detailed information on what a click can be.
3696    *
3697    * @param {EventTarget~Event} [event]
3698    *        The `keydown`, `tap`, or `click` event that caused this function to be
3699    *        called.
3700    *
3701    * @listens tap
3702    * @listens click
3703    */
3704
3705
3706   PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
3707     _MenuItem.prototype.handleClick.call(this);
3708     this.player().playbackRate(this.rate);
3709   };
3710
3711   /**
3712    * Update the PlaybackRateMenuItem when the playbackrate changes.
3713    *
3714    * @param {EventTarget~Event} [event]
3715    *        The `ratechange` event that caused this function to run.
3716    *
3717    * @listens Player#ratechange
3718    */
3719
3720
3721   PlaybackRateMenuItem.prototype.update = function update(event) {
3722     this.selected(this.player().playbackRate() === this.rate);
3723   };
3724
3725   return PlaybackRateMenuItem;
3726 }(_menuItem2['default']);
3727
3728 /**
3729  * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
3730  *
3731  * @type {string}
3732  * @private
3733  */
3734
3735
3736 PlaybackRateMenuItem.prototype.contentElType = 'button';
3737
3738 _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
3739 exports['default'] = PlaybackRateMenuItem;
3740
3741 },{"48":48,"5":5}],15:[function(_dereq_,module,exports){
3742 'use strict';
3743
3744 exports.__esModule = true;
3745
3746 var _component = _dereq_(5);
3747
3748 var _component2 = _interopRequireDefault(_component);
3749
3750 var _dom = _dereq_(81);
3751
3752 var Dom = _interopRequireWildcard(_dom);
3753
3754 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; } }
3755
3756 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3757
3758 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3759
3760 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; }
3761
3762 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; } /**
3763                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file load-progress-bar.js
3764                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3765
3766
3767 /**
3768  * Shows loading progress
3769  *
3770  * @extends Component
3771  */
3772 var LoadProgressBar = function (_Component) {
3773   _inherits(LoadProgressBar, _Component);
3774
3775   /**
3776    * Creates an instance of this class.
3777    *
3778    * @param {Player} player
3779    *        The `Player` that this class should be attached to.
3780    *
3781    * @param {Object} [options]
3782    *        The key/value store of player options.
3783    */
3784   function LoadProgressBar(player, options) {
3785     _classCallCheck(this, LoadProgressBar);
3786
3787     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3788
3789     _this.partEls_ = [];
3790     _this.on(player, 'progress', _this.update);
3791     return _this;
3792   }
3793
3794   /**
3795    * Create the `Component`'s DOM element
3796    *
3797    * @return {Element}
3798    *         The element that was created.
3799    */
3800
3801
3802   LoadProgressBar.prototype.createEl = function createEl() {
3803     return _Component.prototype.createEl.call(this, 'div', {
3804       className: 'vjs-load-progress',
3805       innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
3806     });
3807   };
3808
3809   /**
3810    * Update progress bar
3811    *
3812    * @param {EventTarget~Event} [event]
3813    *        The `progress` event that caused this function to run.
3814    *
3815    * @listens Player#progress
3816    */
3817
3818
3819   LoadProgressBar.prototype.update = function update(event) {
3820     var buffered = this.player_.buffered();
3821     var duration = this.player_.duration();
3822     var bufferedEnd = this.player_.bufferedEnd();
3823     var children = this.partEls_;
3824
3825     // get the percent width of a time compared to the total end
3826     var percentify = function percentify(time, end) {
3827       // no NaN
3828       var percent = time / end || 0;
3829
3830       return (percent >= 1 ? 1 : percent) * 100 + '%';
3831     };
3832
3833     // update the width of the progress bar
3834     this.el_.style.width = percentify(bufferedEnd, duration);
3835
3836     // add child elements to represent the individual buffered time ranges
3837     for (var i = 0; i < buffered.length; i++) {
3838       var start = buffered.start(i);
3839       var end = buffered.end(i);
3840       var part = children[i];
3841
3842       if (!part) {
3843         part = this.el_.appendChild(Dom.createEl());
3844         children[i] = part;
3845       }
3846
3847       // set the percent based on the width of the progress bar (bufferedEnd)
3848       part.style.left = percentify(start, bufferedEnd);
3849       part.style.width = percentify(end - start, bufferedEnd);
3850     }
3851
3852     // remove unused buffered range elements
3853     for (var _i = children.length; _i > buffered.length; _i--) {
3854       this.el_.removeChild(children[_i - 1]);
3855     }
3856     children.length = buffered.length;
3857   };
3858
3859   return LoadProgressBar;
3860 }(_component2['default']);
3861
3862 _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
3863 exports['default'] = LoadProgressBar;
3864
3865 },{"5":5,"81":81}],16:[function(_dereq_,module,exports){
3866 'use strict';
3867
3868 exports.__esModule = true;
3869
3870 var _component = _dereq_(5);
3871
3872 var _component2 = _interopRequireDefault(_component);
3873
3874 var _dom = _dereq_(81);
3875
3876 var Dom = _interopRequireWildcard(_dom);
3877
3878 var _fn = _dereq_(83);
3879
3880 var Fn = _interopRequireWildcard(_fn);
3881
3882 var _formatTime = _dereq_(84);
3883
3884 var _formatTime2 = _interopRequireDefault(_formatTime);
3885
3886 var _computedStyle = _dereq_(80);
3887
3888 var _computedStyle2 = _interopRequireDefault(_computedStyle);
3889
3890 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; } }
3891
3892 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3893
3894 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3895
3896 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; }
3897
3898 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; } /**
3899                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file mouse-time-display.js
3900                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
3901
3902
3903 /**
3904  * The Mouse Time Display component shows the time you will seek to
3905  * when hovering over the progress bar
3906  *
3907  * @extends Component
3908  */
3909 var MouseTimeDisplay = function (_Component) {
3910   _inherits(MouseTimeDisplay, _Component);
3911
3912   /**
3913    * Creates an instance of this class.
3914    *
3915    * @param {Player} player
3916    *        The `Player` that this class should be attached to.
3917    *
3918    * @param {Object} [options]
3919    *        The key/value store of player options.
3920    */
3921   function MouseTimeDisplay(player, options) {
3922     _classCallCheck(this, MouseTimeDisplay);
3923
3924     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3925
3926     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
3927       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
3928     }
3929
3930     if (_this.keepTooltipsInside) {
3931       _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
3932       _this.el().appendChild(_this.tooltip);
3933       _this.addClass('vjs-keep-tooltips-inside');
3934     }
3935
3936     _this.update(0, 0);
3937
3938     player.on('ready', function () {
3939       _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
3940     });
3941     return _this;
3942   }
3943
3944   /**
3945    * Create the `Component`'s DOM element
3946    *
3947    * @return {Element}
3948    *         The element that was created.
3949    */
3950
3951
3952   MouseTimeDisplay.prototype.createEl = function createEl() {
3953     return _Component.prototype.createEl.call(this, 'div', {
3954       className: 'vjs-mouse-display'
3955     });
3956   };
3957
3958   /**
3959    * Handle the mouse move event on the `MouseTimeDisplay`.
3960    *
3961    * @param {EventTarget~Event} event
3962    *        The `mousemove` event that caused this to event to run.
3963    *
3964    * @listen mousemove
3965    */
3966
3967
3968   MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
3969     var duration = this.player_.duration();
3970     var newTime = this.calculateDistance(event) * duration;
3971     var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
3972
3973     this.update(newTime, position);
3974   };
3975
3976   /**
3977    * Update the time and posistion of the `MouseTimeDisplay`.
3978    *
3979    * @param {number} newTime
3980    *        Time to change the `MouseTimeDisplay` to.
3981    *
3982    * @param {nubmer} position
3983    *        Postion from the left of the in pixels.
3984    */
3985
3986
3987   MouseTimeDisplay.prototype.update = function update(newTime, position) {
3988     var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
3989
3990     this.el().style.left = position + 'px';
3991     this.el().setAttribute('data-current-time', time);
3992
3993     if (this.keepTooltipsInside) {
3994       var clampedPosition = this.clampPosition_(position);
3995       var difference = position - clampedPosition + 1;
3996       var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
3997       var tooltipWidthHalf = tooltipWidth / 2;
3998
3999       this.tooltip.innerHTML = time;
4000       this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
4001     }
4002   };
4003
4004   /**
4005    * Get the mouse pointers x coordinate in pixels.
4006    *
4007    * @param {EventTarget~Event} [event]
4008    *        The `mousemove` event that was passed to this function by
4009    *        {@link MouseTimeDisplay#handleMouseMove}
4010    *
4011    * @return {number}
4012    *         THe x position in pixels of the mouse pointer.
4013    */
4014
4015
4016   MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
4017     return Dom.getPointerPosition(this.el().parentNode, event).x;
4018   };
4019
4020   /**
4021    * This takes in a horizontal position for the bar and returns a clamped position.
4022    * Clamped position means that it will keep the position greater than half the width
4023    * of the tooltip and smaller than the player width minus half the width o the tooltip.
4024    * It will only clamp the position if `keepTooltipsInside` option is set.
4025    *
4026    * @param {number} position
4027    *        The position the bar wants to be
4028    *
4029    * @return {number}
4030    *         The (potentially) new clamped position.
4031    *
4032    * @private
4033    */
4034
4035
4036   MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
4037     if (!this.keepTooltipsInside) {
4038       return position;
4039     }
4040
4041     var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4042     var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
4043     var tooltipWidthHalf = tooltipWidth / 2;
4044     var actualPosition = position;
4045
4046     if (position < tooltipWidthHalf) {
4047       actualPosition = Math.ceil(tooltipWidthHalf);
4048     } else if (position > playerWidth - tooltipWidthHalf) {
4049       actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
4050     }
4051
4052     return actualPosition;
4053   };
4054
4055   return MouseTimeDisplay;
4056 }(_component2['default']);
4057
4058 _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
4059 exports['default'] = MouseTimeDisplay;
4060
4061 },{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){
4062 'use strict';
4063
4064 exports.__esModule = true;
4065
4066 var _component = _dereq_(5);
4067
4068 var _component2 = _interopRequireDefault(_component);
4069
4070 var _fn = _dereq_(83);
4071
4072 var Fn = _interopRequireWildcard(_fn);
4073
4074 var _formatTime = _dereq_(84);
4075
4076 var _formatTime2 = _interopRequireDefault(_formatTime);
4077
4078 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; } }
4079
4080 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4081
4082 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4083
4084 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; }
4085
4086 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; } /**
4087                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-progress-bar.js
4088                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4089
4090
4091 /**
4092  * Shows play progress
4093  *
4094  * @extends Component
4095  */
4096 var PlayProgressBar = function (_Component) {
4097   _inherits(PlayProgressBar, _Component);
4098
4099   /**
4100    * Creates an instance of this class.
4101    *
4102    * @param {Player} player
4103    *        The `Player` that this class should be attached to.
4104    *
4105    * @param {Object} [options]
4106    *        The key/value store of player options.
4107    */
4108   function PlayProgressBar(player, options) {
4109     _classCallCheck(this, PlayProgressBar);
4110
4111     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4112
4113     _this.updateDataAttr();
4114     _this.on(player, 'timeupdate', _this.updateDataAttr);
4115     player.ready(Fn.bind(_this, _this.updateDataAttr));
4116
4117     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4118       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4119     }
4120
4121     if (_this.keepTooltipsInside) {
4122       _this.addClass('vjs-keep-tooltips-inside');
4123     }
4124     return _this;
4125   }
4126
4127   /**
4128    * Create the `Component`'s DOM element
4129    *
4130    * @return {Element}
4131    *         The element that was created.
4132    */
4133
4134
4135   PlayProgressBar.prototype.createEl = function createEl() {
4136     return _Component.prototype.createEl.call(this, 'div', {
4137       className: 'vjs-play-progress vjs-slider-bar',
4138       innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4139     });
4140   };
4141
4142   /**
4143    * Update the data-current-time attribute on the `PlayProgressBar`.
4144    *
4145    * @param {EventTarget~Event} [event]
4146    *        The `timeupdate` event that caused this to run.
4147    *
4148    * @listens Player#timeupdate
4149    */
4150
4151
4152   PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4153     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4154
4155     this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
4156   };
4157
4158   return PlayProgressBar;
4159 }(_component2['default']);
4160
4161 _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
4162 exports['default'] = PlayProgressBar;
4163
4164 },{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){
4165 'use strict';
4166
4167 exports.__esModule = true;
4168
4169 var _component = _dereq_(5);
4170
4171 var _component2 = _interopRequireDefault(_component);
4172
4173 _dereq_(19);
4174
4175 _dereq_(16);
4176
4177 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4178
4179 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4180
4181 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; }
4182
4183 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; } /**
4184                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file progress-control.js
4185                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4186
4187
4188 /**
4189  * The Progress Control component contains the seek bar, load progress,
4190  * and play progress.
4191  *
4192  * @extends Component
4193  */
4194 var ProgressControl = function (_Component) {
4195   _inherits(ProgressControl, _Component);
4196
4197   function ProgressControl() {
4198     _classCallCheck(this, ProgressControl);
4199
4200     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4201   }
4202
4203   /**
4204    * Create the `Component`'s DOM element
4205    *
4206    * @return {Element}
4207    *         The element that was created.
4208    */
4209   ProgressControl.prototype.createEl = function createEl() {
4210     return _Component.prototype.createEl.call(this, 'div', {
4211       className: 'vjs-progress-control vjs-control'
4212     });
4213   };
4214
4215   return ProgressControl;
4216 }(_component2['default']);
4217
4218 /**
4219  * Default options for `ProgressControl`
4220  *
4221  * @type {Object}
4222  * @private
4223  */
4224
4225
4226 ProgressControl.prototype.options_ = {
4227   children: ['seekBar']
4228 };
4229
4230 _component2['default'].registerComponent('ProgressControl', ProgressControl);
4231 exports['default'] = ProgressControl;
4232
4233 },{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){
4234 'use strict';
4235
4236 exports.__esModule = true;
4237
4238 var _slider = _dereq_(57);
4239
4240 var _slider2 = _interopRequireDefault(_slider);
4241
4242 var _component = _dereq_(5);
4243
4244 var _component2 = _interopRequireDefault(_component);
4245
4246 var _fn = _dereq_(83);
4247
4248 var Fn = _interopRequireWildcard(_fn);
4249
4250 var _formatTime = _dereq_(84);
4251
4252 var _formatTime2 = _interopRequireDefault(_formatTime);
4253
4254 var _computedStyle = _dereq_(80);
4255
4256 var _computedStyle2 = _interopRequireDefault(_computedStyle);
4257
4258 _dereq_(15);
4259
4260 _dereq_(17);
4261
4262 _dereq_(20);
4263
4264 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; } }
4265
4266 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4267
4268 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4269
4270 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; }
4271
4272 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; } /**
4273                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file seek-bar.js
4274                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4275
4276
4277 /**
4278  * Seek Bar and holder for the progress bars
4279  *
4280  * @extends Slider
4281  */
4282 var SeekBar = function (_Slider) {
4283   _inherits(SeekBar, _Slider);
4284
4285   /**
4286    * Creates an instance of this class.
4287    *
4288    * @param {Player} player
4289    *        The `Player` that this class should be attached to.
4290    *
4291    * @param {Object} [options]
4292    *        The key/value store of player options.
4293    */
4294   function SeekBar(player, options) {
4295     _classCallCheck(this, SeekBar);
4296
4297     var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
4298
4299     _this.on(player, 'timeupdate', _this.updateProgress);
4300     _this.on(player, 'ended', _this.updateProgress);
4301     player.ready(Fn.bind(_this, _this.updateProgress));
4302
4303     if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4304       _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4305     }
4306
4307     if (_this.keepTooltipsInside) {
4308       _this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
4309     }
4310     return _this;
4311   }
4312
4313   /**
4314    * Create the `Component`'s DOM element
4315    *
4316    * @return {Element}
4317    *         The element that was created.
4318    */
4319
4320
4321   SeekBar.prototype.createEl = function createEl() {
4322     return _Slider.prototype.createEl.call(this, 'div', {
4323       className: 'vjs-progress-holder'
4324     }, {
4325       'aria-label': 'progress bar'
4326     });
4327   };
4328
4329   /**
4330    * Update the seek bars tooltip and width.
4331    *
4332    * @param {EventTarget~Event} [event]
4333    *        The `timeupdate` or `ended` event that caused this to run.
4334    *
4335    * @listens Player#timeupdate
4336    * @listens Player#ended
4337    */
4338
4339
4340   SeekBar.prototype.updateProgress = function updateProgress(event) {
4341     this.updateAriaAttributes(this.el_);
4342
4343     if (this.keepTooltipsInside) {
4344       this.updateAriaAttributes(this.tooltipProgressBar.el_);
4345       this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
4346
4347       var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4348       var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
4349       var tooltipStyle = this.tooltipProgressBar.el().style;
4350
4351       tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
4352       tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
4353       tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
4354     }
4355   };
4356
4357   /**
4358    * Update ARIA accessibility attributes
4359    *
4360    * @param {Element} el
4361    *        The element to update with aria accessibility attributes.
4362    */
4363
4364
4365   SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
4366     // Allows for smooth scrubbing, when player can't keep up.
4367     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4368
4369     // machine readable value of progress bar (percentage complete)
4370     el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
4371     // human readable value of progress bar (time complete)
4372     el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
4373   };
4374
4375   /**
4376    * Get percentage of video played
4377    *
4378    * @return {number}
4379    *         The percentage played
4380    */
4381
4382
4383   SeekBar.prototype.getPercent = function getPercent() {
4384     var percent = this.player_.currentTime() / this.player_.duration();
4385
4386     return percent >= 1 ? 1 : percent;
4387   };
4388
4389   /**
4390    * Handle mouse down on seek bar
4391    *
4392    * @param {EventTarget~Event} event
4393    *        The `mousedown` event that caused this to run.
4394    *
4395    * @listens mousedown
4396    */
4397
4398
4399   SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
4400     this.player_.scrubbing(true);
4401
4402     this.videoWasPlaying = !this.player_.paused();
4403     this.player_.pause();
4404
4405     _Slider.prototype.handleMouseDown.call(this, event);
4406   };
4407
4408   /**
4409    * Handle mouse move on seek bar
4410    *
4411    * @param {EventTarget~Event} event
4412    *        The `mousemove` event that caused this to run.
4413    *
4414    * @listens mousemove
4415    */
4416
4417
4418   SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
4419     var newTime = this.calculateDistance(event) * this.player_.duration();
4420
4421     // Don't let video end while scrubbing.
4422     if (newTime === this.player_.duration()) {
4423       newTime = newTime - 0.1;
4424     }
4425
4426     // Set new time (tell player to seek to new time)
4427     this.player_.currentTime(newTime);
4428   };
4429
4430   /**
4431    * Handle mouse up on seek bar
4432    *
4433    * @param {EventTarget~Event} event
4434    *        The `mouseup` event that caused this to run.
4435    *
4436    * @listens mouseup
4437    */
4438
4439
4440   SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
4441     _Slider.prototype.handleMouseUp.call(this, event);
4442
4443     this.player_.scrubbing(false);
4444     if (this.videoWasPlaying) {
4445       this.player_.play();
4446     }
4447   };
4448
4449   /**
4450    * Move more quickly fast forward for keyboard-only users
4451    */
4452
4453
4454   SeekBar.prototype.stepForward = function stepForward() {
4455     // more quickly fast forward for keyboard-only users
4456     this.player_.currentTime(this.player_.currentTime() + 5);
4457   };
4458
4459   /**
4460    * Move more quickly rewind for keyboard-only users
4461    */
4462
4463
4464   SeekBar.prototype.stepBack = function stepBack() {
4465     // more quickly rewind for keyboard-only users
4466     this.player_.currentTime(this.player_.currentTime() - 5);
4467   };
4468
4469   return SeekBar;
4470 }(_slider2['default']);
4471
4472 /**
4473  * Default options for the `SeekBar`
4474  *
4475  * @type {Object}
4476  * @private
4477  */
4478
4479
4480 SeekBar.prototype.options_ = {
4481   children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
4482   barName: 'playProgressBar'
4483 };
4484
4485 /**
4486  * Call the update event for this Slider when this event happens on the player.
4487  *
4488  * @type {string}
4489  */
4490 SeekBar.prototype.playerEvent = 'timeupdate';
4491
4492 _component2['default'].registerComponent('SeekBar', SeekBar);
4493 exports['default'] = SeekBar;
4494
4495 },{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){
4496 'use strict';
4497
4498 exports.__esModule = true;
4499
4500 var _component = _dereq_(5);
4501
4502 var _component2 = _interopRequireDefault(_component);
4503
4504 var _fn = _dereq_(83);
4505
4506 var Fn = _interopRequireWildcard(_fn);
4507
4508 var _formatTime = _dereq_(84);
4509
4510 var _formatTime2 = _interopRequireDefault(_formatTime);
4511
4512 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; } }
4513
4514 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4515
4516 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4517
4518 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; }
4519
4520 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; } /**
4521                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file play-progress-bar.js
4522                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4523
4524
4525 /**
4526  * Shows play progress
4527  *
4528  * @extends Component
4529  */
4530 var TooltipProgressBar = function (_Component) {
4531   _inherits(TooltipProgressBar, _Component);
4532
4533   /**
4534    * Creates an instance of this class.
4535    *
4536    * @param {Player} player
4537    *        The `Player` that this class should be attached to.
4538    *
4539    * @param {Object} [options]
4540    *        The key/value store of player options.
4541    */
4542   function TooltipProgressBar(player, options) {
4543     _classCallCheck(this, TooltipProgressBar);
4544
4545     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4546
4547     _this.updateDataAttr();
4548     _this.on(player, 'timeupdate', _this.updateDataAttr);
4549     player.ready(Fn.bind(_this, _this.updateDataAttr));
4550     return _this;
4551   }
4552
4553   /**
4554    * Create the `Component`'s DOM element
4555    *
4556    * @return {Element}
4557    *         The element that was created.
4558    */
4559
4560
4561   TooltipProgressBar.prototype.createEl = function createEl() {
4562     var el = _Component.prototype.createEl.call(this, 'div', {
4563       className: 'vjs-tooltip-progress-bar vjs-slider-bar',
4564       innerHTML: '<div class="vjs-time-tooltip"></div>\n        <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4565     });
4566
4567     this.tooltip = el.querySelector('.vjs-time-tooltip');
4568
4569     return el;
4570   };
4571
4572   /**
4573    * Updatet the data-current-time attribute for TooltipProgressBar
4574    *
4575    * @param {EventTarget~Event} [event]
4576    *        The `timeupdate` event that caused this function to run.
4577    *
4578    * @listens Player#timeupdate
4579    */
4580
4581
4582   TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4583     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4584     var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
4585
4586     this.el_.setAttribute('data-current-time', formattedTime);
4587     this.tooltip.innerHTML = formattedTime;
4588   };
4589
4590   return TooltipProgressBar;
4591 }(_component2['default']);
4592
4593 _component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
4594 exports['default'] = TooltipProgressBar;
4595
4596 },{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){
4597 'use strict';
4598
4599 exports.__esModule = true;
4600
4601 var _spacer = _dereq_(22);
4602
4603 var _spacer2 = _interopRequireDefault(_spacer);
4604
4605 var _component = _dereq_(5);
4606
4607 var _component2 = _interopRequireDefault(_component);
4608
4609 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4610
4611 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4612
4613 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; }
4614
4615 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; } /**
4616                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file custom-control-spacer.js
4617                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4618
4619
4620 /**
4621  * Spacer specifically meant to be used as an insertion point for new plugins, etc.
4622  *
4623  * @extends Spacer
4624  */
4625 var CustomControlSpacer = function (_Spacer) {
4626   _inherits(CustomControlSpacer, _Spacer);
4627
4628   function CustomControlSpacer() {
4629     _classCallCheck(this, CustomControlSpacer);
4630
4631     return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
4632   }
4633
4634   /**
4635    * Builds the default DOM `className`.
4636    *
4637    * @return {string}
4638    *         The DOM `className` for this object.
4639    */
4640   CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
4641     return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
4642   };
4643
4644   /**
4645    * Create the `Component`'s DOM element
4646    *
4647    * @return {Element}
4648    *         The element that was created.
4649    */
4650
4651
4652   CustomControlSpacer.prototype.createEl = function createEl() {
4653     var el = _Spacer.prototype.createEl.call(this, {
4654       className: this.buildCSSClass()
4655     });
4656
4657     // No-flex/table-cell mode requires there be some content
4658     // in the cell to fill the remaining space of the table.
4659     el.innerHTML = '&nbsp;';
4660     return el;
4661   };
4662
4663   return CustomControlSpacer;
4664 }(_spacer2['default']);
4665
4666 _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
4667 exports['default'] = CustomControlSpacer;
4668
4669 },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
4670 'use strict';
4671
4672 exports.__esModule = true;
4673
4674 var _component = _dereq_(5);
4675
4676 var _component2 = _interopRequireDefault(_component);
4677
4678 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4679
4680 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4681
4682 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; }
4683
4684 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; } /**
4685                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file spacer.js
4686                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4687
4688
4689 /**
4690  * Just an empty spacer element that can be used as an append point for plugins, etc.
4691  * Also can be used to create space between elements when necessary.
4692  *
4693  * @extends Component
4694  */
4695 var Spacer = function (_Component) {
4696   _inherits(Spacer, _Component);
4697
4698   function Spacer() {
4699     _classCallCheck(this, Spacer);
4700
4701     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4702   }
4703
4704   /**
4705    * Builds the default DOM `className`.
4706    *
4707    * @return {string}
4708    *         The DOM `className` for this object.
4709    */
4710   Spacer.prototype.buildCSSClass = function buildCSSClass() {
4711     return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
4712   };
4713
4714   /**
4715    * Create the `Component`'s DOM element
4716    *
4717    * @return {Element}
4718    *         The element that was created.
4719    */
4720
4721
4722   Spacer.prototype.createEl = function createEl() {
4723     return _Component.prototype.createEl.call(this, 'div', {
4724       className: this.buildCSSClass()
4725     });
4726   };
4727
4728   return Spacer;
4729 }(_component2['default']);
4730
4731 _component2['default'].registerComponent('Spacer', Spacer);
4732
4733 exports['default'] = Spacer;
4734
4735 },{"5":5}],23:[function(_dereq_,module,exports){
4736 'use strict';
4737
4738 exports.__esModule = true;
4739
4740 var _textTrackMenuItem = _dereq_(31);
4741
4742 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
4743
4744 var _component = _dereq_(5);
4745
4746 var _component2 = _interopRequireDefault(_component);
4747
4748 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4749
4750 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4751
4752 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; }
4753
4754 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; } /**
4755                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file caption-settings-menu-item.js
4756                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4757
4758
4759 /**
4760  * The menu item for caption track settings menu
4761  *
4762  * @extends TextTrackMenuItem
4763  */
4764 var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
4765   _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
4766
4767   /**
4768    * Creates an instance of this class.
4769    *
4770    * @param {Player} player
4771    *        The `Player` that this class should be attached to.
4772    *
4773    * @param {Object} [options]
4774    *        The key/value store of player options.
4775    */
4776   function CaptionSettingsMenuItem(player, options) {
4777     _classCallCheck(this, CaptionSettingsMenuItem);
4778
4779     options.track = {
4780       player: player,
4781       kind: options.kind,
4782       label: options.kind + ' settings',
4783       selectable: false,
4784       'default': false,
4785       mode: 'disabled'
4786     };
4787
4788     // CaptionSettingsMenuItem has no concept of 'selected'
4789     options.selectable = false;
4790
4791     var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
4792
4793     _this.addClass('vjs-texttrack-settings');
4794     _this.controlText(', opens ' + options.kind + ' settings dialog');
4795     return _this;
4796   }
4797
4798   /**
4799    * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
4800    * {@link ClickableComponent} for more detailed information on what a click can be.
4801    *
4802    * @param {EventTarget~Event} [event]
4803    *        The `keydown`, `tap`, or `click` event that caused this function to be
4804    *        called.
4805    *
4806    * @listens tap
4807    * @listens click
4808    */
4809
4810
4811   CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
4812     this.player().getChild('textTrackSettings').show();
4813     this.player().getChild('textTrackSettings').el_.focus();
4814   };
4815
4816   return CaptionSettingsMenuItem;
4817 }(_textTrackMenuItem2['default']);
4818
4819 _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
4820 exports['default'] = CaptionSettingsMenuItem;
4821
4822 },{"31":31,"5":5}],24:[function(_dereq_,module,exports){
4823 'use strict';
4824
4825 exports.__esModule = true;
4826
4827 var _textTrackButton = _dereq_(30);
4828
4829 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4830
4831 var _component = _dereq_(5);
4832
4833 var _component2 = _interopRequireDefault(_component);
4834
4835 var _captionSettingsMenuItem = _dereq_(23);
4836
4837 var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
4838
4839 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4840
4841 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4842
4843 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; }
4844
4845 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; } /**
4846                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file captions-button.js
4847                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4848
4849
4850 /**
4851  * The button component for toggling and selecting captions
4852  *
4853  * @extends TextTrackButton
4854  */
4855 var CaptionsButton = function (_TextTrackButton) {
4856   _inherits(CaptionsButton, _TextTrackButton);
4857
4858   /**
4859    * Creates an instance of this class.
4860    *
4861    * @param {Player} player
4862    *        The `Player` that this class should be attached to.
4863    *
4864    * @param {Object} [options]
4865    *        The key/value store of player options.
4866    *
4867    * @param {Component~ReadyCallback} [ready]
4868    *        The function to call when this component is ready.
4869    */
4870   function CaptionsButton(player, options, ready) {
4871     _classCallCheck(this, CaptionsButton);
4872
4873     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4874
4875     _this.el_.setAttribute('aria-label', 'Captions Menu');
4876     return _this;
4877   }
4878
4879   /**
4880    * Builds the default DOM `className`.
4881    *
4882    * @return {string}
4883    *         The DOM `className` for this object.
4884    */
4885
4886
4887   CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
4888     return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
4889   };
4890
4891   /**
4892    * Create caption menu items
4893    *
4894    * @return {CaptionSettingsMenuItem[]}
4895    *         The array of current menu items.
4896    */
4897
4898
4899   CaptionsButton.prototype.createItems = function createItems() {
4900     var items = [];
4901
4902     if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
4903       items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
4904
4905       this.hideThreshold_ += 1;
4906     }
4907
4908     return _TextTrackButton.prototype.createItems.call(this, items);
4909   };
4910
4911   return CaptionsButton;
4912 }(_textTrackButton2['default']);
4913
4914 /**
4915  * `kind` of TextTrack to look for to associate it with this menu.
4916  *
4917  * @type {string}
4918  * @private
4919  */
4920
4921
4922 CaptionsButton.prototype.kind_ = 'captions';
4923
4924 /**
4925  * The text that should display over the `CaptionsButton`s controls. Added for localization.
4926  *
4927  * @type {string}
4928  * @private
4929  */
4930 CaptionsButton.prototype.controlText_ = 'Captions';
4931
4932 _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
4933 exports['default'] = CaptionsButton;
4934
4935 },{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){
4936 'use strict';
4937
4938 exports.__esModule = true;
4939
4940 var _textTrackButton = _dereq_(30);
4941
4942 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4943
4944 var _component = _dereq_(5);
4945
4946 var _component2 = _interopRequireDefault(_component);
4947
4948 var _chaptersTrackMenuItem = _dereq_(26);
4949
4950 var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
4951
4952 var _toTitleCase = _dereq_(91);
4953
4954 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
4955
4956 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4957
4958 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4959
4960 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; }
4961
4962 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; } /**
4963                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file chapters-button.js
4964                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
4965
4966
4967 /**
4968  * The button component for toggling and selecting chapters
4969  * Chapters act much differently than other text tracks
4970  * Cues are navigation vs. other tracks of alternative languages
4971  *
4972  * @extends TextTrackButton
4973  */
4974 var ChaptersButton = function (_TextTrackButton) {
4975   _inherits(ChaptersButton, _TextTrackButton);
4976
4977   /**
4978    * Creates an instance of this class.
4979    *
4980    * @param {Player} player
4981    *        The `Player` that this class should be attached to.
4982    *
4983    * @param {Object} [options]
4984    *        The key/value store of player options.
4985    *
4986    * @param {Component~ReadyCallback} [ready]
4987    *        The function to call when this function is ready.
4988    */
4989   function ChaptersButton(player, options, ready) {
4990     _classCallCheck(this, ChaptersButton);
4991
4992     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4993
4994     _this.el_.setAttribute('aria-label', 'Chapters Menu');
4995     return _this;
4996   }
4997
4998   /**
4999    * Builds the default DOM `className`.
5000    *
5001    * @return {string}
5002    *         The DOM `className` for this object.
5003    */
5004
5005
5006   ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
5007     return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5008   };
5009
5010   /**
5011    * Update the menu based on the current state of its items.
5012    *
5013    * @param {EventTarget~Event} [event]
5014    *        An event that triggered this function to run.
5015    *
5016    * @listens TextTrackList#addtrack
5017    * @listens TextTrackList#removetrack
5018    * @listens TextTrackList#change
5019    */
5020
5021
5022   ChaptersButton.prototype.update = function update(event) {
5023     if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
5024       this.setTrack(this.findChaptersTrack());
5025     }
5026     _TextTrackButton.prototype.update.call(this);
5027   };
5028
5029   /**
5030    * Set the currently selected track for the chapters button.
5031    *
5032    * @param {TextTrack} track
5033    *        The new track to select. Nothing will change if this is the currently selected
5034    *        track.
5035    */
5036
5037
5038   ChaptersButton.prototype.setTrack = function setTrack(track) {
5039     if (this.track_ === track) {
5040       return;
5041     }
5042
5043     if (!this.updateHandler_) {
5044       this.updateHandler_ = this.update.bind(this);
5045     }
5046
5047     // here this.track_ refers to the old track instance
5048     if (this.track_) {
5049       var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5050
5051       if (remoteTextTrackEl) {
5052         remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
5053       }
5054
5055       this.track_ = null;
5056     }
5057
5058     this.track_ = track;
5059
5060     // here this.track_ refers to the new track instance
5061     if (this.track_) {
5062       this.track_.mode = 'hidden';
5063
5064       var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5065
5066       if (_remoteTextTrackEl) {
5067         _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
5068       }
5069     }
5070   };
5071
5072   /**
5073    * Find the track object that is currently in use by this ChaptersButton
5074    *
5075    * @return {TextTrack|undefined}
5076    *         The current track or undefined if none was found.
5077    */
5078
5079
5080   ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
5081     var tracks = this.player_.textTracks() || [];
5082
5083     for (var i = tracks.length - 1; i >= 0; i--) {
5084       // We will always choose the last track as our chaptersTrack
5085       var track = tracks[i];
5086
5087       if (track.kind === this.kind_) {
5088         return track;
5089       }
5090     }
5091   };
5092
5093   /**
5094    * Get the caption for the ChaptersButton based on the track label. This will also
5095    * use the current tracks localized kind as a fallback if a label does not exist.
5096    *
5097    * @return {string}
5098    *         The tracks current label or the localized track kind.
5099    */
5100
5101
5102   ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
5103     if (this.track_ && this.track_.label) {
5104       return this.track_.label;
5105     }
5106     return this.localize((0, _toTitleCase2['default'])(this.kind_));
5107   };
5108
5109   /**
5110    * Create menu from chapter track
5111    *
5112    * @return {Menu}
5113    *         New menu for the chapter buttons
5114    */
5115
5116
5117   ChaptersButton.prototype.createMenu = function createMenu() {
5118     this.options_.title = this.getMenuCaption();
5119     return _TextTrackButton.prototype.createMenu.call(this);
5120   };
5121
5122   /**
5123    * Create a menu item for each text track
5124    *
5125    * @return {TextTrackMenuItem[]}
5126    *         Array of menu items
5127    */
5128
5129
5130   ChaptersButton.prototype.createItems = function createItems() {
5131     var items = [];
5132
5133     if (!this.track_) {
5134       return items;
5135     }
5136
5137     var cues = this.track_.cues;
5138
5139     if (!cues) {
5140       return items;
5141     }
5142
5143     for (var i = 0, l = cues.length; i < l; i++) {
5144       var cue = cues[i];
5145       var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
5146
5147       items.push(mi);
5148     }
5149
5150     return items;
5151   };
5152
5153   return ChaptersButton;
5154 }(_textTrackButton2['default']);
5155
5156 /**
5157  * `kind` of TextTrack to look for to associate it with this menu.
5158  *
5159  * @type {string}
5160  * @private
5161  */
5162
5163
5164 ChaptersButton.prototype.kind_ = 'chapters';
5165
5166 /**
5167  * The text that should display over the `ChaptersButton`s controls. Added for localization.
5168  *
5169  * @type {string}
5170  * @private
5171  */
5172 ChaptersButton.prototype.controlText_ = 'Chapters';
5173
5174 _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
5175 exports['default'] = ChaptersButton;
5176
5177 },{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){
5178 'use strict';
5179
5180 exports.__esModule = true;
5181
5182 var _menuItem = _dereq_(48);
5183
5184 var _menuItem2 = _interopRequireDefault(_menuItem);
5185
5186 var _component = _dereq_(5);
5187
5188 var _component2 = _interopRequireDefault(_component);
5189
5190 var _fn = _dereq_(83);
5191
5192 var Fn = _interopRequireWildcard(_fn);
5193
5194 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; } }
5195
5196 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5197
5198 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5199
5200 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; }
5201
5202 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; } /**
5203                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file chapters-track-menu-item.js
5204                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5205
5206
5207 /**
5208  * The chapter track menu item
5209  *
5210  * @extends MenuItem
5211  */
5212 var ChaptersTrackMenuItem = function (_MenuItem) {
5213   _inherits(ChaptersTrackMenuItem, _MenuItem);
5214
5215   /**
5216    * Creates an instance of this class.
5217    *
5218    * @param {Player} player
5219    *        The `Player` that this class should be attached to.
5220    *
5221    * @param {Object} [options]
5222    *        The key/value store of player options.
5223    */
5224   function ChaptersTrackMenuItem(player, options) {
5225     _classCallCheck(this, ChaptersTrackMenuItem);
5226
5227     var track = options.track;
5228     var cue = options.cue;
5229     var currentTime = player.currentTime();
5230
5231     // Modify options for parent MenuItem class's init.
5232     options.selectable = true;
5233     options.label = cue.text;
5234     options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
5235
5236     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5237
5238     _this.track = track;
5239     _this.cue = cue;
5240     track.addEventListener('cuechange', Fn.bind(_this, _this.update));
5241     return _this;
5242   }
5243
5244   /**
5245    * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
5246    * {@link ClickableComponent} for more detailed information on what a click can be.
5247    *
5248    * @param {EventTarget~Event} [event]
5249    *        The `keydown`, `tap`, or `click` event that caused this function to be
5250    *        called.
5251    *
5252    * @listens tap
5253    * @listens click
5254    */
5255
5256
5257   ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
5258     _MenuItem.prototype.handleClick.call(this);
5259     this.player_.currentTime(this.cue.startTime);
5260     this.update(this.cue.startTime);
5261   };
5262
5263   /**
5264    * Update chapter menu item
5265    *
5266    * @param {EventTarget~Event} [event]
5267    *        The `cuechange` event that caused this function to run.
5268    *
5269    * @listens TextTrack#cuechange
5270    */
5271
5272
5273   ChaptersTrackMenuItem.prototype.update = function update(event) {
5274     var cue = this.cue;
5275     var currentTime = this.player_.currentTime();
5276
5277     // vjs.log(currentTime, cue.startTime);
5278     this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
5279   };
5280
5281   return ChaptersTrackMenuItem;
5282 }(_menuItem2['default']);
5283
5284 _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
5285 exports['default'] = ChaptersTrackMenuItem;
5286
5287 },{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){
5288 'use strict';
5289
5290 exports.__esModule = true;
5291
5292 var _textTrackButton = _dereq_(30);
5293
5294 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5295
5296 var _component = _dereq_(5);
5297
5298 var _component2 = _interopRequireDefault(_component);
5299
5300 var _fn = _dereq_(83);
5301
5302 var Fn = _interopRequireWildcard(_fn);
5303
5304 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; } }
5305
5306 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5307
5308 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5309
5310 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; }
5311
5312 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; } /**
5313                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file descriptions-button.js
5314                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5315
5316
5317 /**
5318  * The button component for toggling and selecting descriptions
5319  *
5320  * @extends TextTrackButton
5321  */
5322 var DescriptionsButton = function (_TextTrackButton) {
5323   _inherits(DescriptionsButton, _TextTrackButton);
5324
5325   /**
5326    * Creates an instance of this class.
5327    *
5328    * @param {Player} player
5329    *        The `Player` that this class should be attached to.
5330    *
5331    * @param {Object} [options]
5332    *        The key/value store of player options.
5333    *
5334    * @param {Component~ReadyCallback} [ready]
5335    *        The function to call when this component is ready.
5336    */
5337   function DescriptionsButton(player, options, ready) {
5338     _classCallCheck(this, DescriptionsButton);
5339
5340     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5341
5342     _this.el_.setAttribute('aria-label', 'Descriptions Menu');
5343
5344     var tracks = player.textTracks();
5345
5346     if (tracks) {
5347       var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5348
5349       tracks.addEventListener('change', changeHandler);
5350       _this.on('dispose', function () {
5351         tracks.removeEventListener('change', changeHandler);
5352       });
5353     }
5354     return _this;
5355   }
5356
5357   /**
5358    * Handle text track change
5359    *
5360    * @param {EventTarget~Event} event
5361    *        The event that caused this function to run
5362    *
5363    * @listens TextTrackList#change
5364    */
5365
5366
5367   DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
5368     var tracks = this.player().textTracks();
5369     var disabled = false;
5370
5371     // Check whether a track of a different kind is showing
5372     for (var i = 0, l = tracks.length; i < l; i++) {
5373       var track = tracks[i];
5374
5375       if (track.kind !== this.kind_ && track.mode === 'showing') {
5376         disabled = true;
5377         break;
5378       }
5379     }
5380
5381     // If another track is showing, disable this menu button
5382     if (disabled) {
5383       this.disable();
5384     } else {
5385       this.enable();
5386     }
5387   };
5388
5389   /**
5390    * Builds the default DOM `className`.
5391    *
5392    * @return {string}
5393    *         The DOM `className` for this object.
5394    */
5395
5396
5397   DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
5398     return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5399   };
5400
5401   return DescriptionsButton;
5402 }(_textTrackButton2['default']);
5403
5404 /**
5405  * `kind` of TextTrack to look for to associate it with this menu.
5406  *
5407  * @type {string}
5408  * @private
5409  */
5410
5411
5412 DescriptionsButton.prototype.kind_ = 'descriptions';
5413
5414 /**
5415  * The text that should display over the `DescriptionsButton`s controls. Added for localization.
5416  *
5417  * @type {string}
5418  * @private
5419  */
5420 DescriptionsButton.prototype.controlText_ = 'Descriptions';
5421
5422 _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
5423 exports['default'] = DescriptionsButton;
5424
5425 },{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){
5426 'use strict';
5427
5428 exports.__esModule = true;
5429
5430 var _textTrackMenuItem = _dereq_(31);
5431
5432 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5433
5434 var _component = _dereq_(5);
5435
5436 var _component2 = _interopRequireDefault(_component);
5437
5438 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5439
5440 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5441
5442 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; }
5443
5444 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; } /**
5445                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file off-text-track-menu-item.js
5446                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5447
5448
5449 /**
5450  * A special menu item for turning of a specific type of text track
5451  *
5452  * @extends TextTrackMenuItem
5453  */
5454 var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
5455   _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
5456
5457   /**
5458    * Creates an instance of this class.
5459    *
5460    * @param {Player} player
5461    *        The `Player` that this class should be attached to.
5462    *
5463    * @param {Object} [options]
5464    *        The key/value store of player options.
5465    */
5466   function OffTextTrackMenuItem(player, options) {
5467     _classCallCheck(this, OffTextTrackMenuItem);
5468
5469     // Create pseudo track info
5470     // Requires options['kind']
5471     options.track = {
5472       player: player,
5473       kind: options.kind,
5474       label: options.kind + ' off',
5475       'default': false,
5476       mode: 'disabled'
5477     };
5478
5479     // MenuItem is selectable
5480     options.selectable = true;
5481
5482     var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
5483
5484     _this.selected(true);
5485     return _this;
5486   }
5487
5488   /**
5489    * Handle text track change
5490    *
5491    * @param {EventTarget~Event} event
5492    *        The event that caused this function to run
5493    */
5494
5495
5496   OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5497     var tracks = this.player().textTracks();
5498     var selected = true;
5499
5500     for (var i = 0, l = tracks.length; i < l; i++) {
5501       var track = tracks[i];
5502
5503       if (track.kind === this.track.kind && track.mode === 'showing') {
5504         selected = false;
5505         break;
5506       }
5507     }
5508
5509     this.selected(selected);
5510   };
5511
5512   return OffTextTrackMenuItem;
5513 }(_textTrackMenuItem2['default']);
5514
5515 _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
5516 exports['default'] = OffTextTrackMenuItem;
5517
5518 },{"31":31,"5":5}],29:[function(_dereq_,module,exports){
5519 'use strict';
5520
5521 exports.__esModule = true;
5522
5523 var _textTrackButton = _dereq_(30);
5524
5525 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5526
5527 var _component = _dereq_(5);
5528
5529 var _component2 = _interopRequireDefault(_component);
5530
5531 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5532
5533 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5534
5535 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; }
5536
5537 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; } /**
5538                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file subtitles-button.js
5539                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5540
5541
5542 /**
5543  * The button component for toggling and selecting subtitles
5544  *
5545  * @extends TextTrackButton
5546  */
5547 var SubtitlesButton = function (_TextTrackButton) {
5548   _inherits(SubtitlesButton, _TextTrackButton);
5549
5550   /**
5551    * Creates an instance of this class.
5552    *
5553    * @param {Player} player
5554    *        The `Player` that this class should be attached to.
5555    *
5556    * @param {Object} [options]
5557    *        The key/value store of player options.
5558    *
5559    * @param {Component~ReadyCallback} [ready]
5560    *        The function to call when this component is ready.
5561    */
5562   function SubtitlesButton(player, options, ready) {
5563     _classCallCheck(this, SubtitlesButton);
5564
5565     var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5566
5567     _this.el_.setAttribute('aria-label', 'Subtitles Menu');
5568     return _this;
5569   }
5570
5571   /**
5572    * Builds the default DOM `className`.
5573    *
5574    * @return {string}
5575    *         The DOM `className` for this object.
5576    */
5577
5578
5579   SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
5580     return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5581   };
5582
5583   return SubtitlesButton;
5584 }(_textTrackButton2['default']);
5585
5586 /**
5587  * `kind` of TextTrack to look for to associate it with this menu.
5588  *
5589  * @type {string}
5590  * @private
5591  */
5592
5593
5594 SubtitlesButton.prototype.kind_ = 'subtitles';
5595
5596 /**
5597  * The text that should display over the `SubtitlesButton`s controls. Added for localization.
5598  *
5599  * @type {string}
5600  * @private
5601  */
5602 SubtitlesButton.prototype.controlText_ = 'Subtitles';
5603
5604 _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
5605 exports['default'] = SubtitlesButton;
5606
5607 },{"30":30,"5":5}],30:[function(_dereq_,module,exports){
5608 'use strict';
5609
5610 exports.__esModule = true;
5611
5612 var _trackButton = _dereq_(36);
5613
5614 var _trackButton2 = _interopRequireDefault(_trackButton);
5615
5616 var _component = _dereq_(5);
5617
5618 var _component2 = _interopRequireDefault(_component);
5619
5620 var _textTrackMenuItem = _dereq_(31);
5621
5622 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5623
5624 var _offTextTrackMenuItem = _dereq_(28);
5625
5626 var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
5627
5628 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5629
5630 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5631
5632 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; }
5633
5634 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; } /**
5635                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-button.js
5636                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5637
5638
5639 /**
5640  * The base class for buttons that toggle specific text track types (e.g. subtitles)
5641  *
5642  * @extends MenuButton
5643  */
5644 var TextTrackButton = function (_TrackButton) {
5645   _inherits(TextTrackButton, _TrackButton);
5646
5647   /**
5648    * Creates an instance of this class.
5649    *
5650    * @param {Player} player
5651    *        The `Player` that this class should be attached to.
5652    *
5653    * @param {Object} [options={}]
5654    *        The key/value store of player options.
5655    */
5656   function TextTrackButton(player) {
5657     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5658
5659     _classCallCheck(this, TextTrackButton);
5660
5661     options.tracks = player.textTracks();
5662
5663     return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
5664   }
5665
5666   /**
5667    * Create a menu item for each text track
5668    *
5669    * @param {TextTrackMenuItem[]} [items=[]]
5670    *        Existing array of items to use during creation
5671    *
5672    * @return {TextTrackMenuItem[]}
5673    *         Array of menu items that were created
5674    */
5675
5676
5677   TextTrackButton.prototype.createItems = function createItems() {
5678     var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5679
5680     // Add an OFF menu item to turn all tracks off
5681     items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
5682     this.hideThreshold_ += 1;
5683
5684     var tracks = this.player_.textTracks();
5685
5686     if (!tracks) {
5687       return items;
5688     }
5689
5690     for (var i = 0; i < tracks.length; i++) {
5691       var track = tracks[i];
5692
5693       // only add tracks that are of the appropriate kind and have a label
5694       if (track.kind === this.kind_) {
5695         items.push(new _textTrackMenuItem2['default'](this.player_, {
5696           track: track,
5697           // MenuItem is selectable
5698           selectable: true
5699         }));
5700       }
5701     }
5702
5703     return items;
5704   };
5705
5706   return TextTrackButton;
5707 }(_trackButton2['default']);
5708
5709 _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
5710 exports['default'] = TextTrackButton;
5711
5712 },{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){
5713 'use strict';
5714
5715 exports.__esModule = true;
5716
5717 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; };
5718
5719 var _menuItem = _dereq_(48);
5720
5721 var _menuItem2 = _interopRequireDefault(_menuItem);
5722
5723 var _component = _dereq_(5);
5724
5725 var _component2 = _interopRequireDefault(_component);
5726
5727 var _fn = _dereq_(83);
5728
5729 var Fn = _interopRequireWildcard(_fn);
5730
5731 var _window = _dereq_(95);
5732
5733 var _window2 = _interopRequireDefault(_window);
5734
5735 var _document = _dereq_(94);
5736
5737 var _document2 = _interopRequireDefault(_document);
5738
5739 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; } }
5740
5741 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5742
5743 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5744
5745 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; }
5746
5747 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; } /**
5748                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-menu-item.js
5749                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5750
5751
5752 /**
5753  * The specific menu item type for selecting a language within a text track kind
5754  *
5755  * @extends MenuItem
5756  */
5757 var TextTrackMenuItem = function (_MenuItem) {
5758   _inherits(TextTrackMenuItem, _MenuItem);
5759
5760   /**
5761    * Creates an instance of this class.
5762    *
5763    * @param {Player} player
5764    *        The `Player` that this class should be attached to.
5765    *
5766    * @param {Object} [options]
5767    *        The key/value store of player options.
5768    */
5769   function TextTrackMenuItem(player, options) {
5770     _classCallCheck(this, TextTrackMenuItem);
5771
5772     var track = options.track;
5773     var tracks = player.textTracks();
5774
5775     // Modify options for parent MenuItem class's init.
5776     options.label = track.label || track.language || 'Unknown';
5777     options.selected = track['default'] || track.mode === 'showing';
5778
5779     var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5780
5781     _this.track = track;
5782
5783     if (tracks) {
5784       var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5785
5786       player.on(['loadstart', 'texttrackchange'], changeHandler);
5787       tracks.addEventListener('change', changeHandler);
5788       _this.on('dispose', function () {
5789         tracks.removeEventListener('change', changeHandler);
5790       });
5791     }
5792
5793     // iOS7 doesn't dispatch change events to TextTrackLists when an
5794     // associated track's mode changes. Without something like
5795     // Object.observe() (also not present on iOS7), it's not
5796     // possible to detect changes to the mode attribute and polyfill
5797     // the change event. As a poor substitute, we manually dispatch
5798     // change events whenever the controls modify the mode.
5799     if (tracks && tracks.onchange === undefined) {
5800       var event = void 0;
5801
5802       _this.on(['tap', 'click'], function () {
5803         if (_typeof(_window2['default'].Event) !== 'object') {
5804           // Android 2.3 throws an Illegal Constructor error for window.Event
5805           try {
5806             event = new _window2['default'].Event('change');
5807           } catch (err) {
5808             // continue regardless of error
5809           }
5810         }
5811
5812         if (!event) {
5813           event = _document2['default'].createEvent('Event');
5814           event.initEvent('change', true, true);
5815         }
5816
5817         tracks.dispatchEvent(event);
5818       });
5819     }
5820     return _this;
5821   }
5822
5823   /**
5824    * This gets called when an `TextTrackMenuItem` is "clicked". See
5825    * {@link ClickableComponent} for more detailed information on what a click can be.
5826    *
5827    * @param {EventTarget~Event} event
5828    *        The `keydown`, `tap`, or `click` event that caused this function to be
5829    *        called.
5830    *
5831    * @listens tap
5832    * @listens click
5833    */
5834
5835
5836   TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
5837     var kind = this.track.kind;
5838     var tracks = this.player_.textTracks();
5839
5840     _MenuItem.prototype.handleClick.call(this, event);
5841
5842     if (!tracks) {
5843       return;
5844     }
5845
5846     for (var i = 0; i < tracks.length; i++) {
5847       var track = tracks[i];
5848
5849       if (track.kind !== kind) {
5850         continue;
5851       }
5852
5853       if (track === this.track) {
5854         track.mode = 'showing';
5855       } else {
5856         track.mode = 'disabled';
5857       }
5858     }
5859   };
5860
5861   /**
5862    * Handle text track list change
5863    *
5864    * @param {EventTarget~Event} event
5865    *        The `change` event that caused this function to be called.
5866    *
5867    * @listens TextTrackList#change
5868    */
5869
5870
5871   TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5872     this.selected(this.track.mode === 'showing');
5873   };
5874
5875   return TextTrackMenuItem;
5876 }(_menuItem2['default']);
5877
5878 _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
5879 exports['default'] = TextTrackMenuItem;
5880
5881 },{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){
5882 'use strict';
5883
5884 exports.__esModule = true;
5885
5886 var _component = _dereq_(5);
5887
5888 var _component2 = _interopRequireDefault(_component);
5889
5890 var _dom = _dereq_(81);
5891
5892 var Dom = _interopRequireWildcard(_dom);
5893
5894 var _formatTime = _dereq_(84);
5895
5896 var _formatTime2 = _interopRequireDefault(_formatTime);
5897
5898 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; } }
5899
5900 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5901
5902 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5903
5904 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; }
5905
5906 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; } /**
5907                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file current-time-display.js
5908                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
5909
5910
5911 /**
5912  * Displays the current time
5913  *
5914  * @extends Component
5915  */
5916 var CurrentTimeDisplay = function (_Component) {
5917   _inherits(CurrentTimeDisplay, _Component);
5918
5919   /**
5920    * Creates an instance of this class.
5921    *
5922    * @param {Player} player
5923    *        The `Player` that this class should be attached to.
5924    *
5925    * @param {Object} [options]
5926    *        The key/value store of player options.
5927    */
5928   function CurrentTimeDisplay(player, options) {
5929     _classCallCheck(this, CurrentTimeDisplay);
5930
5931     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
5932
5933     _this.on(player, 'timeupdate', _this.updateContent);
5934     return _this;
5935   }
5936
5937   /**
5938    * Create the `Component`'s DOM element
5939    *
5940    * @return {Element}
5941    *         The element that was created.
5942    */
5943
5944
5945   CurrentTimeDisplay.prototype.createEl = function createEl() {
5946     var el = _Component.prototype.createEl.call(this, 'div', {
5947       className: 'vjs-current-time vjs-time-control vjs-control'
5948     });
5949
5950     this.contentEl_ = Dom.createEl('div', {
5951       className: 'vjs-current-time-display',
5952       // label the current time for screen reader users
5953       innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
5954     }, {
5955       // tell screen readers not to automatically read the time as it changes
5956       'aria-live': 'off'
5957     });
5958
5959     el.appendChild(this.contentEl_);
5960     return el;
5961   };
5962
5963   /**
5964    * Update current time display
5965    *
5966    * @param {EventTarget~Event} [event]
5967    *        The `timeupdate` event that caused this function to run.
5968    *
5969    * @listens Player#timeupdate
5970    */
5971
5972
5973   CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
5974     // Allows for smooth scrubbing, when player can't keep up.
5975     var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5976     var localizedText = this.localize('Current Time');
5977     var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
5978
5979     if (formattedTime !== this.formattedTime_) {
5980       this.formattedTime_ = formattedTime;
5981       this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
5982     }
5983   };
5984
5985   return CurrentTimeDisplay;
5986 }(_component2['default']);
5987
5988 _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
5989 exports['default'] = CurrentTimeDisplay;
5990
5991 },{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){
5992 'use strict';
5993
5994 exports.__esModule = true;
5995
5996 var _component = _dereq_(5);
5997
5998 var _component2 = _interopRequireDefault(_component);
5999
6000 var _dom = _dereq_(81);
6001
6002 var Dom = _interopRequireWildcard(_dom);
6003
6004 var _formatTime = _dereq_(84);
6005
6006 var _formatTime2 = _interopRequireDefault(_formatTime);
6007
6008 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; } }
6009
6010 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6011
6012 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6013
6014 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; }
6015
6016 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; } /**
6017                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file duration-display.js
6018                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6019
6020
6021 /**
6022  * Displays the duration
6023  *
6024  * @extends Component
6025  */
6026 var DurationDisplay = function (_Component) {
6027   _inherits(DurationDisplay, _Component);
6028
6029   /**
6030    * Creates an instance of this class.
6031    *
6032    * @param {Player} player
6033    *        The `Player` that this class should be attached to.
6034    *
6035    * @param {Object} [options]
6036    *        The key/value store of player options.
6037    */
6038   function DurationDisplay(player, options) {
6039     _classCallCheck(this, DurationDisplay);
6040
6041     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6042
6043     _this.on(player, 'durationchange', _this.updateContent);
6044
6045     // Also listen for timeupdate and loadedmetadata because removing those
6046     // listeners could have broken dependent applications/libraries. These
6047     // can likely be removed for 6.0.
6048     _this.on(player, 'timeupdate', _this.updateContent);
6049     _this.on(player, 'loadedmetadata', _this.updateContent);
6050     return _this;
6051   }
6052
6053   /**
6054    * Create the `Component`'s DOM element
6055    *
6056    * @return {Element}
6057    *         The element that was created.
6058    */
6059
6060
6061   DurationDisplay.prototype.createEl = function createEl() {
6062     var el = _Component.prototype.createEl.call(this, 'div', {
6063       className: 'vjs-duration vjs-time-control vjs-control'
6064     });
6065
6066     this.contentEl_ = Dom.createEl('div', {
6067       className: 'vjs-duration-display',
6068       // label the duration time for screen reader users
6069       innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
6070     }, {
6071       // tell screen readers not to automatically read the time as it changes
6072       'aria-live': 'off'
6073     });
6074
6075     el.appendChild(this.contentEl_);
6076     return el;
6077   };
6078
6079   /**
6080    * Update duration time display.
6081    *
6082    * @param {EventTarget~Event} [event]
6083    *        The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
6084    *        this function to be called.
6085    *
6086    * @listens Player#durationchange
6087    * @listens Player#timeupdate
6088    * @listens Player#loadedmetadata
6089    */
6090
6091
6092   DurationDisplay.prototype.updateContent = function updateContent(event) {
6093     var duration = this.player_.duration();
6094
6095     if (duration && this.duration_ !== duration) {
6096       this.duration_ = duration;
6097       var localizedText = this.localize('Duration Time');
6098       var formattedTime = (0, _formatTime2['default'])(duration);
6099
6100       // label the duration time for screen reader users
6101       this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
6102     }
6103   };
6104
6105   return DurationDisplay;
6106 }(_component2['default']);
6107
6108 _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
6109 exports['default'] = DurationDisplay;
6110
6111 },{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){
6112 'use strict';
6113
6114 exports.__esModule = true;
6115
6116 var _component = _dereq_(5);
6117
6118 var _component2 = _interopRequireDefault(_component);
6119
6120 var _dom = _dereq_(81);
6121
6122 var Dom = _interopRequireWildcard(_dom);
6123
6124 var _formatTime = _dereq_(84);
6125
6126 var _formatTime2 = _interopRequireDefault(_formatTime);
6127
6128 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; } }
6129
6130 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6131
6132 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6133
6134 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; }
6135
6136 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; } /**
6137                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file remaining-time-display.js
6138                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6139
6140
6141 /**
6142  * Displays the time left in the video
6143  *
6144  * @extends Component
6145  */
6146 var RemainingTimeDisplay = function (_Component) {
6147   _inherits(RemainingTimeDisplay, _Component);
6148
6149   /**
6150    * Creates an instance of this class.
6151    *
6152    * @param {Player} player
6153    *        The `Player` that this class should be attached to.
6154    *
6155    * @param {Object} [options]
6156    *        The key/value store of player options.
6157    */
6158   function RemainingTimeDisplay(player, options) {
6159     _classCallCheck(this, RemainingTimeDisplay);
6160
6161     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6162
6163     _this.on(player, 'timeupdate', _this.updateContent);
6164     _this.on(player, 'durationchange', _this.updateContent);
6165     return _this;
6166   }
6167
6168   /**
6169    * Create the `Component`'s DOM element
6170    *
6171    * @return {Element}
6172    *         The element that was created.
6173    */
6174
6175
6176   RemainingTimeDisplay.prototype.createEl = function createEl() {
6177     var el = _Component.prototype.createEl.call(this, 'div', {
6178       className: 'vjs-remaining-time vjs-time-control vjs-control'
6179     });
6180
6181     this.contentEl_ = Dom.createEl('div', {
6182       className: 'vjs-remaining-time-display',
6183       // label the remaining time for screen reader users
6184       innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
6185     }, {
6186       // tell screen readers not to automatically read the time as it changes
6187       'aria-live': 'off'
6188     });
6189
6190     el.appendChild(this.contentEl_);
6191     return el;
6192   };
6193
6194   /**
6195    * Update remaining time display.
6196    *
6197    * @param {EventTarget~Event} [event]
6198    *        The `timeupdate` or `durationchange` event that caused this to run.
6199    *
6200    * @listens Player#timeupdate
6201    * @listens Player#durationchange
6202    */
6203
6204
6205   RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
6206     if (this.player_.duration()) {
6207       var localizedText = this.localize('Remaining Time');
6208       var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
6209
6210       if (formattedTime !== this.formattedTime_) {
6211         this.formattedTime_ = formattedTime;
6212         this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
6213       }
6214     }
6215
6216     // Allows for smooth scrubbing, when player can't keep up.
6217     // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
6218     // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
6219   };
6220
6221   return RemainingTimeDisplay;
6222 }(_component2['default']);
6223
6224 _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
6225 exports['default'] = RemainingTimeDisplay;
6226
6227 },{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){
6228 'use strict';
6229
6230 exports.__esModule = true;
6231
6232 var _component = _dereq_(5);
6233
6234 var _component2 = _interopRequireDefault(_component);
6235
6236 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6237
6238 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6239
6240 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; }
6241
6242 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; } /**
6243                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file time-divider.js
6244                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6245
6246
6247 /**
6248  * The separator between the current time and duration.
6249  * Can be hidden if it's not needed in the design.
6250  *
6251  * @extends Component
6252  */
6253 var TimeDivider = function (_Component) {
6254   _inherits(TimeDivider, _Component);
6255
6256   function TimeDivider() {
6257     _classCallCheck(this, TimeDivider);
6258
6259     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6260   }
6261
6262   /**
6263    * Create the component's DOM element
6264    *
6265    * @return {Element}
6266    *         The element that was created.
6267    */
6268   TimeDivider.prototype.createEl = function createEl() {
6269     return _Component.prototype.createEl.call(this, 'div', {
6270       className: 'vjs-time-control vjs-time-divider',
6271       innerHTML: '<div><span>/</span></div>'
6272     });
6273   };
6274
6275   return TimeDivider;
6276 }(_component2['default']);
6277
6278 _component2['default'].registerComponent('TimeDivider', TimeDivider);
6279 exports['default'] = TimeDivider;
6280
6281 },{"5":5}],36:[function(_dereq_,module,exports){
6282 'use strict';
6283
6284 exports.__esModule = true;
6285
6286 var _menuButton = _dereq_(47);
6287
6288 var _menuButton2 = _interopRequireDefault(_menuButton);
6289
6290 var _component = _dereq_(5);
6291
6292 var _component2 = _interopRequireDefault(_component);
6293
6294 var _fn = _dereq_(83);
6295
6296 var Fn = _interopRequireWildcard(_fn);
6297
6298 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; } }
6299
6300 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6301
6302 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6303
6304 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; }
6305
6306 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; } /**
6307                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track-button.js
6308                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6309
6310
6311 /**
6312  * The base class for buttons that toggle specific  track types (e.g. subtitles).
6313  *
6314  * @extends MenuButton
6315  */
6316 var TrackButton = function (_MenuButton) {
6317   _inherits(TrackButton, _MenuButton);
6318
6319   /**
6320    * Creates an instance of this class.
6321    *
6322    * @param {Player} player
6323    *        The `Player` that this class should be attached to.
6324    *
6325    * @param {Object} [options]
6326    *        The key/value store of player options.
6327    */
6328   function TrackButton(player, options) {
6329     _classCallCheck(this, TrackButton);
6330
6331     var tracks = options.tracks;
6332
6333     var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
6334
6335     if (_this.items.length <= 1) {
6336       _this.hide();
6337     }
6338
6339     if (!tracks) {
6340       return _possibleConstructorReturn(_this);
6341     }
6342
6343     var updateHandler = Fn.bind(_this, _this.update);
6344
6345     tracks.addEventListener('removetrack', updateHandler);
6346     tracks.addEventListener('addtrack', updateHandler);
6347
6348     _this.player_.on('dispose', function () {
6349       tracks.removeEventListener('removetrack', updateHandler);
6350       tracks.removeEventListener('addtrack', updateHandler);
6351     });
6352     return _this;
6353   }
6354
6355   return TrackButton;
6356 }(_menuButton2['default']);
6357
6358 _component2['default'].registerComponent('TrackButton', TrackButton);
6359 exports['default'] = TrackButton;
6360
6361 },{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){
6362 'use strict';
6363
6364 exports.__esModule = true;
6365
6366 var _slider = _dereq_(57);
6367
6368 var _slider2 = _interopRequireDefault(_slider);
6369
6370 var _component = _dereq_(5);
6371
6372 var _component2 = _interopRequireDefault(_component);
6373
6374 var _fn = _dereq_(83);
6375
6376 var Fn = _interopRequireWildcard(_fn);
6377
6378 _dereq_(39);
6379
6380 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; } }
6381
6382 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6383
6384 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6385
6386 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; }
6387
6388 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; } /**
6389                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-bar.js
6390                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6391
6392
6393 // Required children
6394
6395
6396 /**
6397  * The bar that contains the volume level and can be clicked on to adjust the level
6398  *
6399  * @extends Slider
6400  */
6401 var VolumeBar = function (_Slider) {
6402   _inherits(VolumeBar, _Slider);
6403
6404   /**
6405    * Creates an instance of this class.
6406    *
6407    * @param {Player} player
6408    *        The `Player` that this class should be attached to.
6409    *
6410    * @param {Object} [options]
6411    *        The key/value store of player options.
6412    */
6413   function VolumeBar(player, options) {
6414     _classCallCheck(this, VolumeBar);
6415
6416     var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
6417
6418     _this.on(player, 'volumechange', _this.updateARIAAttributes);
6419     player.ready(Fn.bind(_this, _this.updateARIAAttributes));
6420     return _this;
6421   }
6422
6423   /**
6424    * Create the `Component`'s DOM element
6425    *
6426    * @return {Element}
6427    *         The element that was created.
6428    */
6429
6430
6431   VolumeBar.prototype.createEl = function createEl() {
6432     return _Slider.prototype.createEl.call(this, 'div', {
6433       className: 'vjs-volume-bar vjs-slider-bar'
6434     }, {
6435       'aria-label': 'volume level'
6436     });
6437   };
6438
6439   /**
6440    * Handle movement events on the {@link VolumeMenuButton}.
6441    *
6442    * @param {EventTarget~Event} event
6443    *        The event that caused this function to run.
6444    *
6445    * @listens mousemove
6446    */
6447
6448
6449   VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
6450     this.checkMuted();
6451     this.player_.volume(this.calculateDistance(event));
6452   };
6453
6454   /**
6455    * If the player is muted unmute it.
6456    */
6457
6458
6459   VolumeBar.prototype.checkMuted = function checkMuted() {
6460     if (this.player_.muted()) {
6461       this.player_.muted(false);
6462     }
6463   };
6464
6465   /**
6466    * Get percent of volume level
6467    *
6468    * @return {number}
6469    *         Volume level percent as a decimal number.
6470    */
6471
6472
6473   VolumeBar.prototype.getPercent = function getPercent() {
6474     if (this.player_.muted()) {
6475       return 0;
6476     }
6477     return this.player_.volume();
6478   };
6479
6480   /**
6481    * Increase volume level for keyboard users
6482    */
6483
6484
6485   VolumeBar.prototype.stepForward = function stepForward() {
6486     this.checkMuted();
6487     this.player_.volume(this.player_.volume() + 0.1);
6488   };
6489
6490   /**
6491    * Decrease volume level for keyboard users
6492    */
6493
6494
6495   VolumeBar.prototype.stepBack = function stepBack() {
6496     this.checkMuted();
6497     this.player_.volume(this.player_.volume() - 0.1);
6498   };
6499
6500   /**
6501    * Update ARIA accessibility attributes
6502    *
6503    * @param {EventTarget~Event} [event]
6504    *        The `volumechange` event that caused this function to run.
6505    *
6506    * @listens Player#volumechange
6507    */
6508
6509
6510   VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
6511     // Current value of volume bar as a percentage
6512     var volume = (this.player_.volume() * 100).toFixed(2);
6513
6514     this.el_.setAttribute('aria-valuenow', volume);
6515     this.el_.setAttribute('aria-valuetext', volume + '%');
6516   };
6517
6518   return VolumeBar;
6519 }(_slider2['default']);
6520
6521 /**
6522  * Default options for the `VolumeBar`
6523  *
6524  * @type {Object}
6525  * @private
6526  */
6527
6528
6529 VolumeBar.prototype.options_ = {
6530   children: ['volumeLevel'],
6531   barName: 'volumeLevel'
6532 };
6533
6534 /**
6535  * Call the update event for this Slider when this event happens on the player.
6536  *
6537  * @type {string}
6538  */
6539 VolumeBar.prototype.playerEvent = 'volumechange';
6540
6541 _component2['default'].registerComponent('VolumeBar', VolumeBar);
6542 exports['default'] = VolumeBar;
6543
6544 },{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){
6545 'use strict';
6546
6547 exports.__esModule = true;
6548
6549 var _component = _dereq_(5);
6550
6551 var _component2 = _interopRequireDefault(_component);
6552
6553 _dereq_(37);
6554
6555 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6556
6557 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6558
6559 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; }
6560
6561 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; } /**
6562                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-control.js
6563                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6564
6565
6566 // Required children
6567
6568
6569 /**
6570  * The component for controlling the volume level
6571  *
6572  * @extends Component
6573  */
6574 var VolumeControl = function (_Component) {
6575   _inherits(VolumeControl, _Component);
6576
6577   /**
6578    * Creates an instance of this class.
6579    *
6580    * @param {Player} player
6581    *        The `Player` that this class should be attached to.
6582    *
6583    * @param {Object} [options={}]
6584    *        The key/value store of player options.
6585    */
6586   function VolumeControl(player, options) {
6587     _classCallCheck(this, VolumeControl);
6588
6589     // hide volume controls when they're not supported by the current tech
6590     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6591
6592     if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6593       _this.addClass('vjs-hidden');
6594     }
6595     _this.on(player, 'loadstart', function () {
6596       if (player.tech_.featuresVolumeControl === false) {
6597         this.addClass('vjs-hidden');
6598       } else {
6599         this.removeClass('vjs-hidden');
6600       }
6601     });
6602     return _this;
6603   }
6604
6605   /**
6606    * Create the `Component`'s DOM element
6607    *
6608    * @return {Element}
6609    *         The element that was created.
6610    */
6611
6612
6613   VolumeControl.prototype.createEl = function createEl() {
6614     return _Component.prototype.createEl.call(this, 'div', {
6615       className: 'vjs-volume-control vjs-control'
6616     });
6617   };
6618
6619   return VolumeControl;
6620 }(_component2['default']);
6621
6622 /**
6623  * Default options for the `VolumeControl`
6624  *
6625  * @type {Object}
6626  * @private
6627  */
6628
6629
6630 VolumeControl.prototype.options_ = {
6631   children: ['volumeBar']
6632 };
6633
6634 _component2['default'].registerComponent('VolumeControl', VolumeControl);
6635 exports['default'] = VolumeControl;
6636
6637 },{"37":37,"5":5}],39:[function(_dereq_,module,exports){
6638 'use strict';
6639
6640 exports.__esModule = true;
6641
6642 var _component = _dereq_(5);
6643
6644 var _component2 = _interopRequireDefault(_component);
6645
6646 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6647
6648 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6649
6650 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; }
6651
6652 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; } /**
6653                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-level.js
6654                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6655
6656
6657 /**
6658  * Shows volume level
6659  *
6660  * @extends Component
6661  */
6662 var VolumeLevel = function (_Component) {
6663   _inherits(VolumeLevel, _Component);
6664
6665   function VolumeLevel() {
6666     _classCallCheck(this, VolumeLevel);
6667
6668     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6669   }
6670
6671   /**
6672    * Create the `Component`'s DOM element
6673    *
6674    * @return {Element}
6675    *         The element that was created.
6676    */
6677   VolumeLevel.prototype.createEl = function createEl() {
6678     return _Component.prototype.createEl.call(this, 'div', {
6679       className: 'vjs-volume-level',
6680       innerHTML: '<span class="vjs-control-text"></span>'
6681     });
6682   };
6683
6684   return VolumeLevel;
6685 }(_component2['default']);
6686
6687 _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
6688 exports['default'] = VolumeLevel;
6689
6690 },{"5":5}],40:[function(_dereq_,module,exports){
6691 'use strict';
6692
6693 exports.__esModule = true;
6694
6695 var _fn = _dereq_(83);
6696
6697 var Fn = _interopRequireWildcard(_fn);
6698
6699 var _component = _dereq_(5);
6700
6701 var _component2 = _interopRequireDefault(_component);
6702
6703 var _popup = _dereq_(54);
6704
6705 var _popup2 = _interopRequireDefault(_popup);
6706
6707 var _popupButton = _dereq_(53);
6708
6709 var _popupButton2 = _interopRequireDefault(_popupButton);
6710
6711 var _muteToggle = _dereq_(11);
6712
6713 var _muteToggle2 = _interopRequireDefault(_muteToggle);
6714
6715 var _volumeBar = _dereq_(37);
6716
6717 var _volumeBar2 = _interopRequireDefault(_volumeBar);
6718
6719 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6720
6721 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; } }
6722
6723 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6724
6725 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; }
6726
6727 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; } /**
6728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file volume-menu-button.js
6729                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6730
6731
6732 /**
6733  * Button for volume popup
6734  *
6735  * @extends PopupButton
6736  */
6737 var VolumeMenuButton = function (_PopupButton) {
6738   _inherits(VolumeMenuButton, _PopupButton);
6739
6740   /**
6741    * Creates an instance of this class.
6742    *
6743    * @param {Player} player
6744    *        The `Player` that this class should be attached to.
6745    *
6746    * @param {Object} [options={}]
6747    *        The key/value store of player options.
6748    */
6749   function VolumeMenuButton(player) {
6750     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6751
6752     _classCallCheck(this, VolumeMenuButton);
6753
6754     // Default to inline
6755     if (options.inline === undefined) {
6756       options.inline = true;
6757     }
6758
6759     // If the vertical option isn't passed at all, default to true.
6760     if (options.vertical === undefined) {
6761       // If an inline volumeMenuButton is used, we should default to using
6762       // a horizontal slider for obvious reasons.
6763       if (options.inline) {
6764         options.vertical = false;
6765       } else {
6766         options.vertical = true;
6767       }
6768     }
6769
6770     // The vertical option needs to be set on the volumeBar as well,
6771     // since that will need to be passed along to the VolumeBar constructor
6772     options.volumeBar = options.volumeBar || {};
6773     options.volumeBar.vertical = !!options.vertical;
6774
6775     // Same listeners as MuteToggle
6776     var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
6777
6778     _this.on(player, 'volumechange', _this.volumeUpdate);
6779     _this.on(player, 'loadstart', _this.volumeUpdate);
6780
6781     // hide mute toggle if the current tech doesn't support volume control
6782     function updateVisibility() {
6783       if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6784         this.addClass('vjs-hidden');
6785       } else {
6786         this.removeClass('vjs-hidden');
6787       }
6788     }
6789
6790     updateVisibility.call(_this);
6791     _this.on(player, 'loadstart', updateVisibility);
6792
6793     _this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
6794       this.addClass('vjs-slider-active');
6795     });
6796
6797     _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
6798       this.removeClass('vjs-slider-active');
6799     });
6800
6801     _this.on(_this.volumeBar, ['focus'], function () {
6802       this.addClass('vjs-lock-showing');
6803     });
6804
6805     _this.on(_this.volumeBar, ['blur'], function () {
6806       this.removeClass('vjs-lock-showing');
6807     });
6808     return _this;
6809   }
6810
6811   /**
6812    * Builds the default DOM `className`.
6813    *
6814    * @return {string}
6815    *         The DOM `className` for this object.
6816    */
6817
6818
6819   VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
6820     var orientationClass = '';
6821
6822     if (this.options_.vertical) {
6823       orientationClass = 'vjs-volume-menu-button-vertical';
6824     } else {
6825       orientationClass = 'vjs-volume-menu-button-horizontal';
6826     }
6827
6828     return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
6829   };
6830
6831   /**
6832    * Create the VolumeMenuButton popup
6833    *
6834    * @return {Popup}
6835    *         The popup that was created
6836    */
6837
6838
6839   VolumeMenuButton.prototype.createPopup = function createPopup() {
6840     var popup = new _popup2['default'](this.player_, {
6841       contentElType: 'div'
6842     });
6843
6844     var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
6845
6846     popup.addChild(vb);
6847
6848     this.menuContent = popup;
6849     this.volumeBar = vb;
6850
6851     this.attachVolumeBarEvents();
6852
6853     return popup;
6854   };
6855
6856   /**
6857    * This gets called when an `VolumeMenuButton` is "clicked". See
6858    * {@link ClickableComponent} for more detailed information on what a click can be.
6859    *
6860    * @param {EventTarget~Event} [event]
6861    *        The `keydown`, `tap`, or `click` event that caused this function to be
6862    *        called.
6863    *
6864    * @listens tap
6865    * @listens click
6866    */
6867
6868
6869   VolumeMenuButton.prototype.handleClick = function handleClick(event) {
6870     _muteToggle2['default'].prototype.handleClick.call(this);
6871     _PopupButton.prototype.handleClick.call(this);
6872   };
6873
6874   /**
6875    * Add events listeners to the created `VolumeBar`.
6876    */
6877
6878
6879   VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
6880     this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
6881   };
6882
6883   /**
6884    * Handle the `mousedown` and `touchdown` events on the `VolumeBar`
6885    *
6886    * @param {EventTarget~Event} [event]
6887    *        The `mousedown` or `touchdown` event that caused this to run.
6888    *
6889    * @listens mousedown
6890    * @listens touchdown
6891    */
6892
6893
6894   VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
6895     this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6896     this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
6897   };
6898
6899   /**
6900    * Handle the `mouseup` and `touchend` events on the `VolumeBar`
6901    *
6902    * @param {EventTarget~Event} [event]
6903    *        The `mouseup` or `touchend` event that caused this to run.
6904    *
6905    * @listens mouseup
6906    * @listens touchend
6907    */
6908
6909
6910   VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
6911     this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6912   };
6913
6914   return VolumeMenuButton;
6915 }(_popupButton2['default']);
6916
6917 /**
6918  * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
6919  */
6920
6921
6922 VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
6923
6924 /**
6925  * The text that should display over the `VolumeMenuButton`s controls. Added for localization.
6926  *
6927  * @type {string}
6928  * @private
6929  */
6930 VolumeMenuButton.prototype.controlText_ = 'Mute';
6931
6932 _component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
6933 exports['default'] = VolumeMenuButton;
6934
6935 },{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){
6936 'use strict';
6937
6938 exports.__esModule = true;
6939
6940 var _component = _dereq_(5);
6941
6942 var _component2 = _interopRequireDefault(_component);
6943
6944 var _modalDialog = _dereq_(50);
6945
6946 var _modalDialog2 = _interopRequireDefault(_modalDialog);
6947
6948 var _mergeOptions = _dereq_(87);
6949
6950 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
6951
6952 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6953
6954 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6955
6956 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; }
6957
6958 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; } /**
6959                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file error-display.js
6960                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
6961
6962
6963 /**
6964  * A display that indicates an error has occurred. This means that the video
6965  * is unplayable.
6966  *
6967  * @extends ModalDialog
6968  */
6969 var ErrorDisplay = function (_ModalDialog) {
6970   _inherits(ErrorDisplay, _ModalDialog);
6971
6972   /**
6973    * Creates an instance of this class.
6974    *
6975    * @param  {Player} player
6976    *         The `Player` that this class should be attached to.
6977    *
6978    * @param  {Object} [options]
6979    *         The key/value store of player options.
6980    */
6981   function ErrorDisplay(player, options) {
6982     _classCallCheck(this, ErrorDisplay);
6983
6984     var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
6985
6986     _this.on(player, 'error', _this.open);
6987     return _this;
6988   }
6989
6990   /**
6991    * Builds the default DOM `className`.
6992    *
6993    * @return {string}
6994    *         The DOM `className` for this object.
6995    *
6996    * @deprecated Since version 5.
6997    */
6998
6999
7000   ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
7001     return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
7002   };
7003
7004   /**
7005    * Gets the localized error message based on the `Player`s error.
7006    *
7007    * @return {string}
7008    *         The `Player`s error message localized or an empty string.
7009    */
7010
7011
7012   ErrorDisplay.prototype.content = function content() {
7013     var error = this.player().error();
7014
7015     return error ? this.localize(error.message) : '';
7016   };
7017
7018   return ErrorDisplay;
7019 }(_modalDialog2['default']);
7020
7021 /**
7022  * The default options for an `ErrorDisplay`.
7023  *
7024  * @private
7025  */
7026
7027
7028 ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
7029   pauseOnOpen: false,
7030   fillAlways: true,
7031   temporary: false,
7032   uncloseable: true
7033 });
7034
7035 _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
7036 exports['default'] = ErrorDisplay;
7037
7038 },{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){
7039 'use strict';
7040
7041 exports.__esModule = true;
7042
7043 var _events = _dereq_(82);
7044
7045 var Events = _interopRequireWildcard(_events);
7046
7047 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; } }
7048
7049 /**
7050  * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
7051  * adds shorthand functions that wrap around lengthy functions. For example:
7052  * the `on` function is a wrapper around `addEventListener`.
7053  *
7054  * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
7055  * @class EventTarget
7056  */
7057 var EventTarget = function EventTarget() {};
7058
7059 /**
7060  * A Custom DOM event.
7061  *
7062  * @typedef {Object} EventTarget~Event
7063  * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
7064  */
7065
7066 /**
7067  * All event listeners should follow the following format.
7068  *
7069  * @callback EventTarget~EventListener
7070  * @this {EventTarget}
7071  *
7072  * @param {EventTarget~Event} event
7073  *        the event that triggered this function
7074  *
7075  * @param {Object} [hash]
7076  *        hash of data sent during the event
7077  */
7078
7079 /**
7080  * An object containing event names as keys and booleans as values.
7081  *
7082  * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
7083  *         will have extra functionality. See that function for more information.
7084  *
7085  * @property EventTarget.prototype.allowedEvents_
7086  * @private
7087  */
7088 /**
7089  * @file src/js/event-target.js
7090  */
7091 EventTarget.prototype.allowedEvents_ = {};
7092
7093 /**
7094  * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
7095  * function that will get called when an event with a certain name gets triggered.
7096  *
7097  * @param {string|string[]} type
7098  *        An event name or an array of event names.
7099  *
7100  * @param {EventTarget~EventListener} fn
7101  *        The function to call with `EventTarget`s
7102  */
7103 EventTarget.prototype.on = function (type, fn) {
7104   // Remove the addEventListener alias before calling Events.on
7105   // so we don't get into an infinite type loop
7106   var ael = this.addEventListener;
7107
7108   this.addEventListener = function () {};
7109   Events.on(this, type, fn);
7110   this.addEventListener = ael;
7111 };
7112
7113 /**
7114  * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
7115  * the standard DOM API.
7116  *
7117  * @function
7118  * @see {@link EventTarget#on}
7119  */
7120 EventTarget.prototype.addEventListener = EventTarget.prototype.on;
7121
7122 /**
7123  * Removes an `event listener` for a specific event from an instance of `EventTarget`.
7124  * This makes it so that the `event listener` will no longer get called when the
7125  * named event happens.
7126  *
7127  * @param {string|string[]} type
7128  *        An event name or an array of event names.
7129  *
7130  * @param {EventTarget~EventListener} fn
7131  *        The function to remove.
7132  */
7133 EventTarget.prototype.off = function (type, fn) {
7134   Events.off(this, type, fn);
7135 };
7136
7137 /**
7138  * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
7139  * the standard DOM API.
7140  *
7141  * @function
7142  * @see {@link EventTarget#off}
7143  */
7144 EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
7145
7146 /**
7147  * This function will add an `event listener` that gets triggered only once. After the
7148  * first trigger it will get removed. This is like adding an `event listener`
7149  * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
7150  *
7151  * @param {string|string[]} type
7152  *        An event name or an array of event names.
7153  *
7154  * @param {EventTarget~EventListener} fn
7155  *        The function to be called once for each event name.
7156  */
7157 EventTarget.prototype.one = function (type, fn) {
7158   // Remove the addEventListener alialing Events.on
7159   // so we don't get into an infinite type loop
7160   var ael = this.addEventListener;
7161
7162   this.addEventListener = function () {};
7163   Events.one(this, type, fn);
7164   this.addEventListener = ael;
7165 };
7166
7167 /**
7168  * This function causes an event to happen. This will then cause any `event listeners`
7169  * that are waiting for that event, to get called. If there are no `event listeners`
7170  * for an event then nothing will happen.
7171  *
7172  * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
7173  * Trigger will also call the `on` + `uppercaseEventName` function.
7174  *
7175  * Example:
7176  * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
7177  * `onClick` if it exists.
7178  *
7179  * @param {string|EventTarget~Event|Object} event
7180  *        The name of the event, an `Event`, or an object with a key of type set to
7181  *        an event name.
7182  */
7183 EventTarget.prototype.trigger = function (event) {
7184   var type = event.type || event;
7185
7186   if (typeof event === 'string') {
7187     event = { type: type };
7188   }
7189   event = Events.fixEvent(event);
7190
7191   if (this.allowedEvents_[type] && this['on' + type]) {
7192     this['on' + type](event);
7193   }
7194
7195   Events.trigger(this, event);
7196 };
7197
7198 /**
7199  * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
7200  * the standard DOM API.
7201  *
7202  * @function
7203  * @see {@link EventTarget#trigger}
7204  */
7205 EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
7206
7207 exports['default'] = EventTarget;
7208
7209 },{"82":82}],43:[function(_dereq_,module,exports){
7210 'use strict';
7211
7212 exports.__esModule = true;
7213
7214 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; };
7215
7216 var _log = _dereq_(86);
7217
7218 var _log2 = _interopRequireDefault(_log);
7219
7220 var _obj = _dereq_(88);
7221
7222 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7223
7224 /**
7225  * @file extend.js
7226  * @module extend
7227  */
7228
7229 /**
7230  * A combination of node inherits and babel's inherits (after transpile).
7231  * Both work the same but node adds `super_` to the subClass
7232  * and Bable adds the superClass as __proto__. Both seem useful.
7233  *
7234  * @param {Object} subClass
7235  *        The class to inherit to
7236  *
7237  * @param {Object} superClass
7238  *        The class to inherit from
7239  *
7240  * @private
7241  */
7242 var _inherits = function _inherits(subClass, superClass) {
7243   if (typeof superClass !== 'function' && superClass !== null) {
7244     throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
7245   }
7246
7247   subClass.prototype = Object.create(superClass && superClass.prototype, {
7248     constructor: {
7249       value: subClass,
7250       enumerable: false,
7251       writable: true,
7252       configurable: true
7253     }
7254   });
7255
7256   if (superClass) {
7257     // node
7258     subClass.super_ = superClass;
7259   }
7260 };
7261
7262 /**
7263  * Function for subclassing using the same inheritance that
7264  * videojs uses internally
7265  *
7266  * @param {Object} superClass
7267  *        The class to inherit from
7268  *
7269  * @param {Object} [subClassMethods={}]
7270  *        The class to inherit to
7271  *
7272  * @return {Object}
7273  *         The new object with subClassMethods that inherited superClass.
7274  */
7275 var extendFn = function extendFn(superClass) {
7276   var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7277
7278   var subClass = function subClass() {
7279     superClass.apply(this, arguments);
7280   };
7281
7282   var methods = {};
7283
7284   if ((0, _obj.isObject)(subClassMethods)) {
7285     if (typeof subClassMethods.init === 'function') {
7286       _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
7287       subClassMethods.constructor = subClassMethods.init;
7288     }
7289     if (subClassMethods.constructor !== Object.prototype.constructor) {
7290       subClass = subClassMethods.constructor;
7291     }
7292     methods = subClassMethods;
7293   } else if (typeof subClassMethods === 'function') {
7294     subClass = subClassMethods;
7295   }
7296
7297   _inherits(subClass, superClass);
7298
7299   // Extend subObj's prototype with functions and other properties from props
7300   for (var name in methods) {
7301     if (methods.hasOwnProperty(name)) {
7302       subClass.prototype[name] = methods[name];
7303     }
7304   }
7305
7306   return subClass;
7307 };
7308
7309 exports['default'] = extendFn;
7310
7311 },{"86":86,"88":88}],44:[function(_dereq_,module,exports){
7312 'use strict';
7313
7314 exports.__esModule = true;
7315
7316 var _document = _dereq_(94);
7317
7318 var _document2 = _interopRequireDefault(_document);
7319
7320 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7321
7322 /**
7323  * Store the browser-specific methods for the fullscreen API.
7324  *
7325  * @type {Object}
7326  * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
7327  * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
7328  */
7329 var FullscreenApi = {};
7330
7331 // browser API methods
7332 /**
7333  * @file fullscreen-api.js
7334  * @module fullscreen-api
7335  * @private
7336  */
7337 var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
7338 // WebKit
7339 ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7340 // Old WebKit (Safari 5.1)
7341 ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7342 // Mozilla
7343 ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
7344 // Microsoft
7345 ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
7346
7347 var specApi = apiMap[0];
7348 var browserApi = void 0;
7349
7350 // determine the supported set of functions
7351 for (var i = 0; i < apiMap.length; i++) {
7352   // check for exitFullscreen function
7353   if (apiMap[i][1] in _document2['default']) {
7354     browserApi = apiMap[i];
7355     break;
7356   }
7357 }
7358
7359 // map the browser API names to the spec API names
7360 if (browserApi) {
7361   for (var _i = 0; _i < browserApi.length; _i++) {
7362     FullscreenApi[specApi[_i]] = browserApi[_i];
7363   }
7364 }
7365
7366 exports['default'] = FullscreenApi;
7367
7368 },{"94":94}],45:[function(_dereq_,module,exports){
7369 'use strict';
7370
7371 exports.__esModule = true;
7372
7373 var _component = _dereq_(5);
7374
7375 var _component2 = _interopRequireDefault(_component);
7376
7377 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7378
7379 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7380
7381 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; }
7382
7383 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; } /**
7384                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file loading-spinner.js
7385                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
7386
7387
7388 /**
7389  * A loading spinner for use during waiting/loading events.
7390  *
7391  * @extends Component
7392  */
7393 var LoadingSpinner = function (_Component) {
7394   _inherits(LoadingSpinner, _Component);
7395
7396   function LoadingSpinner() {
7397     _classCallCheck(this, LoadingSpinner);
7398
7399     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
7400   }
7401
7402   /**
7403    * Create the `LoadingSpinner`s DOM element.
7404    *
7405    * @return {Element}
7406    *         The dom element that gets created.
7407    */
7408   LoadingSpinner.prototype.createEl = function createEl() {
7409     return _Component.prototype.createEl.call(this, 'div', {
7410       className: 'vjs-loading-spinner',
7411       dir: 'ltr'
7412     });
7413   };
7414
7415   return LoadingSpinner;
7416 }(_component2['default']);
7417
7418 _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
7419 exports['default'] = LoadingSpinner;
7420
7421 },{"5":5}],46:[function(_dereq_,module,exports){
7422 'use strict';
7423
7424 exports.__esModule = true;
7425
7426 var _obj = _dereq_(88);
7427
7428 /**
7429  * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
7430  *
7431  * @param {number|string|Object|MediaError} value
7432  *        This can be of multiple types:
7433  *        - number: should be a standard error code
7434  *        - string: an error message (the code will be 0)
7435  *        - Object: arbitrary properties
7436  *        - `MediaError` (native): used to populate a video.js `MediaError` object
7437  *        - `MediaError` (video.js): will return itself if it's already a
7438  *          video.js `MediaError` object.
7439  *
7440  * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
7441  * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
7442  *
7443  * @class MediaError
7444  */
7445 function MediaError(value) {
7446
7447   // Allow redundant calls to this constructor to avoid having `instanceof`
7448   // checks peppered around the code.
7449   if (value instanceof MediaError) {
7450     return value;
7451   }
7452
7453   if (typeof value === 'number') {
7454     this.code = value;
7455   } else if (typeof value === 'string') {
7456     // default code is zero, so this is a custom error
7457     this.message = value;
7458   } else if ((0, _obj.isObject)(value)) {
7459
7460     // We assign the `code` property manually because native `MediaError` objects
7461     // do not expose it as an own/enumerable property of the object.
7462     if (typeof value.code === 'number') {
7463       this.code = value.code;
7464     }
7465
7466     (0, _obj.assign)(this, value);
7467   }
7468
7469   if (!this.message) {
7470     this.message = MediaError.defaultMessages[this.code] || '';
7471   }
7472 }
7473
7474 /**
7475  * The error code that refers two one of the defined `MediaError` types
7476  *
7477  * @type {Number}
7478  */
7479 /**
7480  * @file media-error.js
7481  */
7482 MediaError.prototype.code = 0;
7483
7484 /**
7485  * An optional message that to show with the error. Message is not part of the HTML5
7486  * video spec but allows for more informative custom errors.
7487  *
7488  * @type {String}
7489  */
7490 MediaError.prototype.message = '';
7491
7492 /**
7493  * An optional status code that can be set by plugins to allow even more detail about
7494  * the error. For example a plugin might provide a specific HTTP status code and an
7495  * error message for that code. Then when the plugin gets that error this class will
7496  * know how to display an error message for it. This allows a custom message to show
7497  * up on the `Player` error overlay.
7498  *
7499  * @type {Array}
7500  */
7501 MediaError.prototype.status = null;
7502
7503 /**
7504  * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
7505  * specification listed under {@link MediaError} for more information.
7506  *
7507  * @enum {array}
7508  * @readonly
7509  * @property {string} 0 - MEDIA_ERR_CUSTOM
7510  * @property {string} 1 - MEDIA_ERR_CUSTOM
7511  * @property {string} 2 - MEDIA_ERR_ABORTED
7512  * @property {string} 3 - MEDIA_ERR_NETWORK
7513  * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
7514  * @property {string} 5 - MEDIA_ERR_ENCRYPTED
7515  */
7516 MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
7517
7518 /**
7519  * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
7520  *
7521  * @type {Array}
7522  * @constant
7523  */
7524 MediaError.defaultMessages = {
7525   1: 'You aborted the media playback',
7526   2: 'A network error caused the media download to fail part-way.',
7527   3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
7528   4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
7529   5: 'The media is encrypted and we do not have the keys to decrypt it.'
7530 };
7531
7532 // Add types as properties on MediaError
7533 // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
7534 for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
7535   MediaError[MediaError.errorTypes[errNum]] = errNum;
7536   // values should be accessible on both the class and instance
7537   MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
7538 }
7539
7540 // jsdocs for instance/static members added above
7541 // instance methods use `#` and static methods use `.`
7542 /**
7543  * W3C error code for any custom error.
7544  *
7545  * @member MediaError#MEDIA_ERR_CUSTOM
7546  * @constant {number}
7547  * @default 0
7548  */
7549 /**
7550  * W3C error code for any custom error.
7551  *
7552  * @member MediaError.MEDIA_ERR_CUSTOM
7553  * @constant {number}
7554  * @default 0
7555  */
7556
7557 /**
7558  * W3C error code for media error aborted.
7559  *
7560  * @member MediaError#MEDIA_ERR_ABORTED
7561  * @constant {number}
7562  * @default 1
7563  */
7564 /**
7565  * W3C error code for media error aborted.
7566  *
7567  * @member MediaError.MEDIA_ERR_ABORTED
7568  * @constant {number}
7569  * @default 1
7570  */
7571
7572 /**
7573  * W3C error code for any network error.
7574  *
7575  * @member MediaError#MEDIA_ERR_NETWORK
7576  * @constant {number}
7577  * @default 2
7578  */
7579 /**
7580  * W3C error code for any network error.
7581  *
7582  * @member MediaError.MEDIA_ERR_NETWORK
7583  * @constant {number}
7584  * @default 2
7585  */
7586
7587 /**
7588  * W3C error code for any decoding error.
7589  *
7590  * @member MediaError#MEDIA_ERR_DECODE
7591  * @constant {number}
7592  * @default 3
7593  */
7594 /**
7595  * W3C error code for any decoding error.
7596  *
7597  * @member MediaError.MEDIA_ERR_DECODE
7598  * @constant {number}
7599  * @default 3
7600  */
7601
7602 /**
7603  * W3C error code for any time that a source is not supported.
7604  *
7605  * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
7606  * @constant {number}
7607  * @default 4
7608  */
7609 /**
7610  * W3C error code for any time that a source is not supported.
7611  *
7612  * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
7613  * @constant {number}
7614  * @default 4
7615  */
7616
7617 /**
7618  * W3C error code for any time that a source is encrypted.
7619  *
7620  * @member MediaError#MEDIA_ERR_ENCRYPTED
7621  * @constant {number}
7622  * @default 5
7623  */
7624 /**
7625  * W3C error code for any time that a source is encrypted.
7626  *
7627  * @member MediaError.MEDIA_ERR_ENCRYPTED
7628  * @constant {number}
7629  * @default 5
7630  */
7631
7632 exports['default'] = MediaError;
7633
7634 },{"88":88}],47:[function(_dereq_,module,exports){
7635 'use strict';
7636
7637 exports.__esModule = true;
7638
7639 var _clickableComponent = _dereq_(3);
7640
7641 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7642
7643 var _component = _dereq_(5);
7644
7645 var _component2 = _interopRequireDefault(_component);
7646
7647 var _menu = _dereq_(49);
7648
7649 var _menu2 = _interopRequireDefault(_menu);
7650
7651 var _dom = _dereq_(81);
7652
7653 var Dom = _interopRequireWildcard(_dom);
7654
7655 var _fn = _dereq_(83);
7656
7657 var Fn = _interopRequireWildcard(_fn);
7658
7659 var _toTitleCase = _dereq_(91);
7660
7661 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
7662
7663 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; } }
7664
7665 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7666
7667 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7668
7669 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; }
7670
7671 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; } /**
7672                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file menu-button.js
7673                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
7674
7675
7676 /**
7677  * A `MenuButton` class for any popup {@link Menu}.
7678  *
7679  * @extends ClickableComponent
7680  */
7681 var MenuButton = function (_ClickableComponent) {
7682   _inherits(MenuButton, _ClickableComponent);
7683
7684   /**
7685    * Creates an instance of this class.
7686    *
7687    * @param {Player} player
7688    *        The `Player` that this class should be attached to.
7689    *
7690    * @param {Object} [options={}]
7691    *        The key/value store of player options.
7692    */
7693   function MenuButton(player) {
7694     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7695
7696     _classCallCheck(this, MenuButton);
7697
7698     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
7699
7700     _this.update();
7701
7702     _this.enabled_ = true;
7703
7704     _this.el_.setAttribute('aria-haspopup', 'true');
7705     _this.el_.setAttribute('role', 'menuitem');
7706     _this.on('keydown', _this.handleSubmenuKeyPress);
7707     return _this;
7708   }
7709
7710   /**
7711    * Update the menu based on the current state of its items.
7712    */
7713
7714
7715   MenuButton.prototype.update = function update() {
7716     var menu = this.createMenu();
7717
7718     if (this.menu) {
7719       this.removeChild(this.menu);
7720     }
7721
7722     this.menu = menu;
7723     this.addChild(menu);
7724
7725     /**
7726      * Track the state of the menu button
7727      *
7728      * @type {Boolean}
7729      * @private
7730      */
7731     this.buttonPressed_ = false;
7732     this.el_.setAttribute('aria-expanded', 'false');
7733
7734     if (this.items && this.items.length <= this.hideThreshold_) {
7735       this.hide();
7736     } else {
7737       this.show();
7738     }
7739   };
7740
7741   /**
7742    * Create the menu and add all items to it.
7743    *
7744    * @return {Menu}
7745    *         The constructed menu
7746    */
7747
7748
7749   MenuButton.prototype.createMenu = function createMenu() {
7750     var menu = new _menu2['default'](this.player_);
7751
7752     /**
7753      * Hide the menu if the number of items is less than or equal to this threshold. This defaults
7754      * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list
7755      * it here because every time we run `createMenu` we need to reset the value.
7756      *
7757      * @protected
7758      * @type {Number}
7759      */
7760     this.hideThreshold_ = 0;
7761
7762     // Add a title list item to the top
7763     if (this.options_.title) {
7764       var title = Dom.createEl('li', {
7765         className: 'vjs-menu-title',
7766         innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
7767         tabIndex: -1
7768       });
7769
7770       this.hideThreshold_ += 1;
7771
7772       menu.children_.unshift(title);
7773       Dom.insertElFirst(title, menu.contentEl());
7774     }
7775
7776     this.items = this.createItems();
7777
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     }
7784
7785     return menu;
7786   };
7787
7788   /**
7789    * Create the list of menu items. Specific to each subclass.
7790    *
7791    * @abstract
7792    */
7793
7794
7795   MenuButton.prototype.createItems = function createItems() {};
7796
7797   /**
7798    * Create the `MenuButtons`s DOM element.
7799    *
7800    * @return {Element}
7801    *         The element that gets created.
7802    */
7803
7804
7805   MenuButton.prototype.createEl = function createEl() {
7806     return _ClickableComponent.prototype.createEl.call(this, 'div', {
7807       className: this.buildCSSClass()
7808     });
7809   };
7810
7811   /**
7812    * Builds the default DOM `className`.
7813    *
7814    * @return {string}
7815    *         The DOM `className` for this object.
7816    */
7817
7818
7819   MenuButton.prototype.buildCSSClass = function buildCSSClass() {
7820     var menuButtonClass = 'vjs-menu-button';
7821
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     }
7828
7829     return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
7830   };
7831
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    */
7843
7844
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.
7849
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   };
7860
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    */
7870
7871
7872   MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
7873
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   };
7893
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    */
7903
7904
7905   MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
7906
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   };
7918
7919   /**
7920    * Put the current `MenuButton` into a pressed state.
7921    */
7922
7923
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   };
7933
7934   /**
7935    * Take the current `MenuButton` out of a pressed state.
7936    */
7937
7938
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   };
7948
7949   /**
7950    * Disable the `MenuButton`. Don't allow it to be clicked.
7951    *
7952    * @return {MenuButton}
7953    *         Returns itself; method can be chained.
7954    */
7955
7956
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');
7962
7963     this.enabled_ = false;
7964
7965     return _ClickableComponent.prototype.disable.call(this);
7966   };
7967
7968   /**
7969    * Enable the `MenuButton`. Allow it to be clicked.
7970    *
7971    * @return {MenuButton}
7972    *         Returns itself; method can be chained.
7973    */
7974
7975
7976   MenuButton.prototype.enable = function enable() {
7977     this.enabled_ = true;
7978
7979     return _ClickableComponent.prototype.enable.call(this);
7980   };
7981
7982   return MenuButton;
7983 }(_clickableComponent2['default']);
7984
7985 _component2['default'].registerComponent('MenuButton', MenuButton);
7986 exports['default'] = MenuButton;
7987
7988 },{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){
7989 'use strict';
7990
7991 exports.__esModule = true;
7992
7993 var _clickableComponent = _dereq_(3);
7994
7995 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7996
7997 var _component = _dereq_(5);
7998
7999 var _component2 = _interopRequireDefault(_component);
8000
8001 var _obj = _dereq_(88);
8002
8003 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8004
8005 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8006
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; }
8008
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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8012
8013
8014 /**
8015  * The component for a menu item. `<li>`
8016  *
8017  * @extends ClickableComponent
8018  */
8019 var MenuItem = function (_ClickableComponent) {
8020   _inherits(MenuItem, _ClickableComponent);
8021
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);
8034
8035     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
8036
8037     _this.selectable = options.selectable;
8038
8039     _this.selected(options.selected);
8040
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   }
8050
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    */
8066
8067
8068   MenuItem.prototype.createEl = function createEl(type, props, attrs) {
8069     // The control is textual, not just an icon
8070     this.nonIconControl = true;
8071
8072     return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
8073       className: 'vjs-menu-item',
8074       innerHTML: this.localize(this.options_.label),
8075       tabIndex: -1
8076     }, props), attrs);
8077   };
8078
8079   /**
8080    * Any click on a `MenuItem` puts int into the selected state.
8081    * See {@link ClickableComponent#handleClick} for instances where this is called.
8082    *
8083    * @param {EventTarget~Event} event
8084    *        The `keydown`, `tap`, or `click` event that caused this function to be
8085    *        called.
8086    *
8087    * @listens tap
8088    * @listens click
8089    */
8090
8091
8092   MenuItem.prototype.handleClick = function handleClick(event) {
8093     this.selected(true);
8094   };
8095
8096   /**
8097    * Set the state for this menu item as selected or not.
8098    *
8099    * @param {boolean} selected
8100    *        if the menu item is selected or not
8101    */
8102
8103
8104   MenuItem.prototype.selected = function selected(_selected) {
8105     if (this.selectable) {
8106       if (_selected) {
8107         this.addClass('vjs-selected');
8108         this.el_.setAttribute('aria-checked', 'true');
8109         // aria-checked isn't fully supported by browsers/screen readers,
8110         // so indicate selected state to screen reader in the control text.
8111         this.controlText(', selected');
8112       } else {
8113         this.removeClass('vjs-selected');
8114         this.el_.setAttribute('aria-checked', 'false');
8115         // Indicate un-selected state to screen reader
8116         // Note that a space clears out the selected state text
8117         this.controlText(' ');
8118       }
8119     }
8120   };
8121
8122   return MenuItem;
8123 }(_clickableComponent2['default']);
8124
8125 _component2['default'].registerComponent('MenuItem', MenuItem);
8126 exports['default'] = MenuItem;
8127
8128 },{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){
8129 'use strict';
8130
8131 exports.__esModule = true;
8132
8133 var _component = _dereq_(5);
8134
8135 var _component2 = _interopRequireDefault(_component);
8136
8137 var _dom = _dereq_(81);
8138
8139 var Dom = _interopRequireWildcard(_dom);
8140
8141 var _fn = _dereq_(83);
8142
8143 var Fn = _interopRequireWildcard(_fn);
8144
8145 var _events = _dereq_(82);
8146
8147 var Events = _interopRequireWildcard(_events);
8148
8149 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; } }
8150
8151 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8152
8153 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8154
8155 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; }
8156
8157 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; } /**
8158                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file menu.js
8159                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8160
8161
8162 /**
8163  * The Menu component is used to build popup menus, including subtitle and
8164  * captions selection menus.
8165  *
8166  * @extends Component
8167  */
8168 var Menu = function (_Component) {
8169   _inherits(Menu, _Component);
8170
8171   /**
8172    * Create an instance of this class.
8173    *
8174    * @param {Player} player
8175    *        the player that this component should attach to
8176    *
8177    * @param {Object} [options]
8178    *        Object of option names and values
8179    *
8180    */
8181   function Menu(player, options) {
8182     _classCallCheck(this, Menu);
8183
8184     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8185
8186     _this.focusedChild_ = -1;
8187
8188     _this.on('keydown', _this.handleKeyPress);
8189     return _this;
8190   }
8191
8192   /**
8193    * Add a {@link MenuItem} to the menu.
8194    *
8195    * @param {Object|string} component
8196    *        The name or instance of the `MenuItem` to add.
8197    *
8198    */
8199
8200
8201   Menu.prototype.addItem = function addItem(component) {
8202     this.addChild(component);
8203     component.on('click', Fn.bind(this, function (event) {
8204       this.unlockShowing();
8205       // TODO: Need to set keyboard focus back to the menuButton
8206     }));
8207   };
8208
8209   /**
8210    * Create the `Menu`s DOM element.
8211    *
8212    * @return {Element}
8213    *         the element that was created
8214    */
8215
8216
8217   Menu.prototype.createEl = function createEl() {
8218     var contentElType = this.options_.contentElType || 'ul';
8219
8220     this.contentEl_ = Dom.createEl(contentElType, {
8221       className: 'vjs-menu-content'
8222     });
8223
8224     this.contentEl_.setAttribute('role', 'menu');
8225
8226     var el = _Component.prototype.createEl.call(this, 'div', {
8227       append: this.contentEl_,
8228       className: 'vjs-menu'
8229     });
8230
8231     el.setAttribute('role', 'presentation');
8232     el.appendChild(this.contentEl_);
8233
8234     // Prevent clicks from bubbling up. Needed for Menu Buttons,
8235     // where a click on the parent is significant
8236     Events.on(el, 'click', function (event) {
8237       event.preventDefault();
8238       event.stopImmediatePropagation();
8239     });
8240
8241     return el;
8242   };
8243
8244   /**
8245    * Handle a `keydown` event on this menu. This listener is added in the constructor.
8246    *
8247    * @param {EventTarget~Event} event
8248    *        A `keydown` event that happened on the menu.
8249    *
8250    * @listens keydown
8251    */
8252
8253
8254   Menu.prototype.handleKeyPress = function handleKeyPress(event) {
8255     // Left and Down Arrows
8256     if (event.which === 37 || event.which === 40) {
8257       event.preventDefault();
8258       this.stepForward();
8259
8260       // Up and Right Arrows
8261     } else if (event.which === 38 || event.which === 39) {
8262       event.preventDefault();
8263       this.stepBack();
8264     }
8265   };
8266
8267   /**
8268    * Move to next (lower) menu item for keyboard users.
8269    */
8270
8271
8272   Menu.prototype.stepForward = function stepForward() {
8273     var stepChild = 0;
8274
8275     if (this.focusedChild_ !== undefined) {
8276       stepChild = this.focusedChild_ + 1;
8277     }
8278     this.focus(stepChild);
8279   };
8280
8281   /**
8282    * Move to previous (higher) menu item for keyboard users.
8283    */
8284
8285
8286   Menu.prototype.stepBack = function stepBack() {
8287     var stepChild = 0;
8288
8289     if (this.focusedChild_ !== undefined) {
8290       stepChild = this.focusedChild_ - 1;
8291     }
8292     this.focus(stepChild);
8293   };
8294
8295   /**
8296    * Set focus on a {@link MenuItem} in the `Menu`.
8297    *
8298    * @param {Object|string} [item=0]
8299    *        Index of child item set focus on.
8300    */
8301
8302
8303   Menu.prototype.focus = function focus() {
8304     var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8305
8306     var children = this.children().slice();
8307     var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
8308
8309     if (haveTitle) {
8310       children.shift();
8311     }
8312
8313     if (children.length > 0) {
8314       if (item < 0) {
8315         item = 0;
8316       } else if (item >= children.length) {
8317         item = children.length - 1;
8318       }
8319
8320       this.focusedChild_ = item;
8321
8322       children[item].el_.focus();
8323     }
8324   };
8325
8326   return Menu;
8327 }(_component2['default']);
8328
8329 _component2['default'].registerComponent('Menu', Menu);
8330 exports['default'] = Menu;
8331
8332 },{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){
8333 'use strict';
8334
8335 exports.__esModule = true;
8336
8337 var _dom = _dereq_(81);
8338
8339 var Dom = _interopRequireWildcard(_dom);
8340
8341 var _fn = _dereq_(83);
8342
8343 var Fn = _interopRequireWildcard(_fn);
8344
8345 var _component = _dereq_(5);
8346
8347 var _component2 = _interopRequireDefault(_component);
8348
8349 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8350
8351 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; } }
8352
8353 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8354
8355 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; }
8356
8357 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; } /**
8358                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file modal-dialog.js
8359                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8360
8361
8362 var MODAL_CLASS_NAME = 'vjs-modal-dialog';
8363 var ESC = 27;
8364
8365 /**
8366  * The `ModalDialog` displays over the video and its controls, which blocks
8367  * interaction with the player until it is closed.
8368  *
8369  * Modal dialogs include a "Close" button and will close when that button
8370  * is activated - or when ESC is pressed anywhere.
8371  *
8372  * @extends Component
8373  */
8374
8375 var ModalDialog = function (_Component) {
8376   _inherits(ModalDialog, _Component);
8377
8378   /**
8379    * Create an instance of this class.
8380    *
8381    * @param {Player} player
8382    *        The `Player` that this class should be attached to.
8383    *
8384    * @param {Object} [options]
8385    *        The key/value store of player options.
8386    *
8387    * @param {Mixed} [options.content=undefined]
8388    *        Provide customized content for this modal.
8389    *
8390    * @param {string} [options.description]
8391    *        A text description for the modal, primarily for accessibility.
8392    *
8393    * @param {boolean} [options.fillAlways=false]
8394    *        Normally, modals are automatically filled only the first time
8395    *        they open. This tells the modal to refresh its content
8396    *        every time it opens.
8397    *
8398    * @param {string} [options.label]
8399    *        A text label for the modal, primarily for accessibility.
8400    *
8401    * @param {boolean} [options.temporary=true]
8402    *        If `true`, the modal can only be opened once; it will be
8403    *        disposed as soon as it's closed.
8404    *
8405    * @param {boolean} [options.uncloseable=false]
8406    *        If `true`, the user will not be able to close the modal
8407    *        through the UI in the normal ways. Programmatic closing is
8408    *        still possible.
8409    */
8410   function ModalDialog(player, options) {
8411     _classCallCheck(this, ModalDialog);
8412
8413     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8414
8415     _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
8416
8417     _this.closeable(!_this.options_.uncloseable);
8418     _this.content(_this.options_.content);
8419
8420     // Make sure the contentEl is defined AFTER any children are initialized
8421     // because we only want the contents of the modal in the contentEl
8422     // (not the UI elements like the close button).
8423     _this.contentEl_ = Dom.createEl('div', {
8424       className: MODAL_CLASS_NAME + '-content'
8425     }, {
8426       role: 'document'
8427     });
8428
8429     _this.descEl_ = Dom.createEl('p', {
8430       className: MODAL_CLASS_NAME + '-description vjs-offscreen',
8431       id: _this.el().getAttribute('aria-describedby')
8432     });
8433
8434     Dom.textContent(_this.descEl_, _this.description());
8435     _this.el_.appendChild(_this.descEl_);
8436     _this.el_.appendChild(_this.contentEl_);
8437     return _this;
8438   }
8439
8440   /**
8441    * Create the `ModalDialog`'s DOM element
8442    *
8443    * @return {Element}
8444    *         The DOM element that gets created.
8445    */
8446
8447
8448   ModalDialog.prototype.createEl = function createEl() {
8449     return _Component.prototype.createEl.call(this, 'div', {
8450       className: this.buildCSSClass(),
8451       tabIndex: -1
8452     }, {
8453       'aria-describedby': this.id() + '_description',
8454       'aria-hidden': 'true',
8455       'aria-label': this.label(),
8456       'role': 'dialog'
8457     });
8458   };
8459
8460   /**
8461    * Builds the default DOM `className`.
8462    *
8463    * @return {string}
8464    *         The DOM `className` for this object.
8465    */
8466
8467
8468   ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
8469     return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
8470   };
8471
8472   /**
8473    * Handles `keydown` events on the document, looking for ESC, which closes
8474    * the modal.
8475    *
8476    * @param {EventTarget~Event} e
8477    *        The keypress that triggered this event.
8478    *
8479    * @listens keydown
8480    */
8481
8482
8483   ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
8484     if (e.which === ESC && this.closeable()) {
8485       this.close();
8486     }
8487   };
8488
8489   /**
8490    * Returns the label string for this modal. Primarily used for accessibility.
8491    *
8492    * @return {string}
8493    *         the localized or raw label of this modal.
8494    */
8495
8496
8497   ModalDialog.prototype.label = function label() {
8498     return this.options_.label || this.localize('Modal Window');
8499   };
8500
8501   /**
8502    * Returns the description string for this modal. Primarily used for
8503    * accessibility.
8504    *
8505    * @return {string}
8506    *         The localized or raw description of this modal.
8507    */
8508
8509
8510   ModalDialog.prototype.description = function description() {
8511     var desc = this.options_.description || this.localize('This is a modal window.');
8512
8513     // Append a universal closeability message if the modal is closeable.
8514     if (this.closeable()) {
8515       desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
8516     }
8517
8518     return desc;
8519   };
8520
8521   /**
8522    * Opens the modal.
8523    *
8524    * @fires ModalDialog#beforemodalopen
8525    * @fires ModalDialog#modalopen
8526    *
8527    * @return {ModalDialog}
8528    *         Returns itself; method can be chained.
8529    */
8530
8531
8532   ModalDialog.prototype.open = function open() {
8533     if (!this.opened_) {
8534       var player = this.player();
8535
8536       /**
8537        * Fired just before a `ModalDialog` is opened.
8538        *
8539        * @event ModalDialog#beforemodalopen
8540        * @type {EventTarget~Event}
8541        */
8542       this.trigger('beforemodalopen');
8543       this.opened_ = true;
8544
8545       // Fill content if the modal has never opened before and
8546       // never been filled.
8547       if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
8548         this.fill();
8549       }
8550
8551       // If the player was playing, pause it and take note of its previously
8552       // playing state.
8553       this.wasPlaying_ = !player.paused();
8554
8555       if (this.options_.pauseOnOpen && this.wasPlaying_) {
8556         player.pause();
8557       }
8558
8559       if (this.closeable()) {
8560         this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8561       }
8562
8563       player.controls(false);
8564       this.show();
8565       this.el().setAttribute('aria-hidden', 'false');
8566
8567       /**
8568        * Fired just after a `ModalDialog` is opened.
8569        *
8570        * @event ModalDialog#modalopen
8571        * @type {EventTarget~Event}
8572        */
8573       this.trigger('modalopen');
8574       this.hasBeenOpened_ = true;
8575     }
8576     return this;
8577   };
8578
8579   /**
8580    * If the `ModalDialog` is currently open or closed.
8581    *
8582    * @param  {boolean} [value]
8583    *         If given, it will open (`true`) or close (`false`) the modal.
8584    *
8585    * @return {boolean}
8586    *         the current open state of the modaldialog
8587    */
8588
8589
8590   ModalDialog.prototype.opened = function opened(value) {
8591     if (typeof value === 'boolean') {
8592       this[value ? 'open' : 'close']();
8593     }
8594     return this.opened_;
8595   };
8596
8597   /**
8598    * Closes the modal, does nothing if the `ModalDialog` is
8599    * not open.
8600    *
8601    * @fires ModalDialog#beforemodalclose
8602    * @fires ModalDialog#modalclose
8603    *
8604    * @return {ModalDialog}
8605    *         Returns itself; method can be chained.
8606    */
8607
8608
8609   ModalDialog.prototype.close = function close() {
8610     if (this.opened_) {
8611       var player = this.player();
8612
8613       /**
8614        * Fired just before a `ModalDialog` is closed.
8615        *
8616        * @event ModalDialog#beforemodalclose
8617        * @type {EventTarget~Event}
8618        */
8619       this.trigger('beforemodalclose');
8620       this.opened_ = false;
8621
8622       if (this.wasPlaying_ && this.options_.pauseOnOpen) {
8623         player.play();
8624       }
8625
8626       if (this.closeable()) {
8627         this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8628       }
8629
8630       player.controls(true);
8631       this.hide();
8632       this.el().setAttribute('aria-hidden', 'true');
8633
8634       /**
8635        * Fired just after a `ModalDialog` is closed.
8636        *
8637        * @event ModalDialog#modalclose
8638        * @type {EventTarget~Event}
8639        */
8640       this.trigger('modalclose');
8641
8642       if (this.options_.temporary) {
8643         this.dispose();
8644       }
8645     }
8646     return this;
8647   };
8648
8649   /**
8650    * Check to see if the `ModalDialog` is closeable via the UI.
8651    *
8652    * @param  {boolean} [value]
8653    *         If given as a boolean, it will set the `closeable` option.
8654    *
8655    * @return {boolean}
8656    *         Returns the final value of the closable option.
8657    */
8658
8659
8660   ModalDialog.prototype.closeable = function closeable(value) {
8661     if (typeof value === 'boolean') {
8662       var closeable = this.closeable_ = !!value;
8663       var close = this.getChild('closeButton');
8664
8665       // If this is being made closeable and has no close button, add one.
8666       if (closeable && !close) {
8667
8668         // The close button should be a child of the modal - not its
8669         // content element, so temporarily change the content element.
8670         var temp = this.contentEl_;
8671
8672         this.contentEl_ = this.el_;
8673         close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
8674         this.contentEl_ = temp;
8675         this.on(close, 'close', this.close);
8676       }
8677
8678       // If this is being made uncloseable and has a close button, remove it.
8679       if (!closeable && close) {
8680         this.off(close, 'close', this.close);
8681         this.removeChild(close);
8682         close.dispose();
8683       }
8684     }
8685     return this.closeable_;
8686   };
8687
8688   /**
8689    * Fill the modal's content element with the modal's "content" option.
8690    * The content element will be emptied before this change takes place.
8691    *
8692    * @return {ModalDialog}
8693    *         Returns itself; method can be chained.
8694    */
8695
8696
8697   ModalDialog.prototype.fill = function fill() {
8698     return this.fillWith(this.content());
8699   };
8700
8701   /**
8702    * Fill the modal's content element with arbitrary content.
8703    * The content element will be emptied before this change takes place.
8704    *
8705    * @fires ModalDialog#beforemodalfill
8706    * @fires ModalDialog#modalfill
8707    *
8708    * @param  {Mixed} [content]
8709    *         The same rules apply to this as apply to the `content` option.
8710    *
8711    * @return {ModalDialog}
8712    *         Returns itself; method can be chained.
8713    */
8714
8715
8716   ModalDialog.prototype.fillWith = function fillWith(content) {
8717     var contentEl = this.contentEl();
8718     var parentEl = contentEl.parentNode;
8719     var nextSiblingEl = contentEl.nextSibling;
8720
8721     /**
8722      * Fired just before a `ModalDialog` is filled with content.
8723      *
8724      * @event ModalDialog#beforemodalfill
8725      * @type {EventTarget~Event}
8726      */
8727     this.trigger('beforemodalfill');
8728     this.hasBeenFilled_ = true;
8729
8730     // Detach the content element from the DOM before performing
8731     // manipulation to avoid modifying the live DOM multiple times.
8732     parentEl.removeChild(contentEl);
8733     this.empty();
8734     Dom.insertContent(contentEl, content);
8735     /**
8736      * Fired just after a `ModalDialog` is filled with content.
8737      *
8738      * @event ModalDialog#modalfill
8739      * @type {EventTarget~Event}
8740      */
8741     this.trigger('modalfill');
8742
8743     // Re-inject the re-filled content element.
8744     if (nextSiblingEl) {
8745       parentEl.insertBefore(contentEl, nextSiblingEl);
8746     } else {
8747       parentEl.appendChild(contentEl);
8748     }
8749
8750     return this;
8751   };
8752
8753   /**
8754    * Empties the content element. This happens anytime the modal is filled.
8755    *
8756    * @fires ModalDialog#beforemodalempty
8757    * @fires ModalDialog#modalempty
8758    *
8759    * @return {ModalDialog}
8760    *         Returns itself; method can be chained.
8761    */
8762
8763
8764   ModalDialog.prototype.empty = function empty() {
8765     /**
8766      * Fired just before a `ModalDialog` is emptied.
8767      *
8768      * @event ModalDialog#beforemodalempty
8769      * @type {EventTarget~Event}
8770      */
8771     this.trigger('beforemodalempty');
8772     Dom.emptyEl(this.contentEl());
8773
8774     /**
8775      * Fired just after a `ModalDialog` is emptied.
8776      *
8777      * @event ModalDialog#modalempty
8778      * @type {EventTarget~Event}
8779      */
8780     this.trigger('modalempty');
8781     return this;
8782   };
8783
8784   /**
8785    * Gets or sets the modal content, which gets normalized before being
8786    * rendered into the DOM.
8787    *
8788    * This does not update the DOM or fill the modal, but it is called during
8789    * that process.
8790    *
8791    * @param  {Mixed} [value]
8792    *         If defined, sets the internal content value to be used on the
8793    *         next call(s) to `fill`. This value is normalized before being
8794    *         inserted. To "clear" the internal content value, pass `null`.
8795    *
8796    * @return {Mixed}
8797    *         The current content of the modal dialog
8798    */
8799
8800
8801   ModalDialog.prototype.content = function content(value) {
8802     if (typeof value !== 'undefined') {
8803       this.content_ = value;
8804     }
8805     return this.content_;
8806   };
8807
8808   return ModalDialog;
8809 }(_component2['default']);
8810
8811 /**
8812  * Default options for `ModalDialog` default options.
8813  *
8814  * @type {Object}
8815  * @private
8816  */
8817
8818
8819 ModalDialog.prototype.options_ = {
8820   pauseOnOpen: true,
8821   temporary: true
8822 };
8823
8824 _component2['default'].registerComponent('ModalDialog', ModalDialog);
8825 exports['default'] = ModalDialog;
8826
8827 },{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){
8828 'use strict';
8829
8830 exports.__esModule = true;
8831
8832 var _component = _dereq_(5);
8833
8834 var _component2 = _interopRequireDefault(_component);
8835
8836 var _document = _dereq_(94);
8837
8838 var _document2 = _interopRequireDefault(_document);
8839
8840 var _window = _dereq_(95);
8841
8842 var _window2 = _interopRequireDefault(_window);
8843
8844 var _events = _dereq_(82);
8845
8846 var Events = _interopRequireWildcard(_events);
8847
8848 var _dom = _dereq_(81);
8849
8850 var Dom = _interopRequireWildcard(_dom);
8851
8852 var _fn = _dereq_(83);
8853
8854 var Fn = _interopRequireWildcard(_fn);
8855
8856 var _guid = _dereq_(85);
8857
8858 var Guid = _interopRequireWildcard(_guid);
8859
8860 var _browser = _dereq_(78);
8861
8862 var browser = _interopRequireWildcard(_browser);
8863
8864 var _log = _dereq_(86);
8865
8866 var _log2 = _interopRequireDefault(_log);
8867
8868 var _toTitleCase = _dereq_(91);
8869
8870 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
8871
8872 var _timeRanges = _dereq_(90);
8873
8874 var _buffer = _dereq_(79);
8875
8876 var _stylesheet = _dereq_(89);
8877
8878 var stylesheet = _interopRequireWildcard(_stylesheet);
8879
8880 var _fullscreenApi = _dereq_(44);
8881
8882 var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
8883
8884 var _mediaError = _dereq_(46);
8885
8886 var _mediaError2 = _interopRequireDefault(_mediaError);
8887
8888 var _tuple = _dereq_(97);
8889
8890 var _tuple2 = _interopRequireDefault(_tuple);
8891
8892 var _obj = _dereq_(88);
8893
8894 var _mergeOptions = _dereq_(87);
8895
8896 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
8897
8898 var _textTrackListConverter = _dereq_(69);
8899
8900 var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
8901
8902 var _modalDialog = _dereq_(50);
8903
8904 var _modalDialog2 = _interopRequireDefault(_modalDialog);
8905
8906 var _tech = _dereq_(62);
8907
8908 var _tech2 = _interopRequireDefault(_tech);
8909
8910 var _audioTrackList = _dereq_(63);
8911
8912 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
8913
8914 var _videoTrackList = _dereq_(76);
8915
8916 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
8917
8918 _dereq_(61);
8919
8920 _dereq_(59);
8921
8922 _dereq_(55);
8923
8924 _dereq_(68);
8925
8926 _dereq_(45);
8927
8928 _dereq_(1);
8929
8930 _dereq_(4);
8931
8932 _dereq_(8);
8933
8934 _dereq_(41);
8935
8936 _dereq_(71);
8937
8938 _dereq_(60);
8939
8940 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; } }
8941
8942 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8943
8944 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8945
8946 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; }
8947
8948 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; } /**
8949                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file player.js
8950                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
8951 // Subclasses Component
8952
8953
8954 // The following imports are used only to ensure that the corresponding modules
8955 // are always included in the video.js package. Importing the modules will
8956 // execute them and they will register themselves with video.js.
8957
8958
8959 // Import Html5 tech, at least for disposing the original video tag.
8960
8961
8962 // The following tech events are simply re-triggered
8963 // on the player when they happen
8964 var TECH_EVENTS_RETRIGGER = [
8965 /**
8966  * Fired while the user agent is downloading media data.
8967  *
8968  * @event Player#progress
8969  * @type {EventTarget~Event}
8970  */
8971 /**
8972  * Retrigger the `progress` event that was triggered by the {@link Tech}.
8973  *
8974  * @private
8975  * @method Player#handleTechProgress_
8976  * @fires Player#progress
8977  * @listens Tech#progress
8978  */
8979 'progress',
8980
8981 /**
8982  * Fires when the loading of an audio/video is aborted.
8983  *
8984  * @event Player#abort
8985  * @type {EventTarget~Event}
8986  */
8987 /**
8988  * Retrigger the `abort` event that was triggered by the {@link Tech}.
8989  *
8990  * @private
8991  * @method Player#handleTechAbort_
8992  * @fires Player#abort
8993  * @listens Tech#abort
8994  */
8995 'abort',
8996
8997 /**
8998  * Fires when the browser is intentionally not getting media data.
8999  *
9000  * @event Player#suspend
9001  * @type {EventTarget~Event}
9002  */
9003 /**
9004  * Retrigger the `suspend` event that was triggered by the {@link Tech}.
9005  *
9006  * @private
9007  * @method Player#handleTechSuspend_
9008  * @fires Player#suspend
9009  * @listens Tech#suspend
9010  */
9011 'suspend',
9012
9013 /**
9014  * Fires when the current playlist is empty.
9015  *
9016  * @event Player#emptied
9017  * @type {EventTarget~Event}
9018  */
9019 /**
9020  * Retrigger the `emptied` event that was triggered by the {@link Tech}.
9021  *
9022  * @private
9023  * @method Player#handleTechEmptied_
9024  * @fires Player#emptied
9025  * @listens Tech#emptied
9026  */
9027 'emptied',
9028 /**
9029  * Fires when the browser is trying to get media data, but data is not available.
9030  *
9031  * @event Player#stalled
9032  * @type {EventTarget~Event}
9033  */
9034 /**
9035  * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9036  *
9037  * @private
9038  * @method Player#handleTechStalled_
9039  * @fires Player#stalled
9040  * @listens Tech#stalled
9041  */
9042 'stalled',
9043
9044 /**
9045  * Fires when the browser has loaded meta data for the audio/video.
9046  *
9047  * @event Player#loadedmetadata
9048  * @type {EventTarget~Event}
9049  */
9050 /**
9051  * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9052  *
9053  * @private
9054  * @method Player#handleTechLoadedmetadata_
9055  * @fires Player#loadedmetadata
9056  * @listens Tech#loadedmetadata
9057  */
9058 'loadedmetadata',
9059
9060 /**
9061  * Fires when the browser has loaded the current frame of the audio/video.
9062  *
9063  * @event player#loadeddata
9064  * @type {event}
9065  */
9066 /**
9067  * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
9068  *
9069  * @private
9070  * @method Player#handleTechLoaddeddata_
9071  * @fires Player#loadeddata
9072  * @listens Tech#loadeddata
9073  */
9074 'loadeddata',
9075
9076 /**
9077  * Fires when the current playback position has changed.
9078  *
9079  * @event player#timeupdate
9080  * @type {event}
9081  */
9082 /**
9083  * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
9084  *
9085  * @private
9086  * @method Player#handleTechTimeUpdate_
9087  * @fires Player#timeupdate
9088  * @listens Tech#timeupdate
9089  */
9090 'timeupdate',
9091
9092 /**
9093  * Fires when the playing speed of the audio/video is changed
9094  *
9095  * @event player#ratechange
9096  * @type {event}
9097  */
9098 /**
9099  * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
9100  *
9101  * @private
9102  * @method Player#handleTechRatechange_
9103  * @fires Player#ratechange
9104  * @listens Tech#ratechange
9105  */
9106 'ratechange',
9107
9108 /**
9109  * Fires when the volume has been changed
9110  *
9111  * @event player#volumechange
9112  * @type {event}
9113  */
9114 /**
9115  * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
9116  *
9117  * @private
9118  * @method Player#handleTechVolumechange_
9119  * @fires Player#volumechange
9120  * @listens Tech#volumechange
9121  */
9122 'volumechange',
9123
9124 /**
9125  * Fires when the text track has been changed
9126  *
9127  * @event player#texttrackchange
9128  * @type {event}
9129  */
9130 /**
9131  * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
9132  *
9133  * @private
9134  * @method Player#handleTechTexttrackchange_
9135  * @fires Player#texttrackchange
9136  * @listens Tech#texttrackchange
9137  */
9138 'texttrackchange'];
9139
9140 /**
9141  * An instance of the `Player` class is created when any of the Video.js setup methods
9142  * are used to initialize a video.
9143  *
9144  * After an instance has been created it can be accessed globally in two ways:
9145  * 1. By calling `videojs('example_video_1');`
9146  * 2. By using it directly via  `videojs.players.example_video_1;`
9147  *
9148  * @extends Component
9149  */
9150
9151 var Player = function (_Component) {
9152   _inherits(Player, _Component);
9153
9154   /**
9155    * Create an instance of this class.
9156    *
9157    * @param {Element} tag
9158    *        The original video DOM element used for configuring options.
9159    *
9160    * @param {Object} [options]
9161    *        Object of option names and values.
9162    *
9163    * @param {Component~ReadyCallback} [ready]
9164    *        Ready callback function.
9165    */
9166   function Player(tag, options, ready) {
9167     _classCallCheck(this, Player);
9168
9169     // Make sure tag ID exists
9170     tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
9171
9172     // Set Options
9173     // The options argument overrides options set in the video tag
9174     // which overrides globally set options.
9175     // This latter part coincides with the load order
9176     // (tag must exist before Player)
9177     options = (0, _obj.assign)(Player.getTagSettings(tag), options);
9178
9179     // Delay the initialization of children because we need to set up
9180     // player properties first, and can't use `this` before `super()`
9181     options.initChildren = false;
9182
9183     // Same with creating the element
9184     options.createEl = false;
9185
9186     // we don't want the player to report touch activity on itself
9187     // see enableTouchActivity in Component
9188     options.reportTouchActivity = false;
9189
9190     // If language is not set, get the closest lang attribute
9191     if (!options.language) {
9192       if (typeof tag.closest === 'function') {
9193         var closest = tag.closest('[lang]');
9194
9195         if (closest) {
9196           options.language = closest.getAttribute('lang');
9197         }
9198       } else {
9199         var element = tag;
9200
9201         while (element && element.nodeType === 1) {
9202           if (Dom.getElAttributes(element).hasOwnProperty('lang')) {
9203             options.language = element.getAttribute('lang');
9204             break;
9205           }
9206           element = element.parentNode;
9207         }
9208       }
9209     }
9210
9211     // Run base component initializing with new options
9212
9213     // if the global option object was accidentally blown away by
9214     // someone, bail early with an informative error
9215     var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
9216
9217     if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
9218       throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
9219     }
9220
9221     // Store the original tag used to set options
9222     _this.tag = tag;
9223
9224     // Store the tag attributes used to restore html5 element
9225     _this.tagAttributes = tag && Dom.getElAttributes(tag);
9226
9227     // Update current language
9228     _this.language(_this.options_.language);
9229
9230     // Update Supported Languages
9231     if (options.languages) {
9232       // Normalise player option languages to lowercase
9233       var languagesToLower = {};
9234
9235       Object.getOwnPropertyNames(options.languages).forEach(function (name) {
9236         languagesToLower[name.toLowerCase()] = options.languages[name];
9237       });
9238       _this.languages_ = languagesToLower;
9239     } else {
9240       _this.languages_ = Player.prototype.options_.languages;
9241     }
9242
9243     // Cache for video property values.
9244     _this.cache_ = {};
9245
9246     // Set poster
9247     _this.poster_ = options.poster || '';
9248
9249     // Set controls
9250     _this.controls_ = !!options.controls;
9251
9252     // Original tag settings stored in options
9253     // now remove immediately so native controls don't flash.
9254     // May be turned back on by HTML5 tech if nativeControlsForTouch is true
9255     tag.controls = false;
9256
9257     /*
9258      * Store the internal state of scrubbing
9259      *
9260      * @private
9261      * @return {Boolean} True if the user is scrubbing
9262      */
9263     _this.scrubbing_ = false;
9264
9265     _this.el_ = _this.createEl();
9266
9267     // We also want to pass the original player options to each component and plugin
9268     // as well so they don't need to reach back into the player for options later.
9269     // We also need to do another copy of this.options_ so we don't end up with
9270     // an infinite loop.
9271     var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
9272
9273     // Load plugins
9274     if (options.plugins) {
9275       var plugins = options.plugins;
9276
9277       Object.getOwnPropertyNames(plugins).forEach(function (name) {
9278         if (typeof this[name] === 'function') {
9279           this[name](plugins[name]);
9280         } else {
9281           _log2['default'].error('Unable to find plugin:', name);
9282         }
9283       }, _this);
9284     }
9285
9286     _this.options_.playerOptions = playerOptionsCopy;
9287
9288     _this.initChildren();
9289
9290     // Set isAudio based on whether or not an audio tag was used
9291     _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
9292
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     }
9300
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     }
9308
9309     if (_this.isAudio()) {
9310       _this.addClass('vjs-audio');
9311     }
9312
9313     if (_this.flexNotSupported_()) {
9314       _this.addClass('vjs-no-flex');
9315     }
9316
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     // }
9322
9323     // iOS Safari has broken hover handling
9324     if (!browser.IS_IOS) {
9325       _this.addClass('vjs-workinghover');
9326     }
9327
9328     // Make player easily findable by ID
9329     Player.players[_this.id_] = _this;
9330
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_();
9336
9337     _this.on('fullscreenchange', _this.handleFullscreenChange_);
9338     _this.on('stageclick', _this.handleStageClick_);
9339     return _this;
9340   }
9341
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    */
9350
9351
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');
9362
9363     if (this.styleEl_ && this.styleEl_.parentNode) {
9364       this.styleEl_.parentNode.removeChild(this.styleEl_);
9365     }
9366
9367     // Kill reference to this player
9368     Player.players[this.id_] = null;
9369
9370     if (this.tag && this.tag.player) {
9371       this.tag.player = null;
9372     }
9373
9374     if (this.el_ && this.el_.player) {
9375       this.el_.player = null;
9376     }
9377
9378     if (this.tech_) {
9379       this.tech_.dispose();
9380     }
9381
9382     _Component.prototype.dispose.call(this);
9383   };
9384
9385   /**
9386    * Create the `Player`'s DOM element.
9387    *
9388    * @return {Element}
9389    *         The DOM element that gets created.
9390    */
9391
9392
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 && tag.parentNode.hasAttribute('data-vjs-player');
9397
9398     if (playerElIngest) {
9399       el = this.el_ = tag.parentNode;
9400     } else {
9401       el = this.el_ = _Component.prototype.createEl.call(this, 'div');
9402     }
9403
9404     // set tabindex to -1 so we could focus on the player element
9405     tag.setAttribute('tabindex', '-1');
9406
9407     // Remove width/height attrs from tag so CSS can make it 100% width/height
9408     tag.removeAttribute('width');
9409     tag.removeAttribute('height');
9410
9411     // Copy over all the attributes from the tag, including ID and class
9412     // ID will now reference player box, not the video tag
9413     var attrs = Dom.getElAttributes(tag);
9414
9415     Object.getOwnPropertyNames(attrs).forEach(function (attr) {
9416       // workaround so we don't totally break IE7
9417       // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
9418       if (attr === 'class') {
9419         el.className += ' ' + attrs[attr];
9420       } else {
9421         el.setAttribute(attr, attrs[attr]);
9422       }
9423     });
9424
9425     // Update tag id/class for use as HTML5 playback tech
9426     // Might think we should do this after embedding in container so .vjs-tech class
9427     // doesn't flash 100% width/height, but class only applies with .video-js parent
9428     tag.playerId = tag.id;
9429     tag.id += '_html5_api';
9430     tag.className = 'vjs-tech';
9431
9432     // Make player findable on elements
9433     tag.player = el.player = this;
9434     // Default state of video is paused
9435     this.addClass('vjs-paused');
9436
9437     // Add a style element in the player that we'll use to set the width/height
9438     // of the player in a way that's still overrideable by CSS, just like the
9439     // video element
9440     if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
9441       this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
9442       var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
9443       var head = Dom.$('head');
9444
9445       head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
9446     }
9447
9448     // Pass in the width/height/aspectRatio options which will update the style el
9449     this.width(this.options_.width);
9450     this.height(this.options_.height);
9451     this.fluid(this.options_.fluid);
9452     this.aspectRatio(this.options_.aspectRatio);
9453
9454     // Hide any links within the video/audio tag, because IE doesn't hide them completely.
9455     var links = tag.getElementsByTagName('a');
9456
9457     for (var i = 0; i < links.length; i++) {
9458       var linkEl = links.item(i);
9459
9460       Dom.addElClass(linkEl, 'vjs-hidden');
9461       linkEl.setAttribute('hidden', 'hidden');
9462     }
9463
9464     // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
9465     // keep track of the original for later so we can know if the source originally failed
9466     tag.initNetworkState_ = tag.networkState;
9467
9468     // Wrap video tag in div (el/box) container
9469     if (tag.parentNode && !playerElIngest) {
9470       tag.parentNode.insertBefore(el, tag);
9471     }
9472
9473     // insert the tag as the first child of the player element
9474     // then manually add it to the children array so that this.addChild
9475     // will work properly for other components
9476     //
9477     // Breaks iPhone, fixed in HTML5 setup.
9478     Dom.insertElFirst(tag, el);
9479     this.children_.unshift(tag);
9480
9481     this.el_ = el;
9482
9483     return el;
9484   };
9485
9486   /**
9487    * A getter/setter for the `Player`'s width.
9488    *
9489    * @param {number} [value]
9490    *        The value to set the `Player's width to.
9491    *
9492    * @return {number}
9493    *         The current width of the `Player`.
9494    */
9495
9496
9497   Player.prototype.width = function width(value) {
9498     return this.dimension('width', value);
9499   };
9500
9501   /**
9502    * A getter/setter for the `Player`'s height.
9503    *
9504    * @param {number} [value]
9505    *        The value to set the `Player's heigth to.
9506    *
9507    * @return {number}
9508    *         The current heigth of the `Player`.
9509    */
9510
9511
9512   Player.prototype.height = function height(value) {
9513     return this.dimension('height', value);
9514   };
9515
9516   /**
9517    * A getter/setter for the `Player`'s width & height.
9518    *
9519    * @param {string} dimension
9520    *        This string can be:
9521    *        - 'width'
9522    *        - 'height'
9523    *
9524    * @param {number} [value]
9525    *        Value for dimension specified in the first argument.
9526    *
9527    * @return {Player|number}
9528    *         - Returns itself when setting; method can be chained.
9529    *         - The dimension arguments value when getting (width/height).
9530    */
9531
9532
9533   Player.prototype.dimension = function dimension(_dimension, value) {
9534     var privDimension = _dimension + '_';
9535
9536     if (value === undefined) {
9537       return this[privDimension] || 0;
9538     }
9539
9540     if (value === '') {
9541       // If an empty string is given, reset the dimension to be automatic
9542       this[privDimension] = undefined;
9543     } else {
9544       var parsedVal = parseFloat(value);
9545
9546       if (isNaN(parsedVal)) {
9547         _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
9548         return this;
9549       }
9550
9551       this[privDimension] = parsedVal;
9552     }
9553
9554     this.updateStyleEl_();
9555     return this;
9556   };
9557
9558   /**
9559    * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
9560    *
9561    * @param {boolean} [bool]
9562    *        - A value of true adds the class.
9563    *        - A value of false removes the class.
9564    *        - No value will toggle the fluid class.
9565    *
9566    * @return {boolean|undefined}
9567    *         - The value of fluid when getting.
9568    *         - `undefined` when setting.
9569    */
9570
9571
9572   Player.prototype.fluid = function fluid(bool) {
9573     if (bool === undefined) {
9574       return !!this.fluid_;
9575     }
9576
9577     this.fluid_ = !!bool;
9578
9579     if (bool) {
9580       this.addClass('vjs-fluid');
9581     } else {
9582       this.removeClass('vjs-fluid');
9583     }
9584
9585     this.updateStyleEl_();
9586   };
9587
9588   /**
9589    * Get/Set the aspect ratio
9590    *
9591    * @param {string} [ratio]
9592    *        Aspect ratio for player
9593    *
9594    * @return {string|undefined}
9595    *         returns the current aspect ratio when getting
9596    */
9597
9598   /**
9599    * A getter/setter for the `Player`'s aspect ratio.
9600    *
9601    * @param {string} [ratio]
9602    *        The value to set the `Player's aspect ratio to.
9603    *
9604    * @return {string|undefined}
9605    *         - The current aspect ratio of the `Player` when getting.
9606    *         - undefined when setting
9607    */
9608
9609
9610   Player.prototype.aspectRatio = function aspectRatio(ratio) {
9611     if (ratio === undefined) {
9612       return this.aspectRatio_;
9613     }
9614
9615     // Check for width:height format
9616     if (!/^\d+\:\d+$/.test(ratio)) {
9617       throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
9618     }
9619     this.aspectRatio_ = ratio;
9620
9621     // We're assuming if you set an aspect ratio you want fluid mode,
9622     // because in fixed mode you could calculate width and height yourself.
9623     this.fluid(true);
9624
9625     this.updateStyleEl_();
9626   };
9627
9628   /**
9629    * Update styles of the `Player` element (height, width and aspect ratio).
9630    *
9631    * @private
9632    * @listens Tech#loadedmetadata
9633    */
9634
9635
9636   Player.prototype.updateStyleEl_ = function updateStyleEl_() {
9637     if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
9638       var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
9639       var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
9640       var techEl = this.tech_ && this.tech_.el();
9641
9642       if (techEl) {
9643         if (_width >= 0) {
9644           techEl.width = _width;
9645         }
9646         if (_height >= 0) {
9647           techEl.height = _height;
9648         }
9649       }
9650
9651       return;
9652     }
9653
9654     var width = void 0;
9655     var height = void 0;
9656     var aspectRatio = void 0;
9657     var idClass = void 0;
9658
9659     // The aspect ratio is either used directly or to calculate width and height.
9660     if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
9661       // Use any aspectRatio that's been specifically set
9662       aspectRatio = this.aspectRatio_;
9663     } else if (this.videoWidth() > 0) {
9664       // Otherwise try to get the aspect ratio from the video metadata
9665       aspectRatio = this.videoWidth() + ':' + this.videoHeight();
9666     } else {
9667       // Or use a default. The video element's is 2:1, but 16:9 is more common.
9668       aspectRatio = '16:9';
9669     }
9670
9671     // Get the ratio as a decimal we can use to calculate dimensions
9672     var ratioParts = aspectRatio.split(':');
9673     var ratioMultiplier = ratioParts[1] / ratioParts[0];
9674
9675     if (this.width_ !== undefined) {
9676       // Use any width that's been specifically set
9677       width = this.width_;
9678     } else if (this.height_ !== undefined) {
9679       // Or calulate the width from the aspect ratio if a height has been set
9680       width = this.height_ / ratioMultiplier;
9681     } else {
9682       // Or use the video's metadata, or use the video el's default of 300
9683       width = this.videoWidth() || 300;
9684     }
9685
9686     if (this.height_ !== undefined) {
9687       // Use any height that's been specifically set
9688       height = this.height_;
9689     } else {
9690       // Otherwise calculate the height from the ratio and the width
9691       height = width * ratioMultiplier;
9692     }
9693
9694     // Ensure the CSS class is valid by starting with an alpha character
9695     if (/^[^a-zA-Z]/.test(this.id())) {
9696       idClass = 'dimensions-' + this.id();
9697     } else {
9698       idClass = this.id() + '-dimensions';
9699     }
9700
9701     // Ensure the right class is still on the player for the style element
9702     this.addClass(idClass);
9703
9704     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    ');
9705   };
9706
9707   /**
9708    * Load/Create an instance of playback {@link Tech} including element
9709    * and API methods. Then append the `Tech` element in `Player` as a child.
9710    *
9711    * @param {string} techName
9712    *        name of the playback technology
9713    *
9714    * @param {string} source
9715    *        video source
9716    *
9717    * @private
9718    */
9719
9720
9721   Player.prototype.loadTech_ = function loadTech_(techName, source) {
9722     var _this2 = this;
9723
9724     // Pause and remove current playback technology
9725     if (this.tech_) {
9726       this.unloadTech_();
9727     }
9728
9729     // get rid of the HTML5 video tag as soon as we are using another tech
9730     if (techName !== 'Html5' && this.tag) {
9731       _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
9732       this.tag.player = null;
9733       this.tag = null;
9734     }
9735
9736     this.techName_ = techName;
9737
9738     // Turn off API access because we're loading a new tech that might load asynchronously
9739     this.isReady_ = false;
9740
9741     // Grab tech-specific options from player options and add source and parent element to use.
9742     var techOptions = (0, _obj.assign)({
9743       source: source,
9744       'nativeControlsForTouch': this.options_.nativeControlsForTouch,
9745       'playerId': this.id(),
9746       'techId': this.id() + '_' + techName + '_api',
9747       'videoTracks': this.videoTracks_,
9748       'textTracks': this.textTracks_,
9749       'audioTracks': this.audioTracks_,
9750       'autoplay': this.options_.autoplay,
9751       'preload': this.options_.preload,
9752       'loop': this.options_.loop,
9753       'muted': this.options_.muted,
9754       'poster': this.poster(),
9755       'language': this.language(),
9756       'playerElIngest': this.playerElIngest_ || false,
9757       'vtt.js': this.options_['vtt.js']
9758     }, this.options_[techName.toLowerCase()]);
9759
9760     if (this.tag) {
9761       techOptions.tag = this.tag;
9762     }
9763
9764     if (source) {
9765       this.currentType_ = source.type;
9766
9767       if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
9768         techOptions.startTime = this.cache_.currentTime;
9769       }
9770
9771       this.cache_.sources = null;
9772       this.cache_.source = source;
9773       this.cache_.src = source.src;
9774     }
9775
9776     // Initialize tech instance
9777     var TechComponent = _tech2['default'].getTech(techName);
9778
9779     // Support old behavior of techs being registered as components.
9780     // Remove once that deprecated behavior is removed.
9781     if (!TechComponent) {
9782       TechComponent = _component2['default'].getComponent(techName);
9783     }
9784     this.tech_ = new TechComponent(techOptions);
9785
9786     // player.triggerReady is always async, so don't need this to be async
9787     this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
9788
9789     _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
9790
9791     // Listen to all HTML5-defined events and trigger them on the player
9792     TECH_EVENTS_RETRIGGER.forEach(function (event) {
9793       _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
9794     });
9795     this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
9796     this.on(this.tech_, 'waiting', this.handleTechWaiting_);
9797     this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
9798     this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
9799     this.on(this.tech_, 'playing', this.handleTechPlaying_);
9800     this.on(this.tech_, 'ended', this.handleTechEnded_);
9801     this.on(this.tech_, 'seeking', this.handleTechSeeking_);
9802     this.on(this.tech_, 'seeked', this.handleTechSeeked_);
9803     this.on(this.tech_, 'play', this.handleTechPlay_);
9804     this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
9805     this.on(this.tech_, 'pause', this.handleTechPause_);
9806     this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
9807     this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
9808     this.on(this.tech_, 'error', this.handleTechError_);
9809     this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
9810     this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
9811     this.on(this.tech_, 'textdata', this.handleTechTextData_);
9812
9813     this.usingNativeControls(this.techGet_('controls'));
9814
9815     if (this.controls() && !this.usingNativeControls()) {
9816       this.addTechControlsListeners_();
9817     }
9818
9819     // Add the tech element in the DOM if it was not already there
9820     // Make sure to not insert the original video element if using Html5
9821     if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
9822       Dom.insertElFirst(this.tech_.el(), this.el());
9823     }
9824
9825     // Get rid of the original video tag reference after the first tech is loaded
9826     if (this.tag) {
9827       this.tag.player = null;
9828       this.tag = null;
9829     }
9830   };
9831
9832   /**
9833    * Unload and dispose of the current playback {@link Tech}.
9834    *
9835    * @private
9836    */
9837
9838
9839   Player.prototype.unloadTech_ = function unloadTech_() {
9840     // Save the current text tracks so that we can reuse the same text tracks with the next tech
9841     this.videoTracks_ = this.videoTracks();
9842     this.textTracks_ = this.textTracks();
9843     this.audioTracks_ = this.audioTracks();
9844     this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
9845
9846     this.isReady_ = false;
9847
9848     this.tech_.dispose();
9849
9850     this.tech_ = false;
9851   };
9852
9853   /**
9854    * Return a reference to the current {@link Tech}, but only if given an object with the
9855    * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse
9856    * of techs by plugins.
9857    *
9858    * @param {Object} safety
9859    *        An object that must contain `{IWillNotUseThisInPlugins: true}`
9860    *
9861    * @param {boolean} safety.IWillNotUseThisInPlugins
9862    *        Must be set to true or else this function will throw an error.
9863    *
9864    * @return {Tech}
9865    *         The Tech
9866    */
9867
9868
9869   Player.prototype.tech = function tech(safety) {
9870     if (safety && safety.IWillNotUseThisInPlugins) {
9871       return this.tech_;
9872     }
9873     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    ';
9874
9875     _window2['default'].alert(errorText);
9876     throw new Error(errorText);
9877   };
9878
9879   /**
9880    * Set up click and touch listeners for the playback element
9881    *
9882    * - On desktops: a click on the video itself will toggle playback
9883    * - On mobile devices: a click on the video toggles controls
9884    *   which is done by toggling the user state between active and
9885    *   inactive
9886    * - A tap can signal that a user has become active or has become inactive
9887    *   e.g. a quick tap on an iPhone movie should reveal the controls. Another
9888    *   quick tap should hide them again (signaling the user is in an inactive
9889    *   viewing state)
9890    * - In addition to this, we still want the user to be considered inactive after
9891    *   a few seconds of inactivity.
9892    *
9893    * > Note: the only part of iOS interaction we can't mimic with this setup
9894    * is a touch and hold on the video element counting as activity in order to
9895    * keep the controls showing, but that shouldn't be an issue. A touch and hold
9896    * on any controls will still keep the user active
9897    *
9898    * @private
9899    */
9900
9901
9902   Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
9903     // Make sure to remove all the previous listeners in case we are called multiple times.
9904     this.removeTechControlsListeners_();
9905
9906     // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
9907     // trigger mousedown/up.
9908     // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
9909     // Any touch events are set to block the mousedown event from happening
9910     this.on(this.tech_, 'mousedown', this.handleTechClick_);
9911
9912     // If the controls were hidden we don't want that to change without a tap event
9913     // so we'll check if the controls were already showing before reporting user
9914     // activity
9915     this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
9916     this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
9917     this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
9918
9919     // The tap listener needs to come after the touchend listener because the tap
9920     // listener cancels out any reportedUserActivity when setting userActive(false)
9921     this.on(this.tech_, 'tap', this.handleTechTap_);
9922   };
9923
9924   /**
9925    * Remove the listeners used for click and tap controls. This is needed for
9926    * toggling to controls disabled, where a tap/touch should do nothing.
9927    *
9928    * @private
9929    */
9930
9931
9932   Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
9933     // We don't want to just use `this.off()` because there might be other needed
9934     // listeners added by techs that extend this.
9935     this.off(this.tech_, 'tap', this.handleTechTap_);
9936     this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
9937     this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
9938     this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
9939     this.off(this.tech_, 'mousedown', this.handleTechClick_);
9940   };
9941
9942   /**
9943    * Player waits for the tech to be ready
9944    *
9945    * @private
9946    */
9947
9948
9949   Player.prototype.handleTechReady_ = function handleTechReady_() {
9950     this.triggerReady();
9951
9952     // Keep the same volume as before
9953     if (this.cache_.volume) {
9954       this.techCall_('setVolume', this.cache_.volume);
9955     }
9956
9957     // Look if the tech found a higher resolution poster while loading
9958     this.handleTechPosterChange_();
9959
9960     // Update the duration if available
9961     this.handleTechDurationChange_();
9962
9963     // Chrome and Safari both have issues with autoplay.
9964     // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
9965     // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
9966     // This fixes both issues. Need to wait for API, so it updates displays correctly
9967     if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
9968       try {
9969         // Chrome Fix. Fixed in Chrome v16.
9970         delete this.tag.poster;
9971       } catch (e) {
9972         (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
9973       }
9974       this.play();
9975     }
9976   };
9977
9978   /**
9979    * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
9980    * function will also trigger {@link Player#firstplay} if it is the first loadstart
9981    * for a video.
9982    *
9983    * @fires Player#loadstart
9984    * @fires Player#firstplay
9985    * @listens Tech#loadstart
9986    * @private
9987    */
9988
9989
9990   Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
9991     // TODO: Update to use `emptied` event instead. See #1277.
9992
9993     this.removeClass('vjs-ended');
9994     this.removeClass('vjs-seeking');
9995
9996     // reset the error state
9997     this.error(null);
9998
9999     // If it's already playing we want to trigger a firstplay event now.
10000     // The firstplay event relies on both the play and loadstart events
10001     // which can happen in any order for a new source
10002     if (!this.paused()) {
10003       /**
10004        * Fired when the user agent begins looking for media data
10005        *
10006        * @event Player#loadstart
10007        * @type {EventTarget~Event}
10008        */
10009       this.trigger('loadstart');
10010       this.trigger('firstplay');
10011     } else {
10012       // reset the hasStarted state
10013       this.hasStarted(false);
10014       this.trigger('loadstart');
10015     }
10016   };
10017
10018   /**
10019    * Add/remove the vjs-has-started class
10020    *
10021    * @fires Player#firstplay
10022    *
10023    * @param {boolean} hasStarted
10024    *        - true: adds the class
10025    *        - false: remove the class
10026    *
10027    * @return {boolean}
10028    *         the boolean value of hasStarted
10029    */
10030
10031
10032   Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10033     if (_hasStarted !== undefined) {
10034       // only update if this is a new value
10035       if (this.hasStarted_ !== _hasStarted) {
10036         this.hasStarted_ = _hasStarted;
10037         if (_hasStarted) {
10038           this.addClass('vjs-has-started');
10039           // trigger the firstplay event if this newly has played
10040           this.trigger('firstplay');
10041         } else {
10042           this.removeClass('vjs-has-started');
10043         }
10044       }
10045       return this;
10046     }
10047     return !!this.hasStarted_;
10048   };
10049
10050   /**
10051    * Fired whenever the media begins or resumes playback
10052    *
10053    * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
10054    * @fires Player#play
10055    * @listens Tech#play
10056    * @private
10057    */
10058
10059
10060   Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10061     this.removeClass('vjs-ended');
10062     this.removeClass('vjs-paused');
10063     this.addClass('vjs-playing');
10064
10065     // hide the poster when the user hits play
10066     this.hasStarted(true);
10067     /**
10068      * Triggered whenever an {@link Tech#play} event happens. Indicates that
10069      * playback has started or resumed.
10070      *
10071      * @event Player#play
10072      * @type {EventTarget~Event}
10073      */
10074     this.trigger('play');
10075   };
10076
10077   /**
10078    * Retrigger the `waiting` event that was triggered by the {@link Tech}.
10079    *
10080    * @fires Player#waiting
10081    * @listens Tech#waiting
10082    * @private
10083    */
10084
10085
10086   Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10087     var _this3 = this;
10088
10089     this.addClass('vjs-waiting');
10090     /**
10091      * A readyState change on the DOM element has caused playback to stop.
10092      *
10093      * @event Player#waiting
10094      * @type {EventTarget~Event}
10095      */
10096     this.trigger('waiting');
10097     this.one('timeupdate', function () {
10098       return _this3.removeClass('vjs-waiting');
10099     });
10100   };
10101
10102   /**
10103    * Retrigger the `canplay` event that was triggered by the {@link Tech}.
10104    * > Note: This is not consistent between browsers. See #1351
10105    *
10106    * @fires Player#canplay
10107    * @listens Tech#canplay
10108    * @private
10109    */
10110
10111
10112   Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10113     this.removeClass('vjs-waiting');
10114     /**
10115      * The media has a readyState of HAVE_FUTURE_DATA or greater.
10116      *
10117      * @event Player#canplay
10118      * @type {EventTarget~Event}
10119      */
10120     this.trigger('canplay');
10121   };
10122
10123   /**
10124    * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
10125    *
10126    * @fires Player#canplaythrough
10127    * @listens Tech#canplaythrough
10128    * @private
10129    */
10130
10131
10132   Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10133     this.removeClass('vjs-waiting');
10134     /**
10135      * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
10136      * entire media file can be played without buffering.
10137      *
10138      * @event Player#canplaythrough
10139      * @type {EventTarget~Event}
10140      */
10141     this.trigger('canplaythrough');
10142   };
10143
10144   /**
10145    * Retrigger the `playing` event that was triggered by the {@link Tech}.
10146    *
10147    * @fires Player#playing
10148    * @listens Tech#playing
10149    * @private
10150    */
10151
10152
10153   Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
10154     this.removeClass('vjs-waiting');
10155     /**
10156      * The media is no longer blocked from playback, and has started playing.
10157      *
10158      * @event Player#playing
10159      * @type {EventTarget~Event}
10160      */
10161     this.trigger('playing');
10162   };
10163
10164   /**
10165    * Retrigger the `seeking` event that was triggered by the {@link Tech}.
10166    *
10167    * @fires Player#seeking
10168    * @listens Tech#seeking
10169    * @private
10170    */
10171
10172
10173   Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
10174     this.addClass('vjs-seeking');
10175     /**
10176      * Fired whenever the player is jumping to a new time
10177      *
10178      * @event Player#seeking
10179      * @type {EventTarget~Event}
10180      */
10181     this.trigger('seeking');
10182   };
10183
10184   /**
10185    * Retrigger the `seeked` event that was triggered by the {@link Tech}.
10186    *
10187    * @fires Player#seeked
10188    * @listens Tech#seeked
10189    * @private
10190    */
10191
10192
10193   Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
10194     this.removeClass('vjs-seeking');
10195     /**
10196      * Fired when the player has finished jumping to a new time
10197      *
10198      * @event Player#seeked
10199      * @type {EventTarget~Event}
10200      */
10201     this.trigger('seeked');
10202   };
10203
10204   /**
10205    * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
10206    *
10207    * @fires Player#firstplay
10208    * @listens Tech#firstplay
10209    * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
10210    * @private
10211    */
10212
10213
10214   Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
10215     // If the first starttime attribute is specified
10216     // then we will start at the given offset in seconds
10217     if (this.options_.starttime) {
10218       _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
10219       this.currentTime(this.options_.starttime);
10220     }
10221
10222     this.addClass('vjs-has-started');
10223     /**
10224      * Fired the first time a video is played. Not part of the HLS spec, and this is
10225      * probably not the best implementation yet, so use sparingly. If you don't have a
10226      * reason to prevent playback, use `myPlayer.one('play');` instead.
10227      *
10228      * @event Player#firstplay
10229      * @type {EventTarget~Event}
10230      */
10231     this.trigger('firstplay');
10232   };
10233
10234   /**
10235    * Retrigger the `pause` event that was triggered by the {@link Tech}.
10236    *
10237    * @fires Player#pause
10238    * @listens Tech#pause
10239    * @private
10240    */
10241
10242
10243   Player.prototype.handleTechPause_ = function handleTechPause_() {
10244     this.removeClass('vjs-playing');
10245     this.addClass('vjs-paused');
10246     /**
10247      * Fired whenever the media has been paused
10248      *
10249      * @event Player#pause
10250      * @type {EventTarget~Event}
10251      */
10252     this.trigger('pause');
10253   };
10254
10255   /**
10256    * Retrigger the `ended` event that was triggered by the {@link Tech}.
10257    *
10258    * @fires Player#ended
10259    * @listens Tech#ended
10260    * @private
10261    */
10262
10263
10264   Player.prototype.handleTechEnded_ = function handleTechEnded_() {
10265     this.addClass('vjs-ended');
10266     if (this.options_.loop) {
10267       this.currentTime(0);
10268       this.play();
10269     } else if (!this.paused()) {
10270       this.pause();
10271     }
10272
10273     /**
10274      * Fired when the end of the media resource is reached (currentTime == duration)
10275      *
10276      * @event Player#ended
10277      * @type {EventTarget~Event}
10278      */
10279     this.trigger('ended');
10280   };
10281
10282   /**
10283    * Fired when the duration of the media resource is first known or changed
10284    *
10285    * @listens Tech#durationchange
10286    * @private
10287    */
10288
10289
10290   Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
10291     this.duration(this.techGet_('duration'));
10292   };
10293
10294   /**
10295    * Handle a click on the media element to play/pause
10296    *
10297    * @param {EventTarget~Event} event
10298    *        the event that caused this function to trigger
10299    *
10300    * @listens Tech#mousedown
10301    * @private
10302    */
10303
10304
10305   Player.prototype.handleTechClick_ = function handleTechClick_(event) {
10306     // We're using mousedown to detect clicks thanks to Flash, but mousedown
10307     // will also be triggered with right-clicks, so we need to prevent that
10308     if (event.button !== 0) {
10309       return;
10310     }
10311
10312     // When controls are disabled a click should not toggle playback because
10313     // the click is considered a control
10314     if (this.controls()) {
10315       if (this.paused()) {
10316         this.play();
10317       } else {
10318         this.pause();
10319       }
10320     }
10321   };
10322
10323   /**
10324    * Handle a tap on the media element. It will toggle the user
10325    * activity state, which hides and shows the controls.
10326    *
10327    * @listens Tech#tap
10328    * @private
10329    */
10330
10331
10332   Player.prototype.handleTechTap_ = function handleTechTap_() {
10333     this.userActive(!this.userActive());
10334   };
10335
10336   /**
10337    * Handle touch to start
10338    *
10339    * @listens Tech#touchstart
10340    * @private
10341    */
10342
10343
10344   Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
10345     this.userWasActive = this.userActive();
10346   };
10347
10348   /**
10349    * Handle touch to move
10350    *
10351    * @listens Tech#touchmove
10352    * @private
10353    */
10354
10355
10356   Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
10357     if (this.userWasActive) {
10358       this.reportUserActivity();
10359     }
10360   };
10361
10362   /**
10363    * Handle touch to end
10364    *
10365    * @param {EventTarget~Event} event
10366    *        the touchend event that triggered
10367    *        this function
10368    *
10369    * @listens Tech#touchend
10370    * @private
10371    */
10372
10373
10374   Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
10375     // Stop the mouse events from also happening
10376     event.preventDefault();
10377   };
10378
10379   /**
10380    * Fired when the player switches in or out of fullscreen mode
10381    *
10382    * @private
10383    * @listens Player#fullscreenchange
10384    */
10385
10386
10387   Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
10388     if (this.isFullscreen()) {
10389       this.addClass('vjs-fullscreen');
10390     } else {
10391       this.removeClass('vjs-fullscreen');
10392     }
10393   };
10394
10395   /**
10396    * native click events on the SWF aren't triggered on IE11, Win8.1RT
10397    * use stageclick events triggered from inside the SWF instead
10398    *
10399    * @private
10400    * @listens stageclick
10401    */
10402
10403
10404   Player.prototype.handleStageClick_ = function handleStageClick_() {
10405     this.reportUserActivity();
10406   };
10407
10408   /**
10409    * Handle Tech Fullscreen Change
10410    *
10411    * @param {EventTarget~Event} event
10412    *        the fullscreenchange event that triggered this function
10413    *
10414    * @param {Object} data
10415    *        the data that was sent with the event
10416    *
10417    * @private
10418    * @listens Tech#fullscreenchange
10419    * @fires Player#fullscreenchange
10420    */
10421
10422
10423   Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
10424     if (data) {
10425       this.isFullscreen(data.isFullscreen);
10426     }
10427     /**
10428      * Fired when going in and out of fullscreen.
10429      *
10430      * @event Player#fullscreenchange
10431      * @type {EventTarget~Event}
10432      */
10433     this.trigger('fullscreenchange');
10434   };
10435
10436   /**
10437    * Fires when an error occurred during the loading of an audio/video.
10438    *
10439    * @private
10440    * @listens Tech#error
10441    */
10442
10443
10444   Player.prototype.handleTechError_ = function handleTechError_() {
10445     var error = this.tech_.error();
10446
10447     this.error(error);
10448   };
10449
10450   /**
10451    * Retrigger the `textdata` event that was triggered by the {@link Tech}.
10452    *
10453    * @fires Player#textdata
10454    * @listens Tech#textdata
10455    * @private
10456    */
10457
10458
10459   Player.prototype.handleTechTextData_ = function handleTechTextData_() {
10460     var data = null;
10461
10462     if (arguments.length > 1) {
10463       data = arguments[1];
10464     }
10465
10466     /**
10467      * Fires when we get a textdata event from tech
10468      *
10469      * @event Player#textdata
10470      * @type {EventTarget~Event}
10471      */
10472     this.trigger('textdata', data);
10473   };
10474
10475   /**
10476    * Get object for cached values.
10477    *
10478    * @return {Object}
10479    *         get the current object cache
10480    */
10481
10482
10483   Player.prototype.getCache = function getCache() {
10484     return this.cache_;
10485   };
10486
10487   /**
10488    * Pass values to the playback tech
10489    *
10490    * @param {string} [method]
10491    *        the method to call
10492    *
10493    * @param {Object} arg
10494    *        the argument to pass
10495    *
10496    * @private
10497    */
10498
10499
10500   Player.prototype.techCall_ = function techCall_(method, arg) {
10501     // If it's not ready yet, call method when it is
10502     if (this.tech_ && !this.tech_.isReady_) {
10503       this.tech_.ready(function () {
10504         this[method](arg);
10505       }, true);
10506
10507       // Otherwise call method now
10508     } else {
10509       try {
10510         if (this.tech_) {
10511           this.tech_[method](arg);
10512         }
10513       } catch (e) {
10514         (0, _log2['default'])(e);
10515         throw e;
10516       }
10517     }
10518   };
10519
10520   /**
10521    * Get calls can't wait for the tech, and sometimes don't need to.
10522    *
10523    * @param {string} method
10524    *        Tech method
10525    *
10526    * @return {Function|undefined}
10527    *         the method or undefined
10528    *
10529    * @private
10530    */
10531
10532
10533   Player.prototype.techGet_ = function techGet_(method) {
10534     if (this.tech_ && this.tech_.isReady_) {
10535
10536       // Flash likes to die and reload when you hide or reposition it.
10537       // In these cases the object methods go away and we get errors.
10538       // When that happens we'll catch the errors and inform tech that it's not ready any more.
10539       try {
10540         return this.tech_[method]();
10541       } catch (e) {
10542         // When building additional tech libs, an expected method may not be defined yet
10543         if (this.tech_[method] === undefined) {
10544           (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
10545
10546           // When a method isn't available on the object it throws a TypeError
10547         } else if (e.name === 'TypeError') {
10548           (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
10549           this.tech_.isReady_ = false;
10550         } else {
10551           (0, _log2['default'])(e);
10552         }
10553         throw e;
10554       }
10555     }
10556
10557     return;
10558   };
10559
10560   /**
10561    * start media playback
10562    *
10563    * @return {Player}
10564    *         A reference to the player object this function was called on
10565    */
10566
10567
10568   Player.prototype.play = function play() {
10569     // Only calls the tech's play if we already have a src loaded
10570     if (this.src() || this.currentSrc()) {
10571       this.techCall_('play');
10572     } else {
10573       this.tech_.one('loadstart', function () {
10574         this.play();
10575       });
10576     }
10577
10578     return this;
10579   };
10580
10581   /**
10582    * Pause the video playback
10583    *
10584    * @return {Player}
10585    *         A reference to the player object this function was called on
10586    */
10587
10588
10589   Player.prototype.pause = function pause() {
10590     this.techCall_('pause');
10591     return this;
10592   };
10593
10594   /**
10595    * Check if the player is paused or has yet to play
10596    *
10597    * @return {boolean}
10598    *         - false: if the media is currently playing
10599    *         - true: if media is not currently playing
10600    */
10601
10602
10603   Player.prototype.paused = function paused() {
10604     // The initial state of paused should be true (in Safari it's actually false)
10605     return this.techGet_('paused') === false ? false : true;
10606   };
10607
10608   /**
10609    * Returns whether or not the user is "scrubbing". Scrubbing is
10610    * when the user has clicked the progress bar handle and is
10611    * dragging it along the progress bar.
10612    *
10613    * @param {boolean} [isScrubbing]
10614    *        wether the user is or is not scrubbing
10615    *
10616    * @return {boolean|Player}
10617    *         A instance of the player that called this function when setting,
10618    *         and the value of scrubbing when getting
10619    */
10620
10621
10622   Player.prototype.scrubbing = function scrubbing(isScrubbing) {
10623     if (isScrubbing !== undefined) {
10624       this.scrubbing_ = !!isScrubbing;
10625
10626       if (isScrubbing) {
10627         this.addClass('vjs-scrubbing');
10628       } else {
10629         this.removeClass('vjs-scrubbing');
10630       }
10631
10632       return this;
10633     }
10634
10635     return this.scrubbing_;
10636   };
10637
10638   /**
10639    * Get or set the current time (in seconds)
10640    *
10641    * @param {number|string} [seconds]
10642    *        The time to seek to in seconds
10643    *
10644    * @return {Player|number}
10645    *         - the current time in seconds when getting
10646    *         - a reference to the current player object when setting
10647    */
10648
10649
10650   Player.prototype.currentTime = function currentTime(seconds) {
10651     if (seconds !== undefined) {
10652
10653       this.techCall_('setCurrentTime', seconds);
10654
10655       return this;
10656     }
10657
10658     // cache last currentTime and return. default to 0 seconds
10659     //
10660     // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10661     // currentTime when scrubbing, but may not provide much performance benefit afterall.
10662     // Should be tested. Also something has to read the actual current time or the cache will
10663     // never get updated.
10664     this.cache_.currentTime = this.techGet_('currentTime') || 0;
10665     return this.cache_.currentTime;
10666   };
10667
10668   /**
10669    * Normally gets the length in time of the video in seconds;
10670    * in all but the rarest use cases an argument will NOT be passed to the method
10671    *
10672    * > **NOTE**: The video must have started loading before the duration can be
10673    * known, and in the case of Flash, may not be known until the video starts
10674    * playing.
10675    *
10676    * @fires Player#durationchange
10677    *
10678    * @param {number} [seconds]
10679    *        The duration of the video to set in seconds
10680    *
10681    * @return {number|Player}
10682    *         - The duration of the video in seconds when getting
10683    *         - A reference to the player that called this function
10684    *           when setting
10685    */
10686
10687
10688   Player.prototype.duration = function duration(seconds) {
10689     if (seconds === undefined) {
10690       return this.cache_.duration || 0;
10691     }
10692
10693     seconds = parseFloat(seconds) || 0;
10694
10695     // Standardize on Inifity for signaling video is live
10696     if (seconds < 0) {
10697       seconds = Infinity;
10698     }
10699
10700     if (seconds !== this.cache_.duration) {
10701       // Cache the last set value for optimized scrubbing (esp. Flash)
10702       this.cache_.duration = seconds;
10703
10704       if (seconds === Infinity) {
10705         this.addClass('vjs-live');
10706       } else {
10707         this.removeClass('vjs-live');
10708       }
10709       /**
10710        * @event Player#durationchange
10711        * @type {EventTarget~Event}
10712        */
10713       this.trigger('durationchange');
10714     }
10715
10716     return this;
10717   };
10718
10719   /**
10720    * Calculates how much time is left in the video. Not part
10721    * of the native video API.
10722    *
10723    * @return {number}
10724    *         The time remaining in seconds
10725    */
10726
10727
10728   Player.prototype.remainingTime = function remainingTime() {
10729     return this.duration() - this.currentTime();
10730   };
10731
10732   //
10733   // Kind of like an array of portions of the video that have been downloaded.
10734
10735   /**
10736    * Get a TimeRange object with an array of the times of the video
10737    * that have been downloaded. If you just want the percent of the
10738    * video that's been downloaded, use bufferedPercent.
10739    *
10740    * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
10741    *
10742    * @return {TimeRange}
10743    *         A mock TimeRange object (following HTML spec)
10744    */
10745
10746
10747   Player.prototype.buffered = function buffered() {
10748     var buffered = this.techGet_('buffered');
10749
10750     if (!buffered || !buffered.length) {
10751       buffered = (0, _timeRanges.createTimeRange)(0, 0);
10752     }
10753
10754     return buffered;
10755   };
10756
10757   /**
10758    * Get the percent (as a decimal) of the video that's been downloaded.
10759    * This method is not a part of the native HTML video API.
10760    *
10761    * @return {number}
10762    *         A decimal between 0 and 1 representing the percent
10763    *         that is bufferred 0 being 0% and 1 being 100%
10764    */
10765
10766
10767   Player.prototype.bufferedPercent = function bufferedPercent() {
10768     return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
10769   };
10770
10771   /**
10772    * Get the ending time of the last buffered time range
10773    * This is used in the progress bar to encapsulate all time ranges.
10774    *
10775    * @return {number}
10776    *         The end of the last buffered time range
10777    */
10778
10779
10780   Player.prototype.bufferedEnd = function bufferedEnd() {
10781     var buffered = this.buffered();
10782     var duration = this.duration();
10783     var end = buffered.end(buffered.length - 1);
10784
10785     if (end > duration) {
10786       end = duration;
10787     }
10788
10789     return end;
10790   };
10791
10792   /**
10793    * Get or set the current volume of the media
10794    *
10795    * @param  {number} [percentAsDecimal]
10796    *         The new volume as a decimal percent:
10797    *         - 0 is muted/0%/off
10798    *         - 1.0 is 100%/full
10799    *         - 0.5 is half volume or 50%
10800    *
10801    * @return {Player|number}
10802    *         a reference to the calling player when setting and the
10803    *         current volume as a percent when getting
10804    */
10805
10806
10807   Player.prototype.volume = function volume(percentAsDecimal) {
10808     var vol = void 0;
10809
10810     if (percentAsDecimal !== undefined) {
10811       // Force value to between 0 and 1
10812       vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
10813       this.cache_.volume = vol;
10814       this.techCall_('setVolume', vol);
10815
10816       return this;
10817     }
10818
10819     // Default to 1 when returning current volume.
10820     vol = parseFloat(this.techGet_('volume'));
10821     return isNaN(vol) ? 1 : vol;
10822   };
10823
10824   /**
10825    * Get the current muted state, or turn mute on or off
10826    *
10827    * @param {boolean} [muted]
10828    *        - true to mute
10829    *        - false to unmute
10830    *
10831    * @return {boolean|Player}
10832    *         - true if mute is on and getting
10833    *         - false if mute is off and getting
10834    *         - A reference to the current player when setting
10835    */
10836
10837
10838   Player.prototype.muted = function muted(_muted) {
10839     if (_muted !== undefined) {
10840       this.techCall_('setMuted', _muted);
10841       return this;
10842     }
10843     return this.techGet_('muted') || false;
10844   };
10845
10846   /**
10847    * Check if current tech can support native fullscreen
10848    * (e.g. with built in controls like iOS, so not our flash swf)
10849    *
10850    * @return {boolean}
10851    *         if native fullscreen is supported
10852    */
10853
10854
10855   Player.prototype.supportsFullScreen = function supportsFullScreen() {
10856     return this.techGet_('supportsFullScreen') || false;
10857   };
10858
10859   /**
10860    * Check if the player is in fullscreen mode or tell the player that it
10861    * is or is not in fullscreen mode.
10862    *
10863    * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
10864    * property and instead document.fullscreenElement is used. But isFullscreen is
10865    * still a valuable property for internal player workings.
10866    *
10867    * @param  {boolean} [isFS]
10868    *         Set the players current fullscreen state
10869    *
10870    * @return {boolean|Player}
10871    *         - true if fullscreen is on and getting
10872    *         - false if fullscreen is off and getting
10873    *         - A reference to the current player when setting
10874    */
10875
10876
10877   Player.prototype.isFullscreen = function isFullscreen(isFS) {
10878     if (isFS !== undefined) {
10879       this.isFullscreen_ = !!isFS;
10880       return this;
10881     }
10882     return !!this.isFullscreen_;
10883   };
10884
10885   /**
10886    * Increase the size of the video to full screen
10887    * In some browsers, full screen is not supported natively, so it enters
10888    * "full window mode", where the video fills the browser window.
10889    * In browsers and devices that support native full screen, sometimes the
10890    * browser's default controls will be shown, and not the Video.js custom skin.
10891    * This includes most mobile devices (iOS, Android) and older versions of
10892    * Safari.
10893    *
10894    * @fires Player#fullscreenchange
10895    * @return {Player}
10896    *         A reference to the current player
10897    */
10898
10899
10900   Player.prototype.requestFullscreen = function requestFullscreen() {
10901     var fsApi = _fullscreenApi2['default'];
10902
10903     this.isFullscreen(true);
10904
10905     if (fsApi.requestFullscreen) {
10906       // the browser supports going fullscreen at the element level so we can
10907       // take the controls fullscreen as well as the video
10908
10909       // Trigger fullscreenchange event after change
10910       // We have to specifically add this each time, and remove
10911       // when canceling fullscreen. Otherwise if there's multiple
10912       // players on a page, they would all be reacting to the same fullscreen
10913       // events
10914       Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
10915         this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
10916
10917         // If cancelling fullscreen, remove event listener.
10918         if (this.isFullscreen() === false) {
10919           Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
10920         }
10921         /**
10922          * @event Player#fullscreenchange
10923          * @type {EventTarget~Event}
10924          */
10925         this.trigger('fullscreenchange');
10926       }));
10927
10928       this.el_[fsApi.requestFullscreen]();
10929     } else if (this.tech_.supportsFullScreen()) {
10930       // we can't take the video.js controls fullscreen but we can go fullscreen
10931       // with native controls
10932       this.techCall_('enterFullScreen');
10933     } else {
10934       // fullscreen isn't supported so we'll just stretch the video element to
10935       // fill the viewport
10936       this.enterFullWindow();
10937       /**
10938        * @event Player#fullscreenchange
10939        * @type {EventTarget~Event}
10940        */
10941       this.trigger('fullscreenchange');
10942     }
10943
10944     return this;
10945   };
10946
10947   /**
10948    * Return the video to its normal size after having been in full screen mode
10949    *
10950    * @fires Player#fullscreenchange
10951    *
10952    * @return {Player}
10953    *         A reference to the current player
10954    */
10955
10956
10957   Player.prototype.exitFullscreen = function exitFullscreen() {
10958     var fsApi = _fullscreenApi2['default'];
10959
10960     this.isFullscreen(false);
10961
10962     // Check for browser element fullscreen support
10963     if (fsApi.requestFullscreen) {
10964       _document2['default'][fsApi.exitFullscreen]();
10965     } else if (this.tech_.supportsFullScreen()) {
10966       this.techCall_('exitFullScreen');
10967     } else {
10968       this.exitFullWindow();
10969       /**
10970        * @event Player#fullscreenchange
10971        * @type {EventTarget~Event}
10972        */
10973       this.trigger('fullscreenchange');
10974     }
10975
10976     return this;
10977   };
10978
10979   /**
10980    * When fullscreen isn't supported we can stretch the
10981    * video container to as wide as the browser will let us.
10982    *
10983    * @fires Player#enterFullWindow
10984    */
10985
10986
10987   Player.prototype.enterFullWindow = function enterFullWindow() {
10988     this.isFullWindow = true;
10989
10990     // Storing original doc overflow value to return to when fullscreen is off
10991     this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
10992
10993     // Add listener for esc key to exit fullscreen
10994     Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
10995
10996     // Hide any scroll bars
10997     _document2['default'].documentElement.style.overflow = 'hidden';
10998
10999     // Apply fullscreen styles
11000     Dom.addElClass(_document2['default'].body, 'vjs-full-window');
11001
11002     /**
11003      * @event Player#enterFullWindow
11004      * @type {EventTarget~Event}
11005      */
11006     this.trigger('enterFullWindow');
11007   };
11008
11009   /**
11010    * Check for call to either exit full window or
11011    * full screen on ESC key
11012    *
11013    * @param {string} event
11014    *        Event to check for key press
11015    */
11016
11017
11018   Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11019     if (event.keyCode === 27) {
11020       if (this.isFullscreen() === true) {
11021         this.exitFullscreen();
11022       } else {
11023         this.exitFullWindow();
11024       }
11025     }
11026   };
11027
11028   /**
11029    * Exit full window
11030    *
11031    * @fires Player#exitFullWindow
11032    */
11033
11034
11035   Player.prototype.exitFullWindow = function exitFullWindow() {
11036     this.isFullWindow = false;
11037     Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
11038
11039     // Unhide scroll bars.
11040     _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
11041
11042     // Remove fullscreen styles
11043     Dom.removeElClass(_document2['default'].body, 'vjs-full-window');
11044
11045     // Resize the box, controller, and poster to original sizes
11046     // this.positionAll();
11047     /**
11048      * @event Player#exitFullWindow
11049      * @type {EventTarget~Event}
11050      */
11051     this.trigger('exitFullWindow');
11052   };
11053
11054   /**
11055    * Check whether the player can play a given mimetype
11056    *
11057    * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
11058    *
11059    * @param {string} type
11060    *        The mimetype to check
11061    *
11062    * @return {string}
11063    *         'probably', 'maybe', or '' (empty string)
11064    */
11065
11066
11067   Player.prototype.canPlayType = function canPlayType(type) {
11068     var can = void 0;
11069
11070     // Loop through each playback technology in the options order
11071     for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11072       var techName = (0, _toTitleCase2['default'])(j[i]);
11073       var tech = _tech2['default'].getTech(techName);
11074
11075       // Support old behavior of techs being registered as components.
11076       // Remove once that deprecated behavior is removed.
11077       if (!tech) {
11078         tech = _component2['default'].getComponent(techName);
11079       }
11080
11081       // Check if the current tech is defined before continuing
11082       if (!tech) {
11083         _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11084         continue;
11085       }
11086
11087       // Check if the browser supports this technology
11088       if (tech.isSupported()) {
11089         can = tech.canPlayType(type);
11090
11091         if (can) {
11092           return can;
11093         }
11094       }
11095     }
11096
11097     return '';
11098   };
11099
11100   /**
11101    * Select source based on tech-order or source-order
11102    * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11103    * defaults to tech-order selection
11104    *
11105    * @param {Array} sources
11106    *        The sources for a media asset
11107    *
11108    * @return {Object|boolean}
11109    *         Object of source and tech order or false
11110    */
11111
11112
11113   Player.prototype.selectSource = function selectSource(sources) {
11114     var _this4 = this;
11115
11116     // Get only the techs specified in `techOrder` that exist and are supported by the
11117     // current platform
11118     var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) {
11119       // `Component.getComponent(...)` is for support of old behavior of techs
11120       // being registered as components.
11121       // Remove once that deprecated behavior is removed.
11122       return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)];
11123     }).filter(function (_ref) {
11124       var techName = _ref[0],
11125           tech = _ref[1];
11126
11127       // Check if the current tech is defined before continuing
11128       if (tech) {
11129         // Check if the browser supports this technology
11130         return tech.isSupported();
11131       }
11132
11133       _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11134       return false;
11135     });
11136
11137     // Iterate over each `innerArray` element once per `outerArray` element and execute
11138     // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11139     // that value.
11140     var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11141       var found = void 0;
11142
11143       outerArray.some(function (outerChoice) {
11144         return innerArray.some(function (innerChoice) {
11145           found = tester(outerChoice, innerChoice);
11146
11147           if (found) {
11148             return true;
11149           }
11150         });
11151       });
11152
11153       return found;
11154     };
11155
11156     var foundSourceAndTech = void 0;
11157     var flip = function flip(fn) {
11158       return function (a, b) {
11159         return fn(b, a);
11160       };
11161     };
11162     var finder = function finder(_ref2, source) {
11163       var techName = _ref2[0],
11164           tech = _ref2[1];
11165
11166       if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) {
11167         return { source: source, tech: techName };
11168       }
11169     };
11170
11171     // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11172     // to select from them based on their priority.
11173     if (this.options_.sourceOrder) {
11174       // Source-first ordering
11175       foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11176     } else {
11177       // Tech-first ordering
11178       foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11179     }
11180
11181     return foundSourceAndTech || false;
11182   };
11183
11184   /**
11185    * The source function updates the video source
11186    * There are three types of variables you can pass as the argument.
11187    * **URL string**: A URL to the the video file. Use this method if you are sure
11188    * the current playback technology (HTML5/Flash) can support the source you
11189    * provide. Currently only MP4 files can be used in both HTML5 and Flash.
11190    *
11191    * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
11192    *        One SourceObject or an array of SourceObjects
11193    *
11194    * @return {string|Player}
11195    *         - The current video source when getting
11196    *         - The player when setting
11197    */
11198
11199
11200   Player.prototype.src = function src(source) {
11201     if (source === undefined) {
11202       return this.techGet_('src');
11203     }
11204
11205     var currentTech = _tech2['default'].getTech(this.techName_);
11206
11207     // Support old behavior of techs being registered as components.
11208     // Remove once that deprecated behavior is removed.
11209     if (!currentTech) {
11210       currentTech = _component2['default'].getComponent(this.techName_);
11211     }
11212
11213     // case: Array of source objects to choose from and pick the best to play
11214     if (Array.isArray(source)) {
11215       this.sourceList_(source);
11216
11217       // case: URL String (http://myvideo...)
11218     } else if (typeof source === 'string') {
11219       // create a source object from the string
11220       this.src({ src: source });
11221
11222       // case: Source object { src: '', type: '' ... }
11223     } else if (source instanceof Object) {
11224       // check if the source has a type and the loaded tech cannot play the source
11225       // if there's no type we'll just try the current tech
11226       if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) {
11227         // create a source list with the current source and send through
11228         // the tech loop to check for a compatible technology
11229         this.sourceList_([source]);
11230       } else {
11231         this.cache_.sources = null;
11232         this.cache_.source = source;
11233         this.cache_.src = source.src;
11234
11235         this.currentType_ = source.type || '';
11236
11237         // wait until the tech is ready to set the source
11238         this.ready(function () {
11239
11240           // The setSource tech method was added with source handlers
11241           // so older techs won't support it
11242           // We need to check the direct prototype for the case where subclasses
11243           // of the tech do not support source handlers
11244           if (currentTech.prototype.hasOwnProperty('setSource')) {
11245             this.techCall_('setSource', source);
11246           } else {
11247             this.techCall_('src', source.src);
11248           }
11249
11250           if (this.options_.preload === 'auto') {
11251             this.load();
11252           }
11253
11254           if (this.options_.autoplay) {
11255             this.play();
11256           }
11257
11258           // Set the source synchronously if possible (#2326)
11259         }, true);
11260       }
11261     }
11262
11263     return this;
11264   };
11265
11266   /**
11267    * Handle an array of source objects
11268    *
11269    * @param  {Tech~SourceObject[]} sources
11270    *         Array of source objects
11271    *
11272    * @private
11273    */
11274
11275
11276   Player.prototype.sourceList_ = function sourceList_(sources) {
11277     var sourceTech = this.selectSource(sources);
11278
11279     if (sourceTech) {
11280       if (sourceTech.tech === this.techName_) {
11281         // if this technology is already loaded, set the source
11282         this.src(sourceTech.source);
11283       } else {
11284         // load this technology with the chosen source
11285         this.loadTech_(sourceTech.tech, sourceTech.source);
11286       }
11287
11288       this.cache_.sources = sources;
11289     } else {
11290       // We need to wrap this in a timeout to give folks a chance to add error event handlers
11291       this.setTimeout(function () {
11292         this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
11293       }, 0);
11294
11295       // we could not find an appropriate tech, but let's still notify the delegate that this is it
11296       // this needs a better comment about why this is needed
11297       this.triggerReady();
11298     }
11299   };
11300
11301   /**
11302    * Begin loading the src data.
11303    *
11304    * @return {Player}
11305    *         A reference to the player
11306    */
11307
11308
11309   Player.prototype.load = function load() {
11310     this.techCall_('load');
11311     return this;
11312   };
11313
11314   /**
11315    * Reset the player. Loads the first tech in the techOrder,
11316    * and calls `reset` on the tech`.
11317    *
11318    * @return {Player}
11319    *         A reference to the player
11320    */
11321
11322
11323   Player.prototype.reset = function reset() {
11324     this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null);
11325     this.techCall_('reset');
11326     return this;
11327   };
11328
11329   /**
11330    * Returns all of the current source objects.
11331    *
11332    * @return {Tech~SourceObject[]}
11333    *         The current source objects
11334    */
11335
11336
11337   Player.prototype.currentSources = function currentSources() {
11338     var source = this.currentSource();
11339     var sources = [];
11340
11341     // assume `{}` or `{ src }`
11342     if (Object.keys(source).length !== 0) {
11343       sources.push(source);
11344     }
11345
11346     return this.cache_.sources || sources;
11347   };
11348
11349   /**
11350    * Returns the current source object.
11351    *
11352    * @return {Tech~SourceObject}
11353    *         The current source object
11354    */
11355
11356
11357   Player.prototype.currentSource = function currentSource() {
11358     var source = {};
11359     var src = this.currentSrc();
11360
11361     if (src) {
11362       source.src = src;
11363     }
11364
11365     return this.cache_.source || source;
11366   };
11367
11368   /**
11369    * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
11370    * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
11371    *
11372    * @return {string}
11373    *         The current source
11374    */
11375
11376
11377   Player.prototype.currentSrc = function currentSrc() {
11378     return this.techGet_('currentSrc') || this.cache_.src || '';
11379   };
11380
11381   /**
11382    * Get the current source type e.g. video/mp4
11383    * This can allow you rebuild the current source object so that you could load the same
11384    * source and tech later
11385    *
11386    * @return {string}
11387    *         The source MIME type
11388    */
11389
11390
11391   Player.prototype.currentType = function currentType() {
11392     return this.currentType_ || '';
11393   };
11394
11395   /**
11396    * Get or set the preload attribute
11397    *
11398    * @param {boolean} [value]
11399    *        - true means that we should preload
11400    *        - false maens that we should not preload
11401    *
11402    * @return {string|Player}
11403    *         - the preload attribute value when getting
11404    *         - the player when setting
11405    */
11406
11407
11408   Player.prototype.preload = function preload(value) {
11409     if (value !== undefined) {
11410       this.techCall_('setPreload', value);
11411       this.options_.preload = value;
11412       return this;
11413     }
11414     return this.techGet_('preload');
11415   };
11416
11417   /**
11418    * Get or set the autoplay attribute.
11419    *
11420    * @param {boolean} [value]
11421    *        - true means that we should autoplay
11422    *        - false maens that we should not autoplay
11423    *
11424    * @return {string|Player}
11425    *         - the current value of autoplay
11426    *         - the player when setting
11427    */
11428
11429
11430   Player.prototype.autoplay = function autoplay(value) {
11431     if (value !== undefined) {
11432       this.techCall_('setAutoplay', value);
11433       this.options_.autoplay = value;
11434       return this;
11435     }
11436     return this.techGet_('autoplay', value);
11437   };
11438
11439   /**
11440    * Get or set the loop attribute on the video element.
11441    *
11442    * @param {boolean} [value]
11443    *        - true means that we should loop the video
11444    *        - false means that we should not loop the video
11445    *
11446    * @return {string|Player}
11447    *         - the current value of loop when getting
11448    *         - the player when setting
11449    */
11450
11451
11452   Player.prototype.loop = function loop(value) {
11453     if (value !== undefined) {
11454       this.techCall_('setLoop', value);
11455       this.options_.loop = value;
11456       return this;
11457     }
11458     return this.techGet_('loop');
11459   };
11460
11461   /**
11462    * Get or set the poster image source url
11463    *
11464    * @fires Player#posterchange
11465    *
11466    * @param {string} [src]
11467    *        Poster image source URL
11468    *
11469    * @return {string|Player}
11470    *         - the current value of poster when getting
11471    *         - the player when setting
11472    */
11473
11474
11475   Player.prototype.poster = function poster(src) {
11476     if (src === undefined) {
11477       return this.poster_;
11478     }
11479
11480     // The correct way to remove a poster is to set as an empty string
11481     // other falsey values will throw errors
11482     if (!src) {
11483       src = '';
11484     }
11485
11486     // update the internal poster variable
11487     this.poster_ = src;
11488
11489     // update the tech's poster
11490     this.techCall_('setPoster', src);
11491
11492     // alert components that the poster has been set
11493     /**
11494      * This event fires when the poster image is changed on the player.
11495      *
11496      * @event Player#posterchange
11497      * @type {EventTarget~Event}
11498      */
11499     this.trigger('posterchange');
11500
11501     return this;
11502   };
11503
11504   /**
11505    * Some techs (e.g. YouTube) can provide a poster source in an
11506    * asynchronous way. We want the poster component to use this
11507    * poster source so that it covers up the tech's controls.
11508    * (YouTube's play button). However we only want to use this
11509    * soruce if the player user hasn't set a poster through
11510    * the normal APIs.
11511    *
11512    * @fires Player#posterchange
11513    * @listens Tech#posterchange
11514    * @private
11515    */
11516
11517
11518   Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
11519     if (!this.poster_ && this.tech_ && this.tech_.poster) {
11520       this.poster_ = this.tech_.poster() || '';
11521
11522       // Let components know the poster has changed
11523       this.trigger('posterchange');
11524     }
11525   };
11526
11527   /**
11528    * Get or set whether or not the controls are showing.
11529    *
11530    * @fires Player#controlsenabled
11531    *
11532    * @param {boolean} [bool]
11533    *        - true to turn controls on
11534    *        - false to turn controls off
11535    *
11536    * @return {boolean|Player}
11537    *         - the current value of controls when getting
11538    *         - the player when setting
11539    */
11540
11541
11542   Player.prototype.controls = function controls(bool) {
11543     if (bool !== undefined) {
11544       bool = !!bool;
11545
11546       // Don't trigger a change event unless it actually changed
11547       if (this.controls_ !== bool) {
11548         this.controls_ = bool;
11549
11550         if (this.usingNativeControls()) {
11551           this.techCall_('setControls', bool);
11552         }
11553
11554         if (bool) {
11555           this.removeClass('vjs-controls-disabled');
11556           this.addClass('vjs-controls-enabled');
11557           /**
11558            * @event Player#controlsenabled
11559            * @type {EventTarget~Event}
11560            */
11561           this.trigger('controlsenabled');
11562
11563           if (!this.usingNativeControls()) {
11564             this.addTechControlsListeners_();
11565           }
11566         } else {
11567           this.removeClass('vjs-controls-enabled');
11568           this.addClass('vjs-controls-disabled');
11569           /**
11570            * @event Player#controlsdisabled
11571            * @type {EventTarget~Event}
11572            */
11573           this.trigger('controlsdisabled');
11574
11575           if (!this.usingNativeControls()) {
11576             this.removeTechControlsListeners_();
11577           }
11578         }
11579       }
11580       return this;
11581     }
11582     return !!this.controls_;
11583   };
11584
11585   /**
11586    * Toggle native controls on/off. Native controls are the controls built into
11587    * devices (e.g. default iPhone controls), Flash, or other techs
11588    * (e.g. Vimeo Controls)
11589    * **This should only be set by the current tech, because only the tech knows
11590    * if it can support native controls**
11591    *
11592    * @fires Player#usingnativecontrols
11593    * @fires Player#usingcustomcontrols
11594    *
11595    * @param {boolean} [bool]
11596    *        - true to turn native controls on
11597    *        - false to turn native controls off
11598    *
11599    * @return {boolean|Player}
11600    *         - the current value of native controls when getting
11601    *         - the player when setting
11602    */
11603
11604
11605   Player.prototype.usingNativeControls = function usingNativeControls(bool) {
11606     if (bool !== undefined) {
11607       bool = !!bool;
11608
11609       // Don't trigger a change event unless it actually changed
11610       if (this.usingNativeControls_ !== bool) {
11611         this.usingNativeControls_ = bool;
11612         if (bool) {
11613           this.addClass('vjs-using-native-controls');
11614
11615           /**
11616            * player is using the native device controls
11617            *
11618            * @event Player#usingnativecontrols
11619            * @type {EventTarget~Event}
11620            */
11621           this.trigger('usingnativecontrols');
11622         } else {
11623           this.removeClass('vjs-using-native-controls');
11624
11625           /**
11626            * player is using the custom HTML controls
11627            *
11628            * @event Player#usingcustomcontrols
11629            * @type {EventTarget~Event}
11630            */
11631           this.trigger('usingcustomcontrols');
11632         }
11633       }
11634       return this;
11635     }
11636     return !!this.usingNativeControls_;
11637   };
11638
11639   /**
11640    * Set or get the current MediaError
11641    *
11642    * @fires Player#error
11643    *
11644    * @param  {MediaError|string|number} [err]
11645    *         A MediaError or a string/number to be turned
11646    *         into a MediaError
11647    *
11648    * @return {MediaError|null|Player}
11649    *         - The current MediaError when getting (or null)
11650    *         - The player when setting
11651    */
11652
11653
11654   Player.prototype.error = function error(err) {
11655     if (err === undefined) {
11656       return this.error_ || null;
11657     }
11658
11659     // restoring to default
11660     if (err === null) {
11661       this.error_ = err;
11662       this.removeClass('vjs-error');
11663       if (this.errorDisplay) {
11664         this.errorDisplay.close();
11665       }
11666       return this;
11667     }
11668
11669     this.error_ = new _mediaError2['default'](err);
11670
11671     // add the vjs-error classname to the player
11672     this.addClass('vjs-error');
11673
11674     // log the name of the error type and any message
11675     // ie8 just logs "[object object]" if you just log the error object
11676     _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
11677
11678     /**
11679      * @event Player#error
11680      * @type {EventTarget~Event}
11681      */
11682     this.trigger('error');
11683
11684     return this;
11685   };
11686
11687   /**
11688    * Report user activity
11689    *
11690    * @param {Object} event
11691    *        Event object
11692    */
11693
11694
11695   Player.prototype.reportUserActivity = function reportUserActivity(event) {
11696     this.userActivity_ = true;
11697   };
11698
11699   /**
11700    * Get/set if user is active
11701    *
11702    * @fires Player#useractive
11703    * @fires Player#userinactive
11704    *
11705    * @param {boolean} [bool]
11706    *        - true if the user is active
11707    *        - false if the user is inactive
11708    * @return {boolean|Player}
11709    *         - the current value of userActive when getting
11710    *         - the player when setting
11711    */
11712
11713
11714   Player.prototype.userActive = function userActive(bool) {
11715     if (bool !== undefined) {
11716       bool = !!bool;
11717       if (bool !== this.userActive_) {
11718         this.userActive_ = bool;
11719         if (bool) {
11720           // If the user was inactive and is now active we want to reset the
11721           // inactivity timer
11722           this.userActivity_ = true;
11723           this.removeClass('vjs-user-inactive');
11724           this.addClass('vjs-user-active');
11725           /**
11726            * @event Player#useractive
11727            * @type {EventTarget~Event}
11728            */
11729           this.trigger('useractive');
11730         } else {
11731           // We're switching the state to inactive manually, so erase any other
11732           // activity
11733           this.userActivity_ = false;
11734
11735           // Chrome/Safari/IE have bugs where when you change the cursor it can
11736           // trigger a mousemove event. This causes an issue when you're hiding
11737           // the cursor when the user is inactive, and a mousemove signals user
11738           // activity. Making it impossible to go into inactive mode. Specifically
11739           // this happens in fullscreen when we really need to hide the cursor.
11740           //
11741           // When this gets resolved in ALL browsers it can be removed
11742           // https://code.google.com/p/chromium/issues/detail?id=103041
11743           if (this.tech_) {
11744             this.tech_.one('mousemove', function (e) {
11745               e.stopPropagation();
11746               e.preventDefault();
11747             });
11748           }
11749
11750           this.removeClass('vjs-user-active');
11751           this.addClass('vjs-user-inactive');
11752           /**
11753            * @event Player#userinactive
11754            * @type {EventTarget~Event}
11755            */
11756           this.trigger('userinactive');
11757         }
11758       }
11759       return this;
11760     }
11761     return this.userActive_;
11762   };
11763
11764   /**
11765    * Listen for user activity based on timeout value
11766    *
11767    * @private
11768    */
11769
11770
11771   Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
11772     var mouseInProgress = void 0;
11773     var lastMoveX = void 0;
11774     var lastMoveY = void 0;
11775     var handleActivity = Fn.bind(this, this.reportUserActivity);
11776
11777     var handleMouseMove = function handleMouseMove(e) {
11778       // #1068 - Prevent mousemove spamming
11779       // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
11780       if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
11781         lastMoveX = e.screenX;
11782         lastMoveY = e.screenY;
11783         handleActivity();
11784       }
11785     };
11786
11787     var handleMouseDown = function handleMouseDown() {
11788       handleActivity();
11789       // For as long as the they are touching the device or have their mouse down,
11790       // we consider them active even if they're not moving their finger or mouse.
11791       // So we want to continue to update that they are active
11792       this.clearInterval(mouseInProgress);
11793       // Setting userActivity=true now and setting the interval to the same time
11794       // as the activityCheck interval (250) should ensure we never miss the
11795       // next activityCheck
11796       mouseInProgress = this.setInterval(handleActivity, 250);
11797     };
11798
11799     var handleMouseUp = function handleMouseUp(event) {
11800       handleActivity();
11801       // Stop the interval that maintains activity if the mouse/touch is down
11802       this.clearInterval(mouseInProgress);
11803     };
11804
11805     // Any mouse movement will be considered user activity
11806     this.on('mousedown', handleMouseDown);
11807     this.on('mousemove', handleMouseMove);
11808     this.on('mouseup', handleMouseUp);
11809
11810     // Listen for keyboard navigation
11811     // Shouldn't need to use inProgress interval because of key repeat
11812     this.on('keydown', handleActivity);
11813     this.on('keyup', handleActivity);
11814
11815     // Run an interval every 250 milliseconds instead of stuffing everything into
11816     // the mousemove/touchmove function itself, to prevent performance degradation.
11817     // `this.reportUserActivity` simply sets this.userActivity_ to true, which
11818     // then gets picked up by this loop
11819     // http://ejohn.org/blog/learning-from-twitter/
11820     var inactivityTimeout = void 0;
11821
11822     this.setInterval(function () {
11823       // Check to see if mouse/touch activity has happened
11824       if (this.userActivity_) {
11825         // Reset the activity tracker
11826         this.userActivity_ = false;
11827
11828         // If the user state was inactive, set the state to active
11829         this.userActive(true);
11830
11831         // Clear any existing inactivity timeout to start the timer over
11832         this.clearTimeout(inactivityTimeout);
11833
11834         var timeout = this.options_.inactivityTimeout;
11835
11836         if (timeout > 0) {
11837           // In <timeout> milliseconds, if no more activity has occurred the
11838           // user will be considered inactive
11839           inactivityTimeout = this.setTimeout(function () {
11840             // Protect against the case where the inactivityTimeout can trigger just
11841             // before the next user activity is picked up by the activity check loop
11842             // causing a flicker
11843             if (!this.userActivity_) {
11844               this.userActive(false);
11845             }
11846           }, timeout);
11847         }
11848       }
11849     }, 250);
11850   };
11851
11852   /**
11853    * Gets or sets the current playback rate. A playback rate of
11854    * 1.0 represents normal speed and 0.5 would indicate half-speed
11855    * playback, for instance.
11856    *
11857    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
11858    *
11859    * @param {number} [rate]
11860    *       New playback rate to set.
11861    *
11862    * @return {number|Player}
11863    *         - The current playback rate when getting or 1.0
11864    *         - the player when setting
11865    */
11866
11867
11868   Player.prototype.playbackRate = function playbackRate(rate) {
11869     if (rate !== undefined) {
11870       this.techCall_('setPlaybackRate', rate);
11871       return this;
11872     }
11873
11874     if (this.tech_ && this.tech_.featuresPlaybackRate) {
11875       return this.techGet_('playbackRate');
11876     }
11877     return 1.0;
11878   };
11879
11880   /**
11881    * Gets or sets the audio flag
11882    *
11883    * @param {boolean} bool
11884    *        - true signals that this is an audio player
11885    *        - false signals that this is not an audio player
11886    *
11887    * @return {Player|boolean}
11888    *         - the current value of isAudio when getting
11889    *         - the player if setting
11890    */
11891
11892
11893   Player.prototype.isAudio = function isAudio(bool) {
11894     if (bool !== undefined) {
11895       this.isAudio_ = !!bool;
11896       return this;
11897     }
11898
11899     return !!this.isAudio_;
11900   };
11901
11902   /**
11903    * Get the {@link VideoTrackList}
11904    *
11905    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
11906    *
11907    * @return {VideoTrackList}
11908    *         the current video track list
11909    */
11910
11911
11912   Player.prototype.videoTracks = function videoTracks() {
11913     // if we have not yet loadTech_, we create videoTracks_
11914     // these will be passed to the tech during loading
11915     if (!this.tech_) {
11916       this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
11917       return this.videoTracks_;
11918     }
11919
11920     return this.tech_.videoTracks();
11921   };
11922
11923   /**
11924    * Get the {@link AudioTrackList}
11925    *
11926    * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
11927    *
11928    * @return {AudioTrackList}
11929    *         the current audio track list
11930    */
11931
11932
11933   Player.prototype.audioTracks = function audioTracks() {
11934     // if we have not yet loadTech_, we create videoTracks_
11935     // these will be passed to the tech during loading
11936     if (!this.tech_) {
11937       this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
11938       return this.audioTracks_;
11939     }
11940
11941     return this.tech_.audioTracks();
11942   };
11943
11944   /**
11945    * Get the {@link TextTrackList}
11946    *
11947    * Text tracks are tracks of timed text events.
11948    * - Captions: text displayed over the video
11949    *             for the hearing impaired
11950    * - Subtitles: text displayed over the video for
11951    *              those who don't understand language in the video
11952    * - Chapters: text displayed in a menu allowing the user to jump
11953    *             to particular points (chapters) in the video
11954    * - Descriptions: (not yet implemented) audio descriptions that are read back to
11955    *                 the user by a screen reading device
11956    *
11957    * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
11958    *
11959    * @return {TextTrackList|undefined}
11960    *         The current TextTrackList or undefined if
11961    *         or undefined if we don't have a tech
11962    */
11963
11964
11965   Player.prototype.textTracks = function textTracks() {
11966     // cannot use techGet_ directly because it checks to see whether the tech is ready.
11967     // Flash is unlikely to be ready in time but textTracks should still work.
11968     if (this.tech_) {
11969       return this.tech_.textTracks();
11970     }
11971   };
11972
11973   /**
11974    * Get the "remote" {@link TextTrackList}. Remote Text Tracks
11975    * are tracks that were added to the HTML video element and can
11976    * be removed, whereas normal texttracks cannot be removed.
11977    *
11978    *
11979    * @return {TextTrackList|undefined}
11980    *         The current remote text track list or undefined
11981    *         if we don't have a tech
11982    */
11983
11984
11985   Player.prototype.remoteTextTracks = function remoteTextTracks() {
11986     if (this.tech_) {
11987       return this.tech_.remoteTextTracks();
11988     }
11989   };
11990
11991   /**
11992    * Get the "remote" {@link HTMLTrackElementList}.
11993    * This gives the user all of the DOM elements that match up
11994    * with the remote {@link TextTrackList}.
11995    *
11996    * @return {HTMLTrackElementList}
11997    *         The current remote text track list elements
11998    *         or undefined if we don't have a tech
11999    */
12000
12001
12002   Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
12003     if (this.tech_) {
12004       return this.tech_.remoteTextTrackEls();
12005     }
12006   };
12007
12008   /**
12009    * A helper method for adding a {@link TextTrack} to our
12010    * {@link TextTrackList}.
12011    *
12012    * In addition to the W3C settings we allow adding additional info through options.
12013    *
12014    * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
12015    *
12016    * @param {string} [kind]
12017    *        the kind of TextTrack you are adding
12018    *
12019    * @param {string} [label]
12020    *        the label to give the TextTrack label
12021    *
12022    * @param {string} [language]
12023    *        the language to set on the TextTrack
12024    *
12025    * @return {TextTrack|undefined}
12026    *         the TextTrack that was added or undefined
12027    *         if there is no tech
12028    */
12029
12030
12031   Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
12032     if (this.tech_) {
12033       return this.tech_.addTextTrack(kind, label, language);
12034     }
12035   };
12036
12037   /**
12038    * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
12039    * automatically removed from the video element whenever the source changes, unless
12040    * manualCleanup is set to false.
12041    *
12042    * @param {Object} options
12043    *        Options to pass to {@link HTMLTrackElement} during creation. See
12044    *        {@link HTMLTrackElement} for object properties that you should use.
12045    *
12046    * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
12047    *
12048    * @return {HTMLTrackElement}
12049    *         the HTMLTrackElement that was created and added
12050    *         to the HTMLTrackElementList and the remote
12051    *         TextTrackList
12052    *
12053    * @deprecated The default value of the "manualCleanup" parameter will default
12054    *             to "false" in upcoming versions of Video.js
12055    */
12056
12057
12058   Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
12059     if (this.tech_) {
12060       return this.tech_.addRemoteTextTrack(options, manualCleanup);
12061     }
12062   };
12063
12064   /**
12065    * Remove a remote {@link TextTrack} from the respective
12066    * {@link TextTrackList} and {@link HTMLTrackElementList}.
12067    *
12068    * @param {Object} track
12069    *        Remote {@link TextTrack} to remove
12070    *
12071    * @return {undefined}
12072    *         does not return anything
12073    */
12074
12075
12076   Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
12077     var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
12078         _ref3$track = _ref3.track,
12079         track = _ref3$track === undefined ? arguments[0] : _ref3$track;
12080
12081     // destructure the input into an object with a track argument, defaulting to arguments[0]
12082     // default the whole argument to an empty object if nothing was passed in
12083
12084     if (this.tech_) {
12085       return this.tech_.removeRemoteTextTrack(track);
12086     }
12087   };
12088
12089   /**
12090    * Get video width
12091    *
12092    * @return {number}
12093    *         current video width
12094    */
12095
12096
12097   Player.prototype.videoWidth = function videoWidth() {
12098     return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12099   };
12100
12101   /**
12102    * Get video height
12103    *
12104    * @return {number}
12105    *         current video height
12106    */
12107
12108
12109   Player.prototype.videoHeight = function videoHeight() {
12110     return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12111   };
12112
12113   // Methods to add support for
12114   // initialTime: function() { return this.techCall_('initialTime'); },
12115   // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
12116   // played: function() { return this.techCall_('played'); },
12117   // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
12118   // defaultMuted: function() { return this.techCall_('defaultMuted'); }
12119
12120   /**
12121    * The player's language code
12122    * NOTE: The language should be set in the player options if you want the
12123    * the controls to be built with a specific language. Changing the lanugage
12124    * later will not update controls text.
12125    *
12126    * @param {string} [code]
12127    *        the language code to set the player to
12128    *
12129    * @return {string|Player}
12130    *         - The current language code when getting
12131    *         - A reference to the player when setting
12132    */
12133
12134
12135   Player.prototype.language = function language(code) {
12136     if (code === undefined) {
12137       return this.language_;
12138     }
12139
12140     this.language_ = String(code).toLowerCase();
12141     return this;
12142   };
12143
12144   /**
12145    * Get the player's language dictionary
12146    * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12147    * Languages specified directly in the player options have precedence
12148    *
12149    * @return {Array}
12150    *         An array of of supported languages
12151    */
12152
12153
12154   Player.prototype.languages = function languages() {
12155     return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
12156   };
12157
12158   /**
12159    * returns a JavaScript object reperesenting the current track
12160    * information. **DOES not return it as JSON**
12161    *
12162    * @return {Object}
12163    *         Object representing the current of track info
12164    */
12165
12166
12167   Player.prototype.toJSON = function toJSON() {
12168     var options = (0, _mergeOptions2['default'])(this.options_);
12169     var tracks = options.tracks;
12170
12171     options.tracks = [];
12172
12173     for (var i = 0; i < tracks.length; i++) {
12174       var track = tracks[i];
12175
12176       // deep merge tracks and null out player so no circular references
12177       track = (0, _mergeOptions2['default'])(track);
12178       track.player = undefined;
12179       options.tracks[i] = track;
12180     }
12181
12182     return options;
12183   };
12184
12185   /**
12186    * Creates a simple modal dialog (an instance of the {@link ModalDialog}
12187    * component) that immediately overlays the player with arbitrary
12188    * content and removes itself when closed.
12189    *
12190    * @param {string|Function|Element|Array|null} content
12191    *        Same as {@link ModalDialog#content}'s param of the same name.
12192    *        The most straight-forward usage is to provide a string or DOM
12193    *        element.
12194    *
12195    * @param {Object} [options]
12196    *        Extra options which will be passed on to the {@link ModalDialog}.
12197    *
12198    * @return {ModalDialog}
12199    *         the {@link ModalDialog} that was created
12200    */
12201
12202
12203   Player.prototype.createModal = function createModal(content, options) {
12204     var _this5 = this;
12205
12206     options = options || {};
12207     options.content = content || '';
12208
12209     var modal = new _modalDialog2['default'](this, options);
12210
12211     this.addChild(modal);
12212     modal.on('dispose', function () {
12213       _this5.removeChild(modal);
12214     });
12215
12216     return modal.open();
12217   };
12218
12219   /**
12220    * Gets tag settings
12221    *
12222    * @param {Element} tag
12223    *        The player tag
12224    *
12225    * @return {Object}
12226    *         An object containing all of the settings
12227    *         for a player tag
12228    */
12229
12230
12231   Player.getTagSettings = function getTagSettings(tag) {
12232     var baseOptions = {
12233       sources: [],
12234       tracks: []
12235     };
12236
12237     var tagOptions = Dom.getElAttributes(tag);
12238     var dataSetup = tagOptions['data-setup'];
12239
12240     if (Dom.hasElClass(tag, 'vjs-fluid')) {
12241       tagOptions.fluid = true;
12242     }
12243
12244     // Check if data-setup attr exists.
12245     if (dataSetup !== null) {
12246       // Parse options JSON
12247       // If empty string, make it a parsable json object.
12248       var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
12249           err = _safeParseTuple[0],
12250           data = _safeParseTuple[1];
12251
12252       if (err) {
12253         _log2['default'].error(err);
12254       }
12255       (0, _obj.assign)(tagOptions, data);
12256     }
12257
12258     (0, _obj.assign)(baseOptions, tagOptions);
12259
12260     // Get tag children settings
12261     if (tag.hasChildNodes()) {
12262       var children = tag.childNodes;
12263
12264       for (var i = 0, j = children.length; i < j; i++) {
12265         var child = children[i];
12266         // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12267         var childName = child.nodeName.toLowerCase();
12268
12269         if (childName === 'source') {
12270           baseOptions.sources.push(Dom.getElAttributes(child));
12271         } else if (childName === 'track') {
12272           baseOptions.tracks.push(Dom.getElAttributes(child));
12273         }
12274       }
12275     }
12276
12277     return baseOptions;
12278   };
12279
12280   /**
12281    * Determine wether or not flexbox is supported
12282    *
12283    * @return {boolean}
12284    *         - true if flexbox is supported
12285    *         - false if flexbox is not supported
12286    */
12287
12288
12289   Player.prototype.flexNotSupported_ = function flexNotSupported_() {
12290     var elem = _document2['default'].createElement('i');
12291
12292     // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
12293     // common flex features that we can rely on when checking for flex support.
12294     return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
12295     // IE10-specific (2012 flex spec)
12296     'msFlexOrder' in elem.style);
12297   };
12298
12299   return Player;
12300 }(_component2['default']);
12301
12302 /**
12303  * Global player list
12304  *
12305  * @type {Object}
12306  */
12307
12308
12309 Player.players = {};
12310
12311 var navigator = _window2['default'].navigator;
12312
12313 /*
12314  * Player instance options, surfaced using options
12315  * options = Player.prototype.options_
12316  * Make changes in options, not here.
12317  *
12318  * @type {Object}
12319  * @private
12320  */
12321 Player.prototype.options_ = {
12322   // Default order of fallback technology
12323   techOrder: ['html5', 'flash'],
12324   // techOrder: ['flash','html5'],
12325
12326   html5: {},
12327   flash: {},
12328
12329   // defaultVolume: 0.85,
12330   defaultVolume: 0.00,
12331
12332   // default inactivity timeout
12333   inactivityTimeout: 2000,
12334
12335   // default playback rates
12336   playbackRates: [],
12337   // Add playback rate selection by adding rates
12338   // 'playbackRates': [0.5, 1, 1.5, 2],
12339
12340   // Included control sets
12341   children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
12342
12343   language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
12344
12345   // locales and their language translations
12346   languages: {},
12347
12348   // Default message to show when a video cannot be played.
12349   notSupportedMessage: 'No compatible source was found for this media.'
12350 };
12351
12352 [
12353 /**
12354  * Returns whether or not the player is in the "ended" state.
12355  *
12356  * @return {Boolean} True if the player is in the ended state, false if not.
12357  * @method Player#ended
12358  */
12359 'ended',
12360 /**
12361  * Returns whether or not the player is in the "seeking" state.
12362  *
12363  * @return {Boolean} True if the player is in the seeking state, false if not.
12364  * @method Player#seeking
12365  */
12366 'seeking',
12367 /**
12368  * Returns the TimeRanges of the media that are currently available
12369  * for seeking to.
12370  *
12371  * @return {TimeRanges} the seekable intervals of the media timeline
12372  * @method Player#seekable
12373  */
12374 'seekable',
12375 /**
12376  * Returns the current state of network activity for the element, from
12377  * the codes in the list below.
12378  * - NETWORK_EMPTY (numeric value 0)
12379  *   The element has not yet been initialised. All attributes are in
12380  *   their initial states.
12381  * - NETWORK_IDLE (numeric value 1)
12382  *   The element's resource selection algorithm is active and has
12383  *   selected a resource, but it is not actually using the network at
12384  *   this time.
12385  * - NETWORK_LOADING (numeric value 2)
12386  *   The user agent is actively trying to download data.
12387  * - NETWORK_NO_SOURCE (numeric value 3)
12388  *   The element's resource selection algorithm is active, but it has
12389  *   not yet found a resource to use.
12390  *
12391  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
12392  * @return {number} the current network activity state
12393  * @method Player#networkState
12394  */
12395 'networkState',
12396 /**
12397  * Returns a value that expresses the current state of the element
12398  * with respect to rendering the current playback position, from the
12399  * codes in the list below.
12400  * - HAVE_NOTHING (numeric value 0)
12401  *   No information regarding the media resource is available.
12402  * - HAVE_METADATA (numeric value 1)
12403  *   Enough of the resource has been obtained that the duration of the
12404  *   resource is available.
12405  * - HAVE_CURRENT_DATA (numeric value 2)
12406  *   Data for the immediate current playback position is available.
12407  * - HAVE_FUTURE_DATA (numeric value 3)
12408  *   Data for the immediate current playback position is available, as
12409  *   well as enough data for the user agent to advance the current
12410  *   playback position in the direction of playback.
12411  * - HAVE_ENOUGH_DATA (numeric value 4)
12412  *   The user agent estimates that enough data is available for
12413  *   playback to proceed uninterrupted.
12414  *
12415  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
12416  * @return {number} the current playback rendering state
12417  * @method Player#readyState
12418  */
12419 'readyState'].forEach(function (fn) {
12420   Player.prototype[fn] = function () {
12421     return this.techGet_(fn);
12422   };
12423 });
12424
12425 TECH_EVENTS_RETRIGGER.forEach(function (event) {
12426   Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
12427     return this.trigger(event);
12428   };
12429 });
12430
12431 /**
12432  * Fired when the player has initial duration and dimension information
12433  *
12434  * @event Player#loadedmetadata
12435  * @type {EventTarget~Event}
12436  */
12437
12438 /**
12439  * Fired when the player has downloaded data at the current playback position
12440  *
12441  * @event Player#loadeddata
12442  * @type {EventTarget~Event}
12443  */
12444
12445 /**
12446  * Fired when the current playback position has changed *
12447  * During playback this is fired every 15-250 milliseconds, depending on the
12448  * playback technology in use.
12449  *
12450  * @event Player#timeupdate
12451  * @type {EventTarget~Event}
12452  */
12453
12454 /**
12455  * Fired when the volume changes
12456  *
12457  * @event Player#volumechange
12458  * @type {EventTarget~Event}
12459  */
12460
12461 _component2['default'].registerComponent('Player', Player);
12462 exports['default'] = Player;
12463
12464 },{"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){
12465 'use strict';
12466
12467 exports.__esModule = true;
12468
12469 var _player = _dereq_(51);
12470
12471 var _player2 = _interopRequireDefault(_player);
12472
12473 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12474
12475 /**
12476  * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
12477  *
12478  * @param {string} name
12479  *        The name of the plugin that is being registered
12480  *
12481  * @param {plugins:PluginFn} init
12482  *        The function that gets run when a `Player` initializes.
12483  */
12484 var plugin = function plugin(name, init) {
12485   _player2['default'].prototype[name] = init;
12486 }; /**
12487     * @file plugins.js
12488     * @module plugins
12489     */
12490 exports['default'] = plugin;
12491
12492 },{"51":51}],53:[function(_dereq_,module,exports){
12493 'use strict';
12494
12495 exports.__esModule = true;
12496
12497 var _clickableComponent = _dereq_(3);
12498
12499 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12500
12501 var _component = _dereq_(5);
12502
12503 var _component2 = _interopRequireDefault(_component);
12504
12505 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12506
12507 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12508
12509 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; }
12510
12511 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; } /**
12512                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file popup-button.js
12513                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12514
12515
12516 /**
12517  * A button class for use with {@link Popup} controls
12518  *
12519  * @extends ClickableComponent
12520  */
12521 var PopupButton = function (_ClickableComponent) {
12522   _inherits(PopupButton, _ClickableComponent);
12523
12524   /**
12525    * Create an instance of this class.
12526    *
12527    * @param {Player} player
12528    *        The `Player` that this class should be attached to.
12529    *
12530    * @param {Object} [options]
12531    *        The key/value store of player options.
12532    */
12533   function PopupButton(player) {
12534     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
12535
12536     _classCallCheck(this, PopupButton);
12537
12538     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12539
12540     _this.update();
12541     return _this;
12542   }
12543
12544   /**
12545    * Update the `Popup` that this button is attached to.
12546    */
12547
12548
12549   PopupButton.prototype.update = function update() {
12550     var popup = this.createPopup();
12551
12552     if (this.popup) {
12553       this.removeChild(this.popup);
12554     }
12555
12556     this.popup = popup;
12557     this.addChild(popup);
12558
12559     if (this.items && this.items.length === 0) {
12560       this.hide();
12561     } else if (this.items && this.items.length > 1) {
12562       this.show();
12563     }
12564   };
12565
12566   /**
12567    * Create a `Popup`. - Override with specific functionality for component
12568    *
12569    * @abstract
12570    */
12571
12572
12573   PopupButton.prototype.createPopup = function createPopup() {};
12574
12575   /**
12576    * Create the `PopupButton`s DOM element.
12577    *
12578    * @return {Element}
12579    *         The element that gets created.
12580    */
12581
12582
12583   PopupButton.prototype.createEl = function createEl() {
12584     return _ClickableComponent.prototype.createEl.call(this, 'div', {
12585       className: this.buildCSSClass()
12586     });
12587   };
12588
12589   /**
12590    * Builds the default DOM `className`.
12591    *
12592    * @return {string}
12593    *         The DOM `className` for this object.
12594    */
12595
12596
12597   PopupButton.prototype.buildCSSClass = function buildCSSClass() {
12598     var menuButtonClass = 'vjs-menu-button';
12599
12600     // If the inline option is passed, we want to use different styles altogether.
12601     if (this.options_.inline === true) {
12602       menuButtonClass += '-inline';
12603     } else {
12604       menuButtonClass += '-popup';
12605     }
12606
12607     return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
12608   };
12609
12610   return PopupButton;
12611 }(_clickableComponent2['default']);
12612
12613 _component2['default'].registerComponent('PopupButton', PopupButton);
12614 exports['default'] = PopupButton;
12615
12616 },{"3":3,"5":5}],54:[function(_dereq_,module,exports){
12617 'use strict';
12618
12619 exports.__esModule = true;
12620
12621 var _component = _dereq_(5);
12622
12623 var _component2 = _interopRequireDefault(_component);
12624
12625 var _dom = _dereq_(81);
12626
12627 var Dom = _interopRequireWildcard(_dom);
12628
12629 var _fn = _dereq_(83);
12630
12631 var Fn = _interopRequireWildcard(_fn);
12632
12633 var _events = _dereq_(82);
12634
12635 var Events = _interopRequireWildcard(_events);
12636
12637 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; } }
12638
12639 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12640
12641 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12642
12643 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; }
12644
12645 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; } /**
12646                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file popup.js
12647                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12648
12649
12650 /**
12651  * The Popup component is used to build pop up controls.
12652  *
12653  * @extends Component
12654  */
12655 var Popup = function (_Component) {
12656   _inherits(Popup, _Component);
12657
12658   function Popup() {
12659     _classCallCheck(this, Popup);
12660
12661     return _possibleConstructorReturn(this, _Component.apply(this, arguments));
12662   }
12663
12664   /**
12665    * Add a popup item to the popup
12666    *
12667    * @param {Object|string} component
12668    *        Component or component type to add
12669    *
12670    */
12671   Popup.prototype.addItem = function addItem(component) {
12672     this.addChild(component);
12673     component.on('click', Fn.bind(this, function () {
12674       this.unlockShowing();
12675     }));
12676   };
12677
12678   /**
12679    * Create the `PopupButton`s DOM element.
12680    *
12681    * @return {Element}
12682    *         The element that gets created.
12683    */
12684
12685
12686   Popup.prototype.createEl = function createEl() {
12687     var contentElType = this.options_.contentElType || 'ul';
12688
12689     this.contentEl_ = Dom.createEl(contentElType, {
12690       className: 'vjs-menu-content'
12691     });
12692
12693     var el = _Component.prototype.createEl.call(this, 'div', {
12694       append: this.contentEl_,
12695       className: 'vjs-menu'
12696     });
12697
12698     el.appendChild(this.contentEl_);
12699
12700     // Prevent clicks from bubbling up. Needed for Popup Buttons,
12701     // where a click on the parent is significant
12702     Events.on(el, 'click', function (event) {
12703       event.preventDefault();
12704       event.stopImmediatePropagation();
12705     });
12706
12707     return el;
12708   };
12709
12710   return Popup;
12711 }(_component2['default']);
12712
12713 _component2['default'].registerComponent('Popup', Popup);
12714 exports['default'] = Popup;
12715
12716 },{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){
12717 'use strict';
12718
12719 exports.__esModule = true;
12720
12721 var _clickableComponent = _dereq_(3);
12722
12723 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12724
12725 var _component = _dereq_(5);
12726
12727 var _component2 = _interopRequireDefault(_component);
12728
12729 var _fn = _dereq_(83);
12730
12731 var Fn = _interopRequireWildcard(_fn);
12732
12733 var _dom = _dereq_(81);
12734
12735 var Dom = _interopRequireWildcard(_dom);
12736
12737 var _browser = _dereq_(78);
12738
12739 var browser = _interopRequireWildcard(_browser);
12740
12741 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; } }
12742
12743 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12744
12745 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12746
12747 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; }
12748
12749 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; } /**
12750                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file poster-image.js
12751                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
12752
12753
12754 /**
12755  * A `ClickableComponent` that handles showing the poster image for the player.
12756  *
12757  * @extends ClickableComponent
12758  */
12759 var PosterImage = function (_ClickableComponent) {
12760   _inherits(PosterImage, _ClickableComponent);
12761
12762   /**
12763    * Create an instance of this class.
12764    *
12765    * @param {Player} player
12766    *        The `Player` that this class should attach to.
12767    *
12768    * @param {Object} [options]
12769    *        The key/value store of player options.
12770    */
12771   function PosterImage(player, options) {
12772     _classCallCheck(this, PosterImage);
12773
12774     var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12775
12776     _this.update();
12777     player.on('posterchange', Fn.bind(_this, _this.update));
12778     return _this;
12779   }
12780
12781   /**
12782    * Clean up and dispose of the `PosterImage`.
12783    */
12784
12785
12786   PosterImage.prototype.dispose = function dispose() {
12787     this.player().off('posterchange', this.update);
12788     _ClickableComponent.prototype.dispose.call(this);
12789   };
12790
12791   /**
12792    * Create the `PosterImage`s DOM element.
12793    *
12794    * @return {Element}
12795    *         The element that gets created.
12796    */
12797
12798
12799   PosterImage.prototype.createEl = function createEl() {
12800     var el = Dom.createEl('div', {
12801       className: 'vjs-poster',
12802
12803       // Don't want poster to be tabbable.
12804       tabIndex: -1
12805     });
12806
12807     // To ensure the poster image resizes while maintaining its original aspect
12808     // ratio, use a div with `background-size` when available. For browsers that
12809     // do not support `background-size` (e.g. IE8), fall back on using a regular
12810     // img element.
12811     if (!browser.BACKGROUND_SIZE_SUPPORTED) {
12812       this.fallbackImg_ = Dom.createEl('img');
12813       el.appendChild(this.fallbackImg_);
12814     }
12815
12816     return el;
12817   };
12818
12819   /**
12820    * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
12821    *
12822    * @listens Player#posterchange
12823    *
12824    * @param {EventTarget~Event} [event]
12825    *        The `Player#posterchange` event that triggered this function.
12826    */
12827
12828
12829   PosterImage.prototype.update = function update(event) {
12830     var url = this.player().poster();
12831
12832     this.setSrc(url);
12833
12834     // If there's no poster source we should display:none on this component
12835     // so it's not still clickable or right-clickable
12836     if (url) {
12837       this.show();
12838     } else {
12839       this.hide();
12840     }
12841   };
12842
12843   /**
12844    * Set the source of the `PosterImage` depending on the display method.
12845    *
12846    * @param {string} url
12847    *        The URL to the source for the `PosterImage`.
12848    */
12849
12850
12851   PosterImage.prototype.setSrc = function setSrc(url) {
12852     if (this.fallbackImg_) {
12853       this.fallbackImg_.src = url;
12854     } else {
12855       var backgroundImage = '';
12856
12857       // Any falsey values should stay as an empty string, otherwise
12858       // this will throw an extra error
12859       if (url) {
12860         backgroundImage = 'url("' + url + '")';
12861       }
12862
12863       this.el_.style.backgroundImage = backgroundImage;
12864     }
12865   };
12866
12867   /**
12868    * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
12869    * {@link ClickableComponent#handleClick} for instances where this will be triggered.
12870    *
12871    * @listens tap
12872    * @listens click
12873    * @listens keydown
12874    *
12875    * @param {EventTarget~Event} event
12876    +        The `click`, `tap` or `keydown` event that caused this function to be called.
12877    */
12878
12879
12880   PosterImage.prototype.handleClick = function handleClick(event) {
12881     // We don't want a click to trigger playback when controls are disabled
12882     if (!this.player_.controls()) {
12883       return;
12884     }
12885
12886     if (this.player_.paused()) {
12887       this.player_.play();
12888     } else {
12889       this.player_.pause();
12890     }
12891   };
12892
12893   return PosterImage;
12894 }(_clickableComponent2['default']);
12895
12896 _component2['default'].registerComponent('PosterImage', PosterImage);
12897 exports['default'] = PosterImage;
12898
12899 },{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){
12900 'use strict';
12901
12902 exports.__esModule = true;
12903 exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
12904
12905 var _dom = _dereq_(81);
12906
12907 var Dom = _interopRequireWildcard(_dom);
12908
12909 var _events = _dereq_(82);
12910
12911 var Events = _interopRequireWildcard(_events);
12912
12913 var _document = _dereq_(94);
12914
12915 var _document2 = _interopRequireDefault(_document);
12916
12917 var _window = _dereq_(95);
12918
12919 var _window2 = _interopRequireDefault(_window);
12920
12921 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12922
12923 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; } }
12924
12925 /**
12926  * @file setup.js - Functions for setting up a player without
12927  * user interaction based on the data-setup `attribute` of the video tag.
12928  *
12929  * @module setup
12930  */
12931 var _windowLoaded = false;
12932 var videojs = void 0;
12933
12934 /**
12935  * Set up any tags that have a data-setup `attribute` when the player is started.
12936  */
12937 var autoSetup = function autoSetup() {
12938
12939   // Protect against breakage in non-browser environments.
12940   if (!Dom.isReal()) {
12941     return;
12942   }
12943
12944   // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
12945   // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
12946   // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
12947   // var mediaEls = vids.concat(audios);
12948
12949   // Because IE8 doesn't support calling slice on a node list, we need to loop
12950   // through each list of elements to build up a new, combined list of elements.
12951   var vids = _document2['default'].getElementsByTagName('video');
12952   var audios = _document2['default'].getElementsByTagName('audio');
12953   var mediaEls = [];
12954
12955   if (vids && vids.length > 0) {
12956     for (var i = 0, e = vids.length; i < e; i++) {
12957       mediaEls.push(vids[i]);
12958     }
12959   }
12960
12961   if (audios && audios.length > 0) {
12962     for (var _i = 0, _e = audios.length; _i < _e; _i++) {
12963       mediaEls.push(audios[_i]);
12964     }
12965   }
12966
12967   // Check if any media elements exist
12968   if (mediaEls && mediaEls.length > 0) {
12969
12970     for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
12971       var mediaEl = mediaEls[_i2];
12972
12973       // Check if element exists, has getAttribute func.
12974       // IE seems to consider typeof el.getAttribute == 'object' instead of
12975       // 'function' like expected, at least when loading the player immediately.
12976       if (mediaEl && mediaEl.getAttribute) {
12977
12978         // Make sure this player hasn't already been set up.
12979         if (mediaEl.player === undefined) {
12980           var options = mediaEl.getAttribute('data-setup');
12981
12982           // Check if data-setup attr exists.
12983           // We only auto-setup if they've added the data-setup attr.
12984           if (options !== null) {
12985             // Create new video.js instance.
12986             videojs(mediaEl);
12987           }
12988         }
12989
12990         // If getAttribute isn't defined, we need to wait for the DOM.
12991       } else {
12992         autoSetupTimeout(1);
12993         break;
12994       }
12995     }
12996
12997     // No videos were found, so keep looping unless page is finished loading.
12998   } else if (!_windowLoaded) {
12999     autoSetupTimeout(1);
13000   }
13001 };
13002
13003 /**
13004  * Wait until the page is loaded before running autoSetup. This will be called in
13005  * autoSetup if `hasLoaded` returns false.
13006  *
13007  * @param {number} wait
13008  *        How long to wait in ms
13009  *
13010  * @param {videojs} [vjs]
13011  *        The videojs library function
13012  */
13013 function autoSetupTimeout(wait, vjs) {
13014   if (vjs) {
13015     videojs = vjs;
13016   }
13017
13018   _window2['default'].setTimeout(autoSetup, wait);
13019 }
13020
13021 if (Dom.isReal() && _document2['default'].readyState === 'complete') {
13022   _windowLoaded = true;
13023 } else {
13024   /**
13025    * Listen for the load event on window, and set _windowLoaded to true.
13026    *
13027    * @listens load
13028    */
13029   Events.one(_window2['default'], 'load', function () {
13030     _windowLoaded = true;
13031   });
13032 }
13033
13034 /**
13035  * check if the document has been loaded
13036  */
13037 var hasLoaded = function hasLoaded() {
13038   return _windowLoaded;
13039 };
13040
13041 exports.autoSetup = autoSetup;
13042 exports.autoSetupTimeout = autoSetupTimeout;
13043 exports.hasLoaded = hasLoaded;
13044
13045 },{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){
13046 'use strict';
13047
13048 exports.__esModule = true;
13049
13050 var _component = _dereq_(5);
13051
13052 var _component2 = _interopRequireDefault(_component);
13053
13054 var _dom = _dereq_(81);
13055
13056 var Dom = _interopRequireWildcard(_dom);
13057
13058 var _obj = _dereq_(88);
13059
13060 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; } }
13061
13062 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13063
13064 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13065
13066 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; }
13067
13068 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; } /**
13069                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file slider.js
13070                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
13071
13072
13073 /**
13074  * The base functionality for a slider. Can be vertical or horizontal.
13075  * For instance the volume bar or the seek bar on a video is a slider.
13076  *
13077  * @extends Component
13078  */
13079 var Slider = function (_Component) {
13080   _inherits(Slider, _Component);
13081
13082   /**
13083    * Create an instance of this class
13084    *
13085    * @param {Player} player
13086    *        The `Player` that this class should be attached to.
13087    *
13088    * @param {Object} [options]
13089    *        The key/value store of player options.
13090    */
13091   function Slider(player, options) {
13092     _classCallCheck(this, Slider);
13093
13094     // Set property names to bar to match with the child Slider class is looking for
13095     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
13096
13097     _this.bar = _this.getChild(_this.options_.barName);
13098
13099     // Set a horizontal or vertical class on the slider depending on the slider type
13100     _this.vertical(!!_this.options_.vertical);
13101
13102     _this.on('mousedown', _this.handleMouseDown);
13103     _this.on('touchstart', _this.handleMouseDown);
13104     _this.on('focus', _this.handleFocus);
13105     _this.on('blur', _this.handleBlur);
13106     _this.on('click', _this.handleClick);
13107
13108     _this.on(player, 'controlsvisible', _this.update);
13109     _this.on(player, _this.playerEvent, _this.update);
13110     return _this;
13111   }
13112
13113   /**
13114    * Create the `Button`s DOM element.
13115    *
13116    * @param {string} type
13117    *        Type of element to create.
13118    *
13119    * @param {Object} [props={}]
13120    *        List of properties in Object form.
13121    *
13122    * @param {Object} [attributes={}]
13123    *        list of attributes in Object form.
13124    *
13125    * @return {Element}
13126    *         The element that gets created.
13127    */
13128
13129
13130   Slider.prototype.createEl = function createEl(type) {
13131     var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13132     var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13133
13134     // Add the slider element class to all sub classes
13135     props.className = props.className + ' vjs-slider';
13136     props = (0, _obj.assign)({
13137       tabIndex: 0
13138     }, props);
13139
13140     attributes = (0, _obj.assign)({
13141       'role': 'slider',
13142       'aria-valuenow': 0,
13143       'aria-valuemin': 0,
13144       'aria-valuemax': 100,
13145       'tabIndex': 0
13146     }, attributes);
13147
13148     return _Component.prototype.createEl.call(this, type, props, attributes);
13149   };
13150
13151   /**
13152    * Handle `mousedown` or `touchstart` events on the `Slider`.
13153    *
13154    * @param {EventTarget~Event} event
13155    *        `mousedown` or `touchstart` event that triggered this function
13156    *
13157    * @listens mousedown
13158    * @listens touchstart
13159    * @fires Slider#slideractive
13160    */
13161
13162
13163   Slider.prototype.handleMouseDown = function handleMouseDown(event) {
13164     var doc = this.bar.el_.ownerDocument;
13165
13166     event.preventDefault();
13167     Dom.blockTextSelection();
13168
13169     this.addClass('vjs-sliding');
13170     /**
13171      * Triggered when the slider is in an active state
13172      *
13173      * @event Slider#slideractive
13174      * @type {EventTarget~Event}
13175      */
13176     this.trigger('slideractive');
13177
13178     this.on(doc, 'mousemove', this.handleMouseMove);
13179     this.on(doc, 'mouseup', this.handleMouseUp);
13180     this.on(doc, 'touchmove', this.handleMouseMove);
13181     this.on(doc, 'touchend', this.handleMouseUp);
13182
13183     this.handleMouseMove(event);
13184   };
13185
13186   /**
13187    * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
13188    * The `mousemove` and `touchmove` events will only only trigger this function during
13189    * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
13190    * {@link Slider#handleMouseUp}.
13191    *
13192    * @param {EventTarget~Event} event
13193    *        `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
13194    *        this function
13195    *
13196    * @listens mousemove
13197    * @listens touchmove
13198    */
13199
13200
13201   Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
13202
13203   /**
13204    * Handle `mouseup` or `touchend` events on the `Slider`.
13205    *
13206    * @param {EventTarget~Event} event
13207    *        `mouseup` or `touchend` event that triggered this function.
13208    *
13209    * @listens touchend
13210    * @listens mouseup
13211    * @fires Slider#sliderinactive
13212    */
13213
13214
13215   Slider.prototype.handleMouseUp = function handleMouseUp() {
13216     var doc = this.bar.el_.ownerDocument;
13217
13218     Dom.unblockTextSelection();
13219
13220     this.removeClass('vjs-sliding');
13221     /**
13222      * Triggered when the slider is no longer in an active state.
13223      *
13224      * @event Slider#sliderinactive
13225      * @type {EventTarget~Event}
13226      */
13227     this.trigger('sliderinactive');
13228
13229     this.off(doc, 'mousemove', this.handleMouseMove);
13230     this.off(doc, 'mouseup', this.handleMouseUp);
13231     this.off(doc, 'touchmove', this.handleMouseMove);
13232     this.off(doc, 'touchend', this.handleMouseUp);
13233
13234     this.update();
13235   };
13236
13237   /**
13238    * Update the progress bar of the `Slider`.
13239    */
13240
13241
13242   Slider.prototype.update = function update() {
13243     // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
13244     // execution stack. The player is destroyed before then update will cause an error
13245     if (!this.el_) {
13246       return;
13247     }
13248
13249     // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
13250     // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
13251     // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
13252     var progress = this.getPercent();
13253     var bar = this.bar;
13254
13255     // If there's no bar...
13256     if (!bar) {
13257       return;
13258     }
13259
13260     // Protect against no duration and other division issues
13261     if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
13262       progress = 0;
13263     }
13264
13265     // Convert to a percentage for setting
13266     var percentage = (progress * 100).toFixed(2) + '%';
13267
13268     // Set the new bar width or height
13269     if (this.vertical()) {
13270       bar.el().style.height = percentage;
13271     } else {
13272       bar.el().style.width = percentage;
13273     }
13274   };
13275
13276   /**
13277    * Calculate distance for slider
13278    *
13279    * @param {EventTarget~Event} event
13280    *        The event that caused this function to run.
13281    *
13282    * @return {number}
13283    *         The current position of the Slider.
13284    *         - postition.x for vertical `Slider`s
13285    *         - postition.y for horizontal `Slider`s
13286    */
13287
13288
13289   Slider.prototype.calculateDistance = function calculateDistance(event) {
13290     var position = Dom.getPointerPosition(this.el_, event);
13291
13292     if (this.vertical()) {
13293       return position.y;
13294     }
13295     return position.x;
13296   };
13297
13298   /**
13299    * Handle a `focus` event on this `Slider`.
13300    *
13301    * @param {EventTarget~Event} event
13302    *        The `focus` event that caused this function to run.
13303    *
13304    * @listens focus
13305    */
13306
13307
13308   Slider.prototype.handleFocus = function handleFocus() {
13309     this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13310   };
13311
13312   /**
13313    * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
13314    * arrow keys. This function will only be called when the slider has focus. See
13315    * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
13316    *
13317    * @param {EventTarget~Event} event
13318    *        the `keydown` event that caused this function to run.
13319    *
13320    * @listens keydown
13321    */
13322
13323
13324   Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13325     // Left and Down Arrows
13326     if (event.which === 37 || event.which === 40) {
13327       event.preventDefault();
13328       this.stepBack();
13329
13330       // Up and Right Arrows
13331     } else if (event.which === 38 || event.which === 39) {
13332       event.preventDefault();
13333       this.stepForward();
13334     }
13335   };
13336
13337   /**
13338    * Handle a `blur` event on this `Slider`.
13339    *
13340    * @param {EventTarget~Event} event
13341    *        The `blur` event that caused this function to run.
13342    *
13343    * @listens blur
13344    */
13345
13346   Slider.prototype.handleBlur = function handleBlur() {
13347     this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13348   };
13349
13350   /**
13351    * Listener for click events on slider, used to prevent clicks
13352    *   from bubbling up to parent elements like button menus.
13353    *
13354    * @param {Object} event
13355    *        Event that caused this object to run
13356    */
13357
13358
13359   Slider.prototype.handleClick = function handleClick(event) {
13360     event.stopImmediatePropagation();
13361     event.preventDefault();
13362   };
13363
13364   /**
13365    * Get/set if slider is horizontal for vertical
13366    *
13367    * @param {boolean} [bool]
13368    *        - true if slider is vertical,
13369    *        - false is horizontal
13370    *
13371    * @return {boolean|Slider}
13372    *         - true if slider is vertical, and getting
13373    *         - false is horizontal, and getting
13374    *         - a reference to this object when setting
13375    */
13376
13377
13378   Slider.prototype.vertical = function vertical(bool) {
13379     if (bool === undefined) {
13380       return this.vertical_ || false;
13381     }
13382
13383     this.vertical_ = !!bool;
13384
13385     if (this.vertical_) {
13386       this.addClass('vjs-slider-vertical');
13387     } else {
13388       this.addClass('vjs-slider-horizontal');
13389     }
13390
13391     return this;
13392   };
13393
13394   return Slider;
13395 }(_component2['default']);
13396
13397 _component2['default'].registerComponent('Slider', Slider);
13398 exports['default'] = Slider;
13399
13400 },{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){
13401 'use strict';
13402
13403 exports.__esModule = true;
13404 /**
13405  * @file flash-rtmp.js
13406  * @module flash-rtmp
13407  */
13408
13409 /**
13410  * Add RTMP properties to the {@link Flash} Tech.
13411  *
13412  * @param {Flash} Flash
13413  *        The flash tech class.
13414  *
13415  * @mixin FlashRtmpDecorator
13416  */
13417 function FlashRtmpDecorator(Flash) {
13418   Flash.streamingFormats = {
13419     'rtmp/mp4': 'MP4',
13420     'rtmp/flv': 'FLV'
13421   };
13422
13423   /**
13424    * Join connection and stream with an ampersand.
13425    *
13426    * @param {string} connection
13427    *        The connection string.
13428    *
13429    * @param {string} stream
13430    *        The stream string.
13431    */
13432   Flash.streamFromParts = function (connection, stream) {
13433     return connection + '&' + stream;
13434   };
13435
13436   /**
13437    * The flash parts object that contains connection and stream info.
13438    *
13439    * @typedef {Object} Flash~PartsObject
13440    *
13441    * @property {string} connection
13442    *           The connection string of a source, defaults to an empty string.
13443    *
13444    * @property {string} stream
13445    *           The stream string of the source, defaults to an empty string.
13446    */
13447
13448   /**
13449    * Convert a source url into a stream and connection parts.
13450    *
13451    * @param {string} src
13452    *        the source url
13453    *
13454    * @return {Flash~PartsObject}
13455    *         The parts object that contains a connection and a stream
13456    */
13457   Flash.streamToParts = function (src) {
13458     var parts = {
13459       connection: '',
13460       stream: ''
13461     };
13462
13463     if (!src) {
13464       return parts;
13465     }
13466
13467     // Look for the normal URL separator we expect, '&'.
13468     // If found, we split the URL into two pieces around the
13469     // first '&'.
13470     var connEnd = src.search(/&(?!\w+=)/);
13471     var streamBegin = void 0;
13472
13473     if (connEnd !== -1) {
13474       streamBegin = connEnd + 1;
13475     } else {
13476       // If there's not a '&', we use the last '/' as the delimiter.
13477       connEnd = streamBegin = src.lastIndexOf('/') + 1;
13478       if (connEnd === 0) {
13479         // really, there's not a '/'?
13480         connEnd = streamBegin = src.length;
13481       }
13482     }
13483
13484     parts.connection = src.substring(0, connEnd);
13485     parts.stream = src.substring(streamBegin, src.length);
13486
13487     return parts;
13488   };
13489
13490   /**
13491    * Check if the source type is a streaming type.
13492    *
13493    * @param {string} srcType
13494    *        The mime type to check.
13495    *
13496    * @return {boolean}
13497    *          - True if the source type is a streaming type.
13498    *          - False if the source type is not a streaming type.
13499    */
13500   Flash.isStreamingType = function (srcType) {
13501     return srcType in Flash.streamingFormats;
13502   };
13503
13504   // RTMP has four variations, any string starting
13505   // with one of these protocols should be valid
13506
13507   /**
13508    * Regular expression used to check if the source is an rtmp source.
13509    *
13510    * @property {RegExp} Flash.RTMP_RE
13511    */
13512   Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13513
13514   /**
13515    * Check if the source itself is a streaming type.
13516    *
13517    * @param {string} src
13518    *        The url to the source.
13519    *
13520    * @return {boolean}
13521    *          - True if the source url indicates that the source is streaming.
13522    *          - False if the shource url indicates that the source url is not streaming.
13523    */
13524   Flash.isStreamingSrc = function (src) {
13525     return Flash.RTMP_RE.test(src);
13526   };
13527
13528   /**
13529    * A source handler for RTMP urls
13530    * @type {Object}
13531    */
13532   Flash.rtmpSourceHandler = {};
13533
13534   /**
13535    * Check if Flash can play the given mime type.
13536    *
13537    * @param {string} type
13538    *        The mime type to check
13539    *
13540    * @return {string}
13541    *         'maybe', or '' (empty string)
13542    */
13543   Flash.rtmpSourceHandler.canPlayType = function (type) {
13544     if (Flash.isStreamingType(type)) {
13545       return 'maybe';
13546     }
13547
13548     return '';
13549   };
13550
13551   /**
13552    * Check if Flash can handle the source natively
13553    *
13554    * @param {Object} source
13555    *        The source object
13556    *
13557    * @param {Object} [options]
13558    *        The options passed to the tech
13559    *
13560    * @return {string}
13561    *         'maybe', or '' (empty string)
13562    */
13563   Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
13564     var can = Flash.rtmpSourceHandler.canPlayType(source.type);
13565
13566     if (can) {
13567       return can;
13568     }
13569
13570     if (Flash.isStreamingSrc(source.src)) {
13571       return 'maybe';
13572     }
13573
13574     return '';
13575   };
13576
13577   /**
13578    * Pass the source to the flash object.
13579    *
13580    * @param {Object} source
13581    *        The source object
13582    *
13583    * @param {Flash} tech
13584    *        The instance of the Flash tech
13585    *
13586    * @param {Object} [options]
13587    *        The options to pass to the source
13588    */
13589   Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
13590     var srcParts = Flash.streamToParts(source.src);
13591
13592     tech.setRtmpConnection(srcParts.connection);
13593     tech.setRtmpStream(srcParts.stream);
13594   };
13595
13596   // Register the native source handler
13597   Flash.registerSourceHandler(Flash.rtmpSourceHandler);
13598
13599   return Flash;
13600 }
13601
13602 exports['default'] = FlashRtmpDecorator;
13603
13604 },{}],59:[function(_dereq_,module,exports){
13605 'use strict';
13606
13607 exports.__esModule = true;
13608
13609 var _tech = _dereq_(62);
13610
13611 var _tech2 = _interopRequireDefault(_tech);
13612
13613 var _dom = _dereq_(81);
13614
13615 var Dom = _interopRequireWildcard(_dom);
13616
13617 var _url = _dereq_(92);
13618
13619 var Url = _interopRequireWildcard(_url);
13620
13621 var _timeRanges = _dereq_(90);
13622
13623 var _flashRtmp = _dereq_(58);
13624
13625 var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
13626
13627 var _component = _dereq_(5);
13628
13629 var _component2 = _interopRequireDefault(_component);
13630
13631 var _window = _dereq_(95);
13632
13633 var _window2 = _interopRequireDefault(_window);
13634
13635 var _obj = _dereq_(88);
13636
13637 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; } }
13638
13639 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13640
13641 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13642
13643 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; }
13644
13645 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; } /**
13646                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file flash.js
13647                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
13648                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * https://github.com/zencoder/video-js-swf
13649                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * Not using setupTriggers. Using global onEvent func to distribute events
13650                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
13651
13652 var navigator = _window2['default'].navigator;
13653
13654 /**
13655  * Flash Media Controller - Wrapper for Flash Media API
13656  *
13657  * @mixes FlashRtmpDecorator
13658  * @mixes Tech~SouceHandlerAdditions
13659  * @extends Tech
13660  */
13661
13662 var Flash = function (_Tech) {
13663   _inherits(Flash, _Tech);
13664
13665   /**
13666    * Create an instance of this Tech.
13667    *
13668    * @param {Object} [options]
13669    *        The key/value store of player options.
13670    *
13671    * @param {Component~ReadyCallback} ready
13672    *        Callback function to call when the `Flash` Tech is ready.
13673    */
13674   function Flash(options, ready) {
13675     _classCallCheck(this, Flash);
13676
13677     // Set the source when ready
13678     var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
13679
13680     if (options.source) {
13681       _this.ready(function () {
13682         this.setSource(options.source);
13683       }, true);
13684     }
13685
13686     // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
13687     // This allows resetting the playhead when we catch the reload
13688     if (options.startTime) {
13689       _this.ready(function () {
13690         this.load();
13691         this.play();
13692         this.currentTime(options.startTime);
13693       }, true);
13694     }
13695
13696     // Add global window functions that the swf expects
13697     // A 4.x workflow we weren't able to solve for in 5.0
13698     // because of the need to hard code these functions
13699     // into the swf for security reasons
13700     _window2['default'].videojs = _window2['default'].videojs || {};
13701     _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {};
13702     _window2['default'].videojs.Flash.onReady = Flash.onReady;
13703     _window2['default'].videojs.Flash.onEvent = Flash.onEvent;
13704     _window2['default'].videojs.Flash.onError = Flash.onError;
13705
13706     _this.on('seeked', function () {
13707       this.lastSeekTarget_ = undefined;
13708     });
13709
13710     return _this;
13711   }
13712
13713   /**
13714    * Create the `Flash` Tech's DOM element.
13715    *
13716    * @return {Element}
13717    *         The element that gets created.
13718    */
13719
13720
13721   Flash.prototype.createEl = function createEl() {
13722     var options = this.options_;
13723
13724     // If video.js is hosted locally you should also set the location
13725     // for the hosted swf, which should be relative to the page (not video.js)
13726     // Otherwise this adds a CDN url.
13727     // The CDN also auto-adds a swf URL for that specific version.
13728     if (!options.swf) {
13729       var ver = '5.3.0';
13730
13731       options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf';
13732     }
13733
13734     // Generate ID for swf object
13735     var objId = options.techId;
13736
13737     // Merge default flashvars with ones passed in to init
13738     var flashVars = (0, _obj.assign)({
13739
13740       // SWF Callback Functions
13741       readyFunction: 'videojs.Flash.onReady',
13742       eventProxyFunction: 'videojs.Flash.onEvent',
13743       errorEventProxyFunction: 'videojs.Flash.onError',
13744
13745       // Player Settings
13746       autoplay: options.autoplay,
13747       preload: options.preload,
13748       loop: options.loop,
13749       muted: options.muted
13750
13751     }, options.flashVars);
13752
13753     // Merge default parames with ones passed in
13754     var params = (0, _obj.assign)({
13755       // Opaque is needed to overlay controls, but can affect playback performance
13756       wmode: 'opaque',
13757       // Using bgcolor prevents a white flash when the object is loading
13758       bgcolor: '#000000'
13759     }, options.params);
13760
13761     // Merge default attributes with ones passed in
13762     var attributes = (0, _obj.assign)({
13763       // Both ID and Name needed or swf to identify itself
13764       id: objId,
13765       name: objId,
13766       'class': 'vjs-tech'
13767     }, options.attributes);
13768
13769     this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
13770     this.el_.tech = this;
13771
13772     return this.el_;
13773   };
13774
13775   /**
13776    * Called by {@link Player#play} to play using the `Flash` `Tech`.
13777    */
13778
13779
13780   Flash.prototype.play = function play() {
13781     if (this.ended()) {
13782       this.setCurrentTime(0);
13783     }
13784     this.el_.vjs_play();
13785   };
13786
13787   /**
13788    * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
13789    */
13790
13791
13792   Flash.prototype.pause = function pause() {
13793     this.el_.vjs_pause();
13794   };
13795
13796   /**
13797    * A getter/setter for the `Flash` Tech's source object.
13798    * > Note: Please use {@link Flash#setSource}
13799    *
13800    * @param {Tech~SourceObject} [src]
13801    *        The source object you want to set on the `Flash` techs.
13802    *
13803    * @return {Tech~SourceObject|undefined}
13804    *         - The current source object when a source is not passed in.
13805    *         - undefined when setting
13806    *
13807    * @deprecated Since version 5.
13808    */
13809
13810
13811   Flash.prototype.src = function src(_src) {
13812     if (_src === undefined) {
13813       return this.currentSrc();
13814     }
13815
13816     // Setting src through `src` not `setSrc` will be deprecated
13817     return this.setSrc(_src);
13818   };
13819
13820   /**
13821    * A getter/setter for the `Flash` Tech's source object.
13822    *
13823    * @param {Tech~SourceObject} [src]
13824    *        The source object you want to set on the `Flash` techs.
13825    *
13826    * @return {Tech~SourceObject|undefined}
13827    *         - The current source object when a source is not passed in.
13828    *         - undefined when setting
13829    */
13830
13831
13832   Flash.prototype.setSrc = function setSrc(src) {
13833     var _this2 = this;
13834
13835     // Make sure source URL is absolute.
13836     src = Url.getAbsoluteURL(src);
13837     this.el_.vjs_src(src);
13838
13839     // Currently the SWF doesn't autoplay if you load a source later.
13840     // e.g. Load player w/ no source, wait 2s, set src.
13841     if (this.autoplay()) {
13842       this.setTimeout(function () {
13843         return _this2.play();
13844       }, 0);
13845     }
13846   };
13847
13848   /**
13849    * Indicates whether the media is currently seeking to a new position or not.
13850    *
13851    * @return {boolean}
13852    *         - True if seeking to a new position
13853    *         - False otherwise
13854    */
13855
13856
13857   Flash.prototype.seeking = function seeking() {
13858     return this.lastSeekTarget_ !== undefined;
13859   };
13860
13861   /**
13862    * Returns the current time in seconds that the media is at in playback.
13863    *
13864    * @param {number} time
13865    *        Current playtime of the media in seconds.
13866    */
13867
13868
13869   Flash.prototype.setCurrentTime = function setCurrentTime(time) {
13870     var seekable = this.seekable();
13871
13872     if (seekable.length) {
13873       // clamp to the current seekable range
13874       time = time > seekable.start(0) ? time : seekable.start(0);
13875       time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
13876
13877       this.lastSeekTarget_ = time;
13878       this.trigger('seeking');
13879       this.el_.vjs_setProperty('currentTime', time);
13880       _Tech.prototype.setCurrentTime.call(this);
13881     }
13882   };
13883
13884   /**
13885    * Get the current playback time in seconds
13886    *
13887    * @return {number}
13888    *         The current time of playback in seconds.
13889    */
13890
13891
13892   Flash.prototype.currentTime = function currentTime() {
13893     // when seeking make the reported time keep up with the requested time
13894     // by reading the time we're seeking to
13895     if (this.seeking()) {
13896       return this.lastSeekTarget_ || 0;
13897     }
13898     return this.el_.vjs_getProperty('currentTime');
13899   };
13900
13901   /**
13902    * Get the current source
13903    *
13904    * @method currentSrc
13905    * @return {Tech~SourceObject}
13906    *         The current source
13907    */
13908
13909
13910   Flash.prototype.currentSrc = function currentSrc() {
13911     if (this.currentSource_) {
13912       return this.currentSource_.src;
13913     }
13914     return this.el_.vjs_getProperty('currentSrc');
13915   };
13916
13917   /**
13918    * Get the total duration of the current media.
13919    *
13920    * @return {number}
13921    8          The total duration of the current media.
13922    */
13923
13924
13925   Flash.prototype.duration = function duration() {
13926     if (this.readyState() === 0) {
13927       return NaN;
13928     }
13929     var duration = this.el_.vjs_getProperty('duration');
13930
13931     return duration >= 0 ? duration : Infinity;
13932   };
13933
13934   /**
13935    * Load media into Tech.
13936    */
13937
13938
13939   Flash.prototype.load = function load() {
13940     this.el_.vjs_load();
13941   };
13942
13943   /**
13944    * Get the poster image that was set on the tech.
13945    */
13946
13947
13948   Flash.prototype.poster = function poster() {
13949     this.el_.vjs_getProperty('poster');
13950   };
13951
13952   /**
13953    * Poster images are not handled by the Flash tech so make this is a no-op.
13954    */
13955
13956
13957   Flash.prototype.setPoster = function setPoster() {};
13958
13959   /**
13960    * Determine the time ranges that can be seeked to in the media.
13961    *
13962    * @return {TimeRange}
13963    *         Returns the time ranges that can be seeked to.
13964    */
13965
13966
13967   Flash.prototype.seekable = function seekable() {
13968     var duration = this.duration();
13969
13970     if (duration === 0) {
13971       return (0, _timeRanges.createTimeRange)();
13972     }
13973     return (0, _timeRanges.createTimeRange)(0, duration);
13974   };
13975
13976   /**
13977    * Get and create a `TimeRange` object for buffering.
13978    *
13979    * @return {TimeRange}
13980    *         The time range object that was created.
13981    */
13982
13983
13984   Flash.prototype.buffered = function buffered() {
13985     var ranges = this.el_.vjs_getProperty('buffered');
13986
13987     if (ranges.length === 0) {
13988       return (0, _timeRanges.createTimeRange)();
13989     }
13990     return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]);
13991   };
13992
13993   /**
13994    * Get fullscreen support -
13995    *
13996    * Flash does not allow fullscreen through javascript
13997    * so this always returns false.
13998    *
13999    * @return {boolean}
14000    *         The Flash tech does not support fullscreen, so it will always return false.
14001    */
14002
14003
14004   Flash.prototype.supportsFullScreen = function supportsFullScreen() {
14005     // Flash does not allow fullscreen through javascript
14006     return false;
14007   };
14008
14009   /**
14010    * Flash does not allow fullscreen through javascript
14011    * so this always returns false.
14012    *
14013    * @return {boolean}
14014    *         The Flash tech does not support fullscreen, so it will always return false.
14015    */
14016
14017
14018   Flash.prototype.enterFullScreen = function enterFullScreen() {
14019     return false;
14020   };
14021
14022   return Flash;
14023 }(_tech2['default']);
14024
14025 // Create setters and getters for attributes
14026
14027
14028 var _api = Flash.prototype;
14029 var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
14030 var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
14031
14032 function _createSetter(attr) {
14033   var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
14034
14035   _api['set' + attrUpper] = function (val) {
14036     return this.el_.vjs_setProperty(attr, val);
14037   };
14038 }
14039
14040 function _createGetter(attr) {
14041   _api[attr] = function () {
14042     return this.el_.vjs_getProperty(attr);
14043   };
14044 }
14045
14046 // Create getter and setters for all read/write attributes
14047 for (var i = 0; i < _readWrite.length; i++) {
14048   _createGetter(_readWrite[i]);
14049   _createSetter(_readWrite[i]);
14050 }
14051
14052 // Create getters for read-only attributes
14053 for (var _i = 0; _i < _readOnly.length; _i++) {
14054   _createGetter(_readOnly[_i]);
14055 }
14056
14057 /** ------------------------------ Getters ------------------------------ **/
14058 /**
14059  * Get the value of `rtmpConnection` from the swf.
14060  *
14061  * @method Flash#rtmpConnection
14062  * @return {string}
14063  *         The current value of `rtmpConnection` on the swf.
14064  */
14065
14066 /**
14067  * Get the value of `rtmpStream` from the swf.
14068  *
14069  * @method Flash#rtmpStream
14070  * @return {string}
14071  *         The current value of `rtmpStream` on the swf.
14072  */
14073
14074 /**
14075  * Get the value of `preload` from the swf. `preload` indicates
14076  * what should download before the media is interacted with. It can have the following
14077  * values:
14078  * - none: nothing should be downloaded
14079  * - metadata: poster and the first few frames of the media may be downloaded to get
14080  *   media dimensions and other metadata
14081  * - auto: allow the media and metadata for the media to be downloaded before
14082  *    interaction
14083  *
14084  * @method Flash#preload
14085  * @return {string}
14086  *         The value of `preload` from the swf. Will be 'none', 'metadata',
14087  *         or 'auto'.
14088  */
14089
14090 /**
14091  * Get the value of `defaultPlaybackRate` from the swf.
14092  *
14093  * @method Flash#defaultPlaybackRate
14094  * @return {number}
14095  *         The current value of `defaultPlaybackRate` on the swf.
14096  */
14097
14098 /**
14099  * Get the value of `playbackRate` from the swf. `playbackRate` indicates
14100  * the rate at which the media is currently playing back. Examples:
14101  *   - if playbackRate is set to 2, media will play twice as fast.
14102  *   - if playbackRate is set to 0.5, media will play half as fast.
14103  *
14104  * @method Flash#playbackRate
14105  * @return {number}
14106  *         The value of `playbackRate` from the swf. A number indicating
14107  *         the current playback speed of the media, where 1 is normal speed.
14108  */
14109
14110 /**
14111  * Get the value of `autoplay` from the swf. `autoplay` indicates
14112  * that the media should start to play as soon as the page is ready.
14113  *
14114  * @method Flash#autoplay
14115  * @return {boolean}
14116  *         - The value of `autoplay` from the swf.
14117  *         - True indicates that the media ashould start as soon as the page loads.
14118  *         - False indicates that the media should not start as soon as the page loads.
14119  */
14120
14121 /**
14122  * Get the value of `loop` from the swf. `loop` indicates
14123  * that the media should return to the start of the media and continue playing once
14124  * it reaches the end.
14125  *
14126  * @method Flash#loop
14127  * @return {boolean}
14128  *         - The value of `loop` from the swf.
14129  *         - True indicates that playback should seek back to start once
14130  *           the end of a media is reached.
14131  *         - False indicates that playback should not loop back to the start when the
14132  *           end of the media is reached.
14133  */
14134
14135 /**
14136  * Get the value of `mediaGroup` from the swf.
14137  *
14138  * @method Flash#mediaGroup
14139  * @return {string}
14140  *         The current value of `mediaGroup` on the swf.
14141  */
14142
14143 /**
14144  * Get the value of `controller` from the swf.
14145  *
14146  * @method Flash#controller
14147  * @return {string}
14148  *         The current value of `controller` on the swf.
14149  */
14150
14151 /**
14152  * Get the value of `controls` from the swf. `controls` indicates
14153  * whether the native flash controls should be shown or hidden.
14154  *
14155  * @method Flash#controls
14156  * @return {boolean}
14157  *         - The value of `controls` from the swf.
14158  *         - True indicates that native controls should be showing.
14159  *         - False indicates that native controls should be hidden.
14160  */
14161
14162 /**
14163  * Get the value of the `volume` from the swf. `volume` indicates the current
14164  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14165  * so on.
14166  *
14167  * @method Flash#volume
14168  * @return {number}
14169  *         The volume percent as a decimal. Value will be between 0-1.
14170  */
14171
14172 /**
14173  * Get the value of the `muted` from the swf. `muted` indicates the current
14174  * audio level should be silent.
14175  *
14176  * @method Flash#muted
14177  * @return {boolean}
14178  *         - True if the audio should be set to silent
14179  *         - False otherwise
14180  */
14181
14182 /**
14183  * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
14184  * whether the media should start muted or not. Only changes the default state of the
14185  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14186  * current state.
14187  *
14188  * @method Flash#defaultMuted
14189  * @return {boolean}
14190  *         - The value of `defaultMuted` from the swf.
14191  *         - True indicates that the media should start muted.
14192  *         - False indicates that the media should not start muted.
14193  */
14194
14195 /**
14196  * Get the value of `networkState` from the swf. `networkState` indicates
14197  * the current network state. It returns an enumeration from the following list:
14198  * - 0: NETWORK_EMPTY
14199  * - 1: NEWORK_IDLE
14200  * - 2: NETWORK_LOADING
14201  * - 3: NETWORK_NO_SOURCE
14202  *
14203  * @method Flash#networkState
14204  * @return {number}
14205  *         The value of `networkState` from the swf. This will be a number
14206  *         from the list in the description.
14207  */
14208
14209 /**
14210  * Get the value of `readyState` from the swf. `readyState` indicates
14211  * the current state of the media element. It returns an enumeration from the
14212  * following list:
14213  * - 0: HAVE_NOTHING
14214  * - 1: HAVE_METADATA
14215  * - 2: HAVE_CURRENT_DATA
14216  * - 3: HAVE_FUTURE_DATA
14217  * - 4: HAVE_ENOUGH_DATA
14218  *
14219  * @method Flash#readyState
14220  * @return {number}
14221  *         The value of `readyState` from the swf. This will be a number
14222  *         from the list in the description.
14223  */
14224
14225 /**
14226  * Get the value of `readyState` from the swf. `readyState` indicates
14227  * the current state of the media element. It returns an enumeration from the
14228  * following list:
14229  * - 0: HAVE_NOTHING
14230  * - 1: HAVE_METADATA
14231  * - 2: HAVE_CURRENT_DATA
14232  * - 3: HAVE_FUTURE_DATA
14233  * - 4: HAVE_ENOUGH_DATA
14234  *
14235  * @method Flash#readyState
14236  * @return {number}
14237  *         The value of `readyState` from the swf. This will be a number
14238  *         from the list in the description.
14239  */
14240
14241 /**
14242  * Get the value of `initialTime` from the swf.
14243  *
14244  * @method Flash#initialTime
14245  * @return {number}
14246  *         The `initialTime` proprety on the swf.
14247  */
14248
14249 /**
14250  * Get the value of `startOffsetTime` from the swf.
14251  *
14252  * @method Flash#startOffsetTime
14253  * @return {number}
14254  *         The `startOffsetTime` proprety on the swf.
14255  */
14256
14257 /**
14258  * Get the value of `paused` from the swf. `paused` indicates whether the swf
14259  * is current paused or not.
14260  *
14261  * @method Flash#paused
14262  * @return {boolean}
14263  *         The value of `paused` from the swf.
14264  */
14265
14266 /**
14267  * Get the value of `ended` from the swf. `ended` indicates whether
14268  * the media has reached the end or not.
14269  *
14270  * @method Flash#ended
14271  * @return {boolean}
14272  *         - True indicates that the media has ended.
14273  *         - False indicates that the media has not ended.
14274  *
14275  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
14276  */
14277
14278 /**
14279  * Get the value of `videoWidth` from the swf. `videoWidth` indicates
14280  * the current width of the media in css pixels.
14281  *
14282  * @method Flash#videoWidth
14283  * @return {number}
14284  *         The value of `videoWidth` from the swf. This will be a number
14285  *         in css pixels.
14286  */
14287
14288 /**
14289  * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
14290  * the current height of the media in css pixels.
14291  *
14292  * @method Flassh.prototype.videoHeight
14293  * @return {number}
14294  *         The value of `videoHeight` from the swf. This will be a number
14295  *         in css pixels.
14296  */
14297 /** ------------------------------ Setters ------------------------------ **/
14298
14299 /**
14300  * Set the value of `rtmpConnection` on the swf.
14301  *
14302  * @method Flash#setRtmpConnection
14303  * @param {string} rtmpConnection
14304  *        New value to set the `rtmpConnection` property to.
14305  */
14306
14307 /**
14308  * Set the value of `rtmpStream` on the swf.
14309  *
14310  * @method Flash#setRtmpStream
14311  * @param {string} rtmpStream
14312  *        New value to set the `rtmpStream` property to.
14313  */
14314
14315 /**
14316  * Set the value of `preload` on the swf. `preload` indicates
14317  * what should download before the media is interacted with. It can have the following
14318  * values:
14319  * - none: nothing should be downloaded
14320  * - metadata: poster and the first few frames of the media may be downloaded to get
14321  *   media dimensions and other metadata
14322  * - auto: allow the media and metadata for the media to be downloaded before
14323  *    interaction
14324  *
14325  * @method Flash#setPreload
14326  * @param {string} preload
14327  *        The value of `preload` to set on the swf. Should be 'none', 'metadata',
14328  *        or 'auto'.
14329  */
14330
14331 /**
14332  * Set the value of `defaultPlaybackRate` on the swf.
14333  *
14334  * @method Flash#setDefaultPlaybackRate
14335  * @param {number} defaultPlaybackRate
14336  *        New value to set the `defaultPlaybackRate` property to.
14337  */
14338
14339 /**
14340  * Set the value of `playbackRate` on the swf. `playbackRate` indicates
14341  * the rate at which the media is currently playing back. Examples:
14342  *   - if playbackRate is set to 2, media will play twice as fast.
14343  *   - if playbackRate is set to 0.5, media will play half as fast.
14344  *
14345  * @method Flash#setPlaybackRate
14346  * @param {number} playbackRate
14347  *        New value of `playbackRate` on the swf. A number indicating
14348  *        the current playback speed of the media, where 1 is normal speed.
14349  */
14350
14351 /**
14352  * Set the value of `autoplay` on the swf. `autoplay` indicates
14353  * that the media should start to play as soon as the page is ready.
14354  *
14355  * @method Flash#setAutoplay
14356  * @param {boolean} autoplay
14357  *        - The value of `autoplay` from the swf.
14358  *        - True indicates that the media ashould start as soon as the page loads.
14359  *        - False indicates that the media should not start as soon as the page loads.
14360  */
14361
14362 /**
14363  * Set the value of `loop` on the swf. `loop` indicates
14364  * that the media should return to the start of the media and continue playing once
14365  * it reaches the end.
14366  *
14367  * @method Flash#setLoop
14368  * @param {boolean} loop
14369  *        - True indicates that playback should seek back to start once
14370  *          the end of a media is reached.
14371  *        - False indicates that playback should not loop back to the start when the
14372  *          end of the media is reached.
14373  */
14374
14375 /**
14376  * Set the value of `mediaGroup` on the swf.
14377  *
14378  * @method Flash#setMediaGroup
14379  * @param {string} mediaGroup
14380  *        New value of `mediaGroup` to set on the swf.
14381  */
14382
14383 /**
14384  * Set the value of `controller` on the swf.
14385  *
14386  * @method Flash#setController
14387  * @param {string} controller
14388  *        New value the current value of `controller` on the swf.
14389  */
14390
14391 /**
14392  * Get the value of `controls` from the swf. `controls` indicates
14393  * whether the native flash controls should be shown or hidden.
14394  *
14395  * @method Flash#controls
14396  * @return {boolean}
14397  *         - The value of `controls` from the swf.
14398  *         - True indicates that native controls should be showing.
14399  *         - False indicates that native controls should be hidden.
14400  */
14401
14402 /**
14403  * Set the value of the `volume` on the swf. `volume` indicates the current
14404  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14405  * so on.
14406  *
14407  * @method Flash#setVolume
14408  * @param {number} percentAsDecimal
14409  *         The volume percent as a decimal. Value will be between 0-1.
14410  */
14411
14412 /**
14413  * Set the value of the `muted` on the swf. `muted` indicates that the current
14414  * audio level should be silent.
14415  *
14416  * @method Flash#setMuted
14417  * @param {boolean} muted
14418  *         - True if the audio should be set to silent
14419  *         - False otherwise
14420  */
14421
14422 /**
14423  * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
14424  * whether the media should start muted or not. Only changes the default state of the
14425  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14426  * current state.
14427  *
14428  * @method Flash#setDefaultMuted
14429  * @param {boolean} defaultMuted
14430  *         - True indicates that the media should start muted.
14431  *         - False indicates that the media should not start muted.
14432  */
14433
14434 /* Flash Support Testing -------------------------------------------------------- */
14435
14436 /**
14437  * Check if the Flash tech is currently supported.
14438  *
14439  * @return {boolean}
14440  *          - True if the flash tech is supported.
14441  *          - False otherwise.
14442  */
14443 Flash.isSupported = function () {
14444   return Flash.version()[0] >= 10;
14445   // return swfobject.hasFlashPlayerVersion('10');
14446 };
14447
14448 // Add Source Handler pattern functions to this tech
14449 _tech2['default'].withSourceHandlers(Flash);
14450
14451 /*
14452  * Native source handler for flash,  simply passes the source to the swf element.
14453  *
14454  * @property {Tech~SourceObject} source
14455  *           The source object
14456  *
14457  * @property {Flash} tech
14458  *           The instance of the Flash tech
14459  */
14460 Flash.nativeSourceHandler = {};
14461
14462 /**
14463  * Check if the Flash can play the given mime type.
14464  *
14465  * @param {string} type
14466  *        The mimetype to check
14467  *
14468  * @return {string}
14469  *         'maybe', or '' (empty string)
14470  */
14471 Flash.nativeSourceHandler.canPlayType = function (type) {
14472   if (type in Flash.formats) {
14473     return 'maybe';
14474   }
14475
14476   return '';
14477 };
14478
14479 /**
14480  * Check if the media element can handle a source natively.
14481  *
14482  * @param {Tech~SourceObject} source
14483  *         The source object
14484  *
14485  * @param {Object} [options]
14486  *         Options to be passed to the tech.
14487  *
14488  * @return {string}
14489  *         'maybe', or '' (empty string).
14490  */
14491 Flash.nativeSourceHandler.canHandleSource = function (source, options) {
14492   var type = void 0;
14493
14494   function guessMimeType(src) {
14495     var ext = Url.getFileExtension(src);
14496
14497     if (ext) {
14498       return 'video/' + ext;
14499     }
14500     return '';
14501   }
14502
14503   if (!source.type) {
14504     type = guessMimeType(source.src);
14505   } else {
14506     // Strip code information from the type because we don't get that specific
14507     type = source.type.replace(/;.*/, '').toLowerCase();
14508   }
14509
14510   return Flash.nativeSourceHandler.canPlayType(type);
14511 };
14512
14513 /**
14514  * Pass the source to the swf.
14515  *
14516  * @param {Tech~SourceObject} source
14517  *        The source object
14518  *
14519  * @param {Flash} tech
14520  *        The instance of the Flash tech
14521  *
14522  * @param {Object} [options]
14523  *        The options to pass to the source
14524  */
14525 Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
14526   tech.setSrc(source.src);
14527 };
14528
14529 /**
14530  * noop for native source handler dispose, as cleanup will happen automatically.
14531  */
14532 Flash.nativeSourceHandler.dispose = function () {};
14533
14534 // Register the native source handler
14535 Flash.registerSourceHandler(Flash.nativeSourceHandler);
14536
14537 /**
14538  * Flash supported mime types.
14539  *
14540  * @constant {Object}
14541  */
14542 Flash.formats = {
14543   'video/flv': 'FLV',
14544   'video/x-flv': 'FLV',
14545   'video/mp4': 'MP4',
14546   'video/m4v': 'MP4'
14547 };
14548
14549 /**
14550  * Called when the the swf is "ready", and makes sure that the swf is really
14551  * ready using {@link Flash#checkReady}
14552  */
14553 Flash.onReady = function (currSwf) {
14554   var el = Dom.getEl(currSwf);
14555   var tech = el && el.tech;
14556
14557   // if there is no el then the tech has been disposed
14558   // and the tech element was removed from the player div
14559   if (tech && tech.el()) {
14560     // check that the flash object is really ready
14561     Flash.checkReady(tech);
14562   }
14563 };
14564
14565 /**
14566  * The SWF isn't always ready when it says it is. Sometimes the API functions still
14567  * need to be added to the object. If it's not ready, we set a timeout to check again
14568  * shortly.
14569  *
14570  * @param {Flash} tech
14571  *        The instance of the flash tech to check.
14572  */
14573 Flash.checkReady = function (tech) {
14574   // stop worrying if the tech has been disposed
14575   if (!tech.el()) {
14576     return;
14577   }
14578
14579   // check if API property exists
14580   if (tech.el().vjs_getProperty) {
14581     // tell tech it's ready
14582     tech.triggerReady();
14583   } else {
14584     // wait longer
14585     this.setTimeout(function () {
14586       Flash.checkReady(tech);
14587     }, 50);
14588   }
14589 };
14590
14591 /**
14592  * Trigger events from the swf on the Flash Tech.
14593  *
14594  * @param {number} swfID
14595  *        The id of the swf that had the event
14596  *
14597  * @param {string} eventName
14598  *        The name of the event to trigger
14599  */
14600 Flash.onEvent = function (swfID, eventName) {
14601   var tech = Dom.getEl(swfID).tech;
14602   var args = Array.prototype.slice.call(arguments, 2);
14603
14604   // dispatch Flash events asynchronously for two reasons:
14605   // - Flash swallows any exceptions generated by javascript it
14606   //   invokes
14607   // - Flash is suspended until the javascript returns which may cause
14608   //   playback performance issues
14609   tech.setTimeout(function () {
14610     tech.trigger(eventName, args);
14611   }, 1);
14612 };
14613
14614 /**
14615  * Log errors from the swf on the Flash tech.
14616  *
14617  * @param {number} swfID
14618  *        The id of the swf that had an error.
14619  *
14620  * @param {string} The error string
14621  *        The error to set on the Flash Tech.
14622  *
14623  * @return {MediaError|undefined}
14624  *          - Returns a MediaError when err is 'srcnotfound'
14625  *          - Returns undefined otherwise.
14626  */
14627 Flash.onError = function (swfID, err) {
14628   var tech = Dom.getEl(swfID).tech;
14629
14630   // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
14631   if (err === 'srcnotfound') {
14632     return tech.error(4);
14633   }
14634
14635   // trigger a custom error
14636   tech.error('FLASH: ' + err);
14637 };
14638
14639 /**
14640  * Get the current version of Flash that is in use on the page.
14641  *
14642  * @return {Array}
14643  *          an array of versions that are available.
14644  */
14645 Flash.version = function () {
14646   var version = '0,0,0';
14647
14648   // IE
14649   try {
14650     version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14651
14652     // other browsers
14653   } catch (e) {
14654     try {
14655       if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
14656         version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14657       }
14658     } catch (err) {
14659       // satisfy linter
14660     }
14661   }
14662   return version.split(',');
14663 };
14664
14665 /**
14666  * Only use for non-iframe embeds.
14667  *
14668  * @param {Object} swf
14669  *        The videojs-swf object.
14670  *
14671  * @param {Object} flashVars
14672  *        Names and values to use as flash option variables.
14673  *
14674  * @param {Object} params
14675  *        Style parameters to set on the object.
14676  *
14677  * @param {Object} attributes
14678  *        Attributes to set on the element.
14679  *
14680  * @return {Element}
14681  *          The embeded Flash DOM element.
14682  */
14683 Flash.embed = function (swf, flashVars, params, attributes) {
14684   var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
14685
14686   // Get element by embedding code and retrieving created element
14687   var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
14688
14689   return obj;
14690 };
14691
14692 /**
14693  * Only use for non-iframe embeds.
14694  *
14695  * @param {Object} swf
14696  *        The videojs-swf object.
14697  *
14698  * @param {Object} flashVars
14699  *        Names and values to use as flash option variables.
14700  *
14701  * @param {Object} params
14702  *        Style parameters to set on the object.
14703  *
14704  * @param {Object} attributes
14705  *        Attributes to set on the element.
14706  *
14707  * @return {Element}
14708  *          The embeded Flash DOM element.
14709  */
14710 Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
14711   var objTag = '<object type="application/x-shockwave-flash" ';
14712   var flashVarsString = '';
14713   var paramsString = '';
14714   var attrsString = '';
14715
14716   // Convert flash vars to string
14717   if (flashVars) {
14718     Object.getOwnPropertyNames(flashVars).forEach(function (key) {
14719       flashVarsString += key + '=' + flashVars[key] + '&amp;';
14720     });
14721   }
14722
14723   // Add swf, flashVars, and other default params
14724   params = (0, _obj.assign)({
14725     movie: swf,
14726     flashvars: flashVarsString,
14727     // Required to talk to swf
14728     allowScriptAccess: 'always',
14729     // All should be default, but having security issues.
14730     allowNetworking: 'all'
14731   }, params);
14732
14733   // Create param tags string
14734   Object.getOwnPropertyNames(params).forEach(function (key) {
14735     paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
14736   });
14737
14738   attributes = (0, _obj.assign)({
14739     // Add swf to attributes (need both for IE and Others to work)
14740     data: swf,
14741
14742     // Default to 100% width/height
14743     width: '100%',
14744     height: '100%'
14745
14746   }, attributes);
14747
14748   // Create Attributes string
14749   Object.getOwnPropertyNames(attributes).forEach(function (key) {
14750     attrsString += key + '="' + attributes[key] + '" ';
14751   });
14752
14753   return '' + objTag + attrsString + '>' + paramsString + '</object>';
14754 };
14755
14756 // Run Flash through the RTMP decorator
14757 (0, _flashRtmp2['default'])(Flash);
14758
14759 _component2['default'].registerComponent('Flash', Flash);
14760 _tech2['default'].registerTech('Flash', Flash);
14761 exports['default'] = Flash;
14762
14763 },{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){
14764 'use strict';
14765
14766 exports.__esModule = true;
14767
14768 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.']);
14769
14770 var _tech = _dereq_(62);
14771
14772 var _tech2 = _interopRequireDefault(_tech);
14773
14774 var _component = _dereq_(5);
14775
14776 var _component2 = _interopRequireDefault(_component);
14777
14778 var _dom = _dereq_(81);
14779
14780 var Dom = _interopRequireWildcard(_dom);
14781
14782 var _url = _dereq_(92);
14783
14784 var Url = _interopRequireWildcard(_url);
14785
14786 var _fn = _dereq_(83);
14787
14788 var Fn = _interopRequireWildcard(_fn);
14789
14790 var _log = _dereq_(86);
14791
14792 var _log2 = _interopRequireDefault(_log);
14793
14794 var _tsml = _dereq_(98);
14795
14796 var _tsml2 = _interopRequireDefault(_tsml);
14797
14798 var _browser = _dereq_(78);
14799
14800 var browser = _interopRequireWildcard(_browser);
14801
14802 var _document = _dereq_(94);
14803
14804 var _document2 = _interopRequireDefault(_document);
14805
14806 var _window = _dereq_(95);
14807
14808 var _window2 = _interopRequireDefault(_window);
14809
14810 var _obj = _dereq_(88);
14811
14812 var _mergeOptions = _dereq_(87);
14813
14814 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
14815
14816 var _toTitleCase = _dereq_(91);
14817
14818 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
14819
14820 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; } }
14821
14822 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14823
14824 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
14825
14826 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
14827
14828 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; }
14829
14830 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; } /**
14831                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file html5.js
14832                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
14833
14834
14835 /**
14836  * HTML5 Media Controller - Wrapper for HTML5 Media API
14837  *
14838  * @mixes Tech~SouceHandlerAdditions
14839  * @extends Tech
14840  */
14841 var Html5 = function (_Tech) {
14842   _inherits(Html5, _Tech);
14843
14844   /**
14845    * Create an instance of this Tech.
14846    *
14847    * @param {Object} [options]
14848    *        The key/value store of player options.
14849    *
14850    * @param {Component~ReadyCallback} ready
14851    *        Callback function to call when the `HTML5` Tech is ready.
14852    */
14853   function Html5(options, ready) {
14854     _classCallCheck(this, Html5);
14855
14856     var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
14857
14858     var source = options.source;
14859     var crossoriginTracks = false;
14860
14861     // Set the source if one is provided
14862     // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
14863     // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
14864     // anyway so the error gets fired.
14865     if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
14866       _this.setSource(source);
14867     } else {
14868       _this.handleLateInit_(_this.el_);
14869     }
14870
14871     if (_this.el_.hasChildNodes()) {
14872
14873       var nodes = _this.el_.childNodes;
14874       var nodesLength = nodes.length;
14875       var removeNodes = [];
14876
14877       while (nodesLength--) {
14878         var node = nodes[nodesLength];
14879         var nodeName = node.nodeName.toLowerCase();
14880
14881         if (nodeName === 'track') {
14882           if (!_this.featuresNativeTextTracks) {
14883             // Empty video tag tracks so the built-in player doesn't use them also.
14884             // This may not be fast enough to stop HTML5 browsers from reading the tags
14885             // so we'll need to turn off any default tracks if we're manually doing
14886             // captions and subtitles. videoElement.textTracks
14887             removeNodes.push(node);
14888           } else {
14889             // store HTMLTrackElement and TextTrack to remote list
14890             _this.remoteTextTrackEls().addTrackElement_(node);
14891             _this.remoteTextTracks().addTrack_(node.track);
14892             if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
14893               crossoriginTracks = true;
14894             }
14895           }
14896         }
14897       }
14898
14899       for (var i = 0; i < removeNodes.length; i++) {
14900         _this.el_.removeChild(removeNodes[i]);
14901       }
14902     }
14903
14904     // TODO: add text tracks into this list
14905     var trackTypes = ['audio', 'video'];
14906
14907     // ProxyNative Video/Audio Track
14908     trackTypes.forEach(function (type) {
14909       var elTracks = _this.el()[type + 'Tracks'];
14910       var techTracks = _this[type + 'Tracks']();
14911       var capitalType = (0, _toTitleCase2['default'])(type);
14912
14913       if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
14914         return;
14915       }
14916
14917       _this['handle' + capitalType + 'TrackChange_'] = function (e) {
14918         techTracks.trigger({
14919           type: 'change',
14920           target: techTracks,
14921           currentTarget: techTracks,
14922           srcElement: techTracks
14923         });
14924       };
14925
14926       _this['handle' + capitalType + 'TrackAdd_'] = function (e) {
14927         return techTracks.addTrack(e.track);
14928       };
14929       _this['handle' + capitalType + 'TrackRemove_'] = function (e) {
14930         return techTracks.removeTrack(e.track);
14931       };
14932
14933       elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']);
14934       elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']);
14935       elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']);
14936       _this['removeOld' + capitalType + 'Tracks_'] = function (e) {
14937         return _this.removeOldTracks_(techTracks, elTracks);
14938       };
14939
14940       // Remove (native) tracks that are not used anymore
14941       _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']);
14942     });
14943
14944     if (_this.featuresNativeTextTracks) {
14945       if (crossoriginTracks) {
14946         _log2['default'].warn((0, _tsml2['default'])(_templateObject));
14947       }
14948
14949       _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange);
14950       _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd);
14951       _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove);
14952       _this.proxyNativeTextTracks_();
14953     }
14954
14955     // Determine if native controls should be used
14956     // Our goal should be to get the custom controls on mobile solid everywhere
14957     // so we can remove this all together. Right now this will block custom
14958     // controls on touch enabled laptops like the Chrome Pixel
14959     if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
14960       _this.setControls(true);
14961     }
14962
14963     // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
14964     // into a `fullscreenchange` event
14965     _this.proxyWebkitFullscreen_();
14966
14967     _this.triggerReady();
14968     return _this;
14969   }
14970
14971   /**
14972    * Dispose of `HTML5` media element and remove all tracks.
14973    */
14974
14975
14976   Html5.prototype.dispose = function dispose() {
14977     var _this2 = this;
14978
14979     // Un-ProxyNativeTracks
14980     ['audio', 'video', 'text'].forEach(function (type) {
14981       var capitalType = (0, _toTitleCase2['default'])(type);
14982       var tl = _this2.el_[type + 'Tracks'];
14983
14984       if (tl && tl.removeEventListener) {
14985         tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
14986         tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
14987         tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
14988       }
14989
14990       // Stop removing old text tracks
14991       if (tl) {
14992         _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']);
14993       }
14994     });
14995
14996     Html5.disposeMediaElement(this.el_);
14997     // tech will handle clearing of the emulated track list
14998     _Tech.prototype.dispose.call(this);
14999   };
15000
15001   /**
15002    * Create the `Html5` Tech's DOM element.
15003    *
15004    * @return {Element}
15005    *         The element that gets created.
15006    */
15007
15008
15009   Html5.prototype.createEl = function createEl() {
15010     var el = this.options_.tag;
15011
15012     // Check if this browser supports moving the element into the box.
15013     // On the iPhone video will break if you move the element,
15014     // So we have to create a brand new element.
15015     // If we ingested the player div, we do not need to move the media element.
15016     if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
15017
15018       // If the original tag is still there, clone and remove it.
15019       if (el) {
15020         var clone = el.cloneNode(true);
15021
15022         if (el.parentNode) {
15023           el.parentNode.insertBefore(clone, el);
15024         }
15025         Html5.disposeMediaElement(el);
15026         el = clone;
15027       } else {
15028         el = _document2['default'].createElement('video');
15029
15030         // determine if native controls should be used
15031         var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
15032         var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
15033
15034         if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
15035           delete attributes.controls;
15036         }
15037
15038         Dom.setElAttributes(el, (0, _obj.assign)(attributes, {
15039           id: this.options_.techId,
15040           'class': 'vjs-tech'
15041         }));
15042       }
15043
15044       el.playerId = this.options_.playerId;
15045     }
15046
15047     // Update specific tag settings, in case they were overridden
15048     var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
15049
15050     for (var i = settingsAttrs.length - 1; i >= 0; i--) {
15051       var attr = settingsAttrs[i];
15052       var overwriteAttrs = {};
15053
15054       if (typeof this.options_[attr] !== 'undefined') {
15055         overwriteAttrs[attr] = this.options_[attr];
15056       }
15057       Dom.setElAttributes(el, overwriteAttrs);
15058     }
15059
15060     return el;
15061   };
15062
15063   /**
15064    * This will be triggered if the loadstart event has already fired, before videojs was
15065    * ready. Two known examples of when this can happen are:
15066    * 1. If we're loading the playback object after it has started loading
15067    * 2. The media is already playing the (often with autoplay on) then
15068    *
15069    * This function will fire another loadstart so that videojs can catchup.
15070    *
15071    * @fires Tech#loadstart
15072    *
15073    * @return {undefined}
15074    *         returns nothing.
15075    */
15076
15077
15078   Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
15079     if (el.networkState === 0 || el.networkState === 3) {
15080       // The video element hasn't started loading the source yet
15081       // or didn't find a source
15082       return;
15083     }
15084
15085     if (el.readyState === 0) {
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       };
15100
15101       this.on('loadstart', setLoadstartFired);
15102
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       };
15110
15111       this.on('loadedmetadata', triggerLoadstart);
15112
15113       this.ready(function () {
15114         this.off('loadstart', setLoadstartFired);
15115         this.off('loadedmetadata', triggerLoadstart);
15116
15117         if (!loadstartFired) {
15118           // We did miss the original native loadstart. Fire it now.
15119           this.trigger('loadstart');
15120         }
15121       });
15122
15123       return;
15124     }
15125
15126     // From here on we know that loadstart already fired and we missed it.
15127     // The other readyState events aren't as much of a problem if we double
15128     // them, so not going to go to as much trouble as loadstart to prevent
15129     // that unless we find reason to.
15130     var eventsToTrigger = ['loadstart'];
15131
15132     // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
15133     eventsToTrigger.push('loadedmetadata');
15134
15135     // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
15136     if (el.readyState >= 2) {
15137       eventsToTrigger.push('loadeddata');
15138     }
15139
15140     // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
15141     if (el.readyState >= 3) {
15142       eventsToTrigger.push('canplay');
15143     }
15144
15145     // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
15146     if (el.readyState >= 4) {
15147       eventsToTrigger.push('canplaythrough');
15148     }
15149
15150     // We still need to give the player time to add event listeners
15151     this.ready(function () {
15152       eventsToTrigger.forEach(function (type) {
15153         this.trigger(type);
15154       }, this);
15155     });
15156   };
15157
15158   /**
15159    * Add event listeners to native text track events. This adds the native text tracks
15160    * to our emulated {@link TextTrackList}.
15161    */
15162
15163
15164   Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
15165     var tt = this.el().textTracks;
15166
15167     if (tt) {
15168       // Add tracks - if player is initialised after DOM loaded, textTracks
15169       // will not trigger addtrack
15170       for (var i = 0; i < tt.length; i++) {
15171         this.textTracks().addTrack_(tt[i]);
15172       }
15173
15174       if (tt.addEventListener) {
15175         tt.addEventListener('change', this.handleTextTrackChange_);
15176         tt.addEventListener('addtrack', this.handleTextTrackAdd_);
15177         tt.addEventListener('removetrack', this.handleTextTrackRemove_);
15178       }
15179
15180       // Remove (native) texttracks that are not used anymore
15181       this.on('loadstart', this.removeOldTextTracks_);
15182     }
15183   };
15184
15185   /**
15186    * Handle any {@link TextTrackList} `change` event.
15187    *
15188    * @param {EventTarget~Event} e
15189    *        The `change` event that caused this to run.
15190    *
15191    * @listens TextTrackList#change
15192    */
15193
15194
15195   Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
15196     var tt = this.textTracks();
15197
15198     this.textTracks().trigger({
15199       type: 'change',
15200       target: tt,
15201       currentTarget: tt,
15202       srcElement: tt
15203     });
15204   };
15205
15206   /**
15207    * Handle any {@link TextTrackList} `addtrack` event.
15208    *
15209    * @param {EventTarget~Event} e
15210    *        The `addtrack` event that caused this to run.
15211    *
15212    * @listens TextTrackList#addtrack
15213    */
15214
15215
15216   Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
15217     this.textTracks().addTrack_(e.track);
15218   };
15219
15220   /**
15221    * Handle any {@link TextTrackList} `removetrack` event.
15222    *
15223    * @param {EventTarget~Event} e
15224    *        The `removetrack` event that caused this to run.
15225    *
15226    * @listens TextTrackList#removetrack
15227    */
15228
15229
15230   Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
15231     this.textTracks().removeTrack_(e.track);
15232   };
15233
15234   /**
15235    * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or
15236    * {@link TextTrack}s that are not in the media elements TrackList.
15237    *
15238    * @param {TrackList} techTracks
15239    *        HTML5 Tech's TrackList to search through
15240    *
15241    * @param {TrackList} elTracks
15242    *        HTML5 media elements TrackList to search trough.
15243    *
15244    * @private
15245    */
15246
15247
15248   Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) {
15249     // This will loop over the techTracks and check if they are still used by the HTML5 media element
15250     // If not, they will be removed from the emulated list
15251     var removeTracks = [];
15252
15253     if (!elTracks) {
15254       return;
15255     }
15256
15257     for (var i = 0; i < techTracks.length; i++) {
15258       var techTrack = techTracks[i];
15259       var found = false;
15260
15261       for (var j = 0; j < elTracks.length; j++) {
15262         if (elTracks[j] === techTrack) {
15263           found = true;
15264           break;
15265         }
15266       }
15267
15268       if (!found) {
15269         removeTracks.push(techTrack);
15270       }
15271     }
15272
15273     for (var _i = 0; _i < removeTracks.length; _i++) {
15274       var track = removeTracks[_i];
15275
15276       techTracks.removeTrack_(track);
15277     }
15278   };
15279
15280   /**
15281    * Remove {@link TextTrack}s that dont exist in the native track list from our
15282    * emulated {@link TextTrackList}.
15283    *
15284    * @listens Tech#loadstart
15285    */
15286
15287
15288   Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) {
15289     var techTracks = this.textTracks();
15290     var elTracks = this.el().textTracks;
15291
15292     this.removeOldTracks_(techTracks, elTracks);
15293   };
15294
15295   /**
15296    * Called by {@link Player#play} to play using the `Html5` `Tech`.
15297    */
15298
15299
15300   Html5.prototype.play = function play() {
15301     var playPromise = this.el_.play();
15302
15303     // Catch/silence error when a pause interrupts a play request
15304     // on browsers which return a promise
15305     if (playPromise !== undefined && typeof playPromise.then === 'function') {
15306       playPromise.then(null, function (e) {});
15307     }
15308   };
15309
15310   /**
15311    * Set current time for the `HTML5` tech.
15312    *
15313    * @param {number} seconds
15314    *        Set the current time of the media to this.
15315    */
15316
15317
15318   Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
15319     try {
15320       this.el_.currentTime = seconds;
15321     } catch (e) {
15322       (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
15323       // this.warning(VideoJS.warnings.videoNotReady);
15324     }
15325   };
15326
15327   /**
15328    * Get the current duration of the HTML5 media element.
15329    *
15330    * @return {number}
15331    *         The duration of the media or 0 if there is no duration.
15332    */
15333
15334
15335   Html5.prototype.duration = function duration() {
15336     var _this3 = this;
15337
15338     // Android Chrome will report duration as Infinity for VOD HLS until after
15339     // playback has started, which triggers the live display erroneously.
15340     // Return NaN if playback has not started and trigger a durationupdate once
15341     // the duration can be reliably known.
15342     if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
15343       if (this.el_.currentTime === 0) {
15344         // Wait for the first `timeupdate` with currentTime > 0 - there may be
15345         // several with 0
15346         var checkProgress = function checkProgress() {
15347           if (_this3.el_.currentTime > 0) {
15348             // Trigger durationchange for genuinely live video
15349             if (_this3.el_.duration === Infinity) {
15350               _this3.trigger('durationchange');
15351             }
15352             _this3.off('timeupdate', checkProgress);
15353           }
15354         };
15355
15356         this.on('timeupdate', checkProgress);
15357         return NaN;
15358       }
15359     }
15360     return this.el_.duration || NaN;
15361   };
15362
15363   /**
15364    * Get the current width of the HTML5 media element.
15365    *
15366    * @return {number}
15367    *         The width of the HTML5 media element.
15368    */
15369
15370
15371   Html5.prototype.width = function width() {
15372     return this.el_.offsetWidth;
15373   };
15374
15375   /**
15376    * Get the current height of the HTML5 media element.
15377    *
15378    * @return {number}
15379    *         The heigth of the HTML5 media element.
15380    */
15381
15382
15383   Html5.prototype.height = function height() {
15384     return this.el_.offsetHeight;
15385   };
15386
15387   /**
15388    * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
15389    * `fullscreenchange` event.
15390    *
15391    * @private
15392    * @fires fullscreenchange
15393    * @listens webkitendfullscreen
15394    * @listens webkitbeginfullscreen
15395    * @listens webkitbeginfullscreen
15396    */
15397
15398
15399   Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
15400     var _this4 = this;
15401
15402     if (!('webkitDisplayingFullscreen' in this.el_)) {
15403       return;
15404     }
15405
15406     var endFn = function endFn() {
15407       this.trigger('fullscreenchange', { isFullscreen: false });
15408     };
15409
15410     var beginFn = function beginFn() {
15411       this.one('webkitendfullscreen', endFn);
15412
15413       this.trigger('fullscreenchange', { isFullscreen: true });
15414     };
15415
15416     this.on('webkitbeginfullscreen', beginFn);
15417     this.on('dispose', function () {
15418       _this4.off('webkitbeginfullscreen', beginFn);
15419       _this4.off('webkitendfullscreen', endFn);
15420     });
15421   };
15422
15423   /**
15424    * Check if fullscreen is supported on the current playback device.
15425    *
15426    * @return {boolean}
15427    *         - True if fullscreen is supported.
15428    *         - False if fullscreen is not supported.
15429    */
15430
15431
15432   Html5.prototype.supportsFullScreen = function supportsFullScreen() {
15433     if (typeof this.el_.webkitEnterFullScreen === 'function') {
15434       var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
15435
15436       // Seems to be broken in Chromium/Chrome && Safari in Leopard
15437       if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
15438         return true;
15439       }
15440     }
15441     return false;
15442   };
15443
15444   /**
15445    * Request that the `HTML5` Tech enter fullscreen.
15446    */
15447
15448
15449   Html5.prototype.enterFullScreen = function enterFullScreen() {
15450     var video = this.el_;
15451
15452     if (video.paused && video.networkState <= video.HAVE_METADATA) {
15453       // attempt to prime the video element for programmatic access
15454       // this isn't necessary on the desktop but shouldn't hurt
15455       this.el_.play();
15456
15457       // playing and pausing synchronously during the transition to fullscreen
15458       // can get iOS ~6.1 devices into a play/pause loop
15459       this.setTimeout(function () {
15460         video.pause();
15461         video.webkitEnterFullScreen();
15462       }, 0);
15463     } else {
15464       video.webkitEnterFullScreen();
15465     }
15466   };
15467
15468   /**
15469    * Request that the `HTML5` Tech exit fullscreen.
15470    */
15471
15472
15473   Html5.prototype.exitFullScreen = function exitFullScreen() {
15474     this.el_.webkitExitFullScreen();
15475   };
15476
15477   /**
15478    * A getter/setter for the `Html5` Tech's source object.
15479    * > Note: Please use {@link Html5#setSource}
15480    *
15481    * @param {Tech~SourceObject} [src]
15482    *        The source object you want to set on the `HTML5` techs element.
15483    *
15484    * @return {Tech~SourceObject|undefined}
15485    *         - The current source object when a source is not passed in.
15486    *         - undefined when setting
15487    *
15488    * @deprecated Since version 5.
15489    */
15490
15491
15492   Html5.prototype.src = function src(_src) {
15493     if (_src === undefined) {
15494       return this.el_.src;
15495     }
15496
15497     // Setting src through `src` instead of `setSrc` will be deprecated
15498     this.setSrc(_src);
15499   };
15500
15501   /**
15502    * Reset the tech by removing all sources and then calling
15503    * {@link Html5.resetMediaElement}.
15504    */
15505
15506
15507   Html5.prototype.reset = function reset() {
15508     Html5.resetMediaElement(this.el_);
15509   };
15510
15511   /**
15512    * Get the current source on the `HTML5` Tech. Falls back to returning the source from
15513    * the HTML5 media element.
15514    *
15515    * @return {Tech~SourceObject}
15516    *         The current source object from the HTML5 tech. With a fallback to the
15517    *         elements source.
15518    */
15519
15520
15521   Html5.prototype.currentSrc = function currentSrc() {
15522     if (this.currentSource_) {
15523       return this.currentSource_.src;
15524     }
15525     return this.el_.currentSrc;
15526   };
15527
15528   /**
15529    * Set controls attribute for the HTML5 media Element.
15530    *
15531    * @param {string} val
15532    *        Value to set the controls attribute to
15533    */
15534
15535
15536   Html5.prototype.setControls = function setControls(val) {
15537     this.el_.controls = !!val;
15538   };
15539
15540   /**
15541    * Create and returns a remote {@link TextTrack} object.
15542    *
15543    * @param {string} kind
15544    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
15545    *
15546    * @param {string} [label]
15547    *        Label to identify the text track
15548    *
15549    * @param {string} [language]
15550    *        Two letter language abbreviation
15551    *
15552    * @return {TextTrack}
15553    *         The TextTrack that gets created.
15554    */
15555
15556
15557   Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15558     if (!this.featuresNativeTextTracks) {
15559       return _Tech.prototype.addTextTrack.call(this, kind, label, language);
15560     }
15561
15562     return this.el_.addTextTrack(kind, label, language);
15563   };
15564
15565   /**
15566    * Creates either native TextTrack or an emulated TextTrack depending
15567    * on the value of `featuresNativeTextTracks`
15568    *
15569    * @param {Object} options
15570    *        The object should contain the options to intialize the TextTrack with.
15571    *
15572    * @param {string} [options.kind]
15573    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
15574    *
15575    * @param {string} [options.label].
15576    *        Label to identify the text track
15577    *
15578    * @param {string} [options.language]
15579    *        Two letter language abbreviation.
15580    *
15581    * @param {boolean} [options.default]
15582    *        Default this track to on.
15583    *
15584    * @param {string} [options.id]
15585    *        The internal id to assign this track.
15586    *
15587    * @param {string} [options.src]
15588    *        A source url for the track.
15589    *
15590    * @return {HTMLTrackElement}
15591    *         The track element that gets created.
15592    */
15593
15594
15595   Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
15596     if (!this.featuresNativeTextTracks) {
15597       return _Tech.prototype.createRemoteTextTrack.call(this, options);
15598     }
15599     var htmlTrackElement = _document2['default'].createElement('track');
15600
15601     if (options.kind) {
15602       htmlTrackElement.kind = options.kind;
15603     }
15604     if (options.label) {
15605       htmlTrackElement.label = options.label;
15606     }
15607     if (options.language || options.srclang) {
15608       htmlTrackElement.srclang = options.language || options.srclang;
15609     }
15610     if (options['default']) {
15611       htmlTrackElement['default'] = options['default'];
15612     }
15613     if (options.id) {
15614       htmlTrackElement.id = options.id;
15615     }
15616     if (options.src) {
15617       htmlTrackElement.src = options.src;
15618     }
15619
15620     return htmlTrackElement;
15621   };
15622
15623   /**
15624    * Creates a remote text track object and returns an html track element.
15625    *
15626    * @param {Object} options The object should contain values for
15627    * kind, language, label, and src (location of the WebVTT file)
15628    * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
15629    * automatically removed from the video element whenever the source changes
15630    * @return {HTMLTrackElement} An Html Track Element.
15631    * This can be an emulated {@link HTMLTrackElement} or a native one.
15632    * @deprecated The default value of the "manualCleanup" parameter will default
15633    * to "false" in upcoming versions of Video.js
15634    */
15635
15636
15637   Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
15638     var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
15639
15640     if (this.featuresNativeTextTracks) {
15641       this.el().appendChild(htmlTrackElement);
15642     }
15643
15644     return htmlTrackElement;
15645   };
15646
15647   /**
15648    * Remove remote `TextTrack` from `TextTrackList` object
15649    *
15650    * @param {TextTrack} track
15651    *        `TextTrack` object to remove
15652    */
15653
15654
15655   Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15656     _Tech.prototype.removeRemoteTextTrack.call(this, track);
15657
15658     if (this.featuresNativeTextTracks) {
15659       var tracks = this.$$('track');
15660
15661       var i = tracks.length;
15662
15663       while (i--) {
15664         if (track === tracks[i] || track === tracks[i].track) {
15665           this.el().removeChild(tracks[i]);
15666         }
15667       }
15668     }
15669   };
15670
15671   return Html5;
15672 }(_tech2['default']);
15673
15674 /* HTML5 Support Testing ---------------------------------------------------- */
15675
15676 if (Dom.isReal()) {
15677
15678   /**
15679    * Element for testing browser HTML5 media capabilities
15680    *
15681    * @type {Element}
15682    * @constant
15683    * @private
15684    */
15685   Html5.TEST_VID = _document2['default'].createElement('video');
15686   var track = _document2['default'].createElement('track');
15687
15688   track.kind = 'captions';
15689   track.srclang = 'en';
15690   track.label = 'English';
15691   Html5.TEST_VID.appendChild(track);
15692 }
15693
15694 /**
15695  * Check if HTML5 media is supported by this browser/device.
15696  *
15697  * @return {boolean}
15698  *         - True if HTML5 media is supported.
15699  *         - False if HTML5 media is not supported.
15700  */
15701 Html5.isSupported = function () {
15702   // IE9 with no Media Player is a LIAR! (#984)
15703   try {
15704     Html5.TEST_VID.volume = 0.5;
15705   } catch (e) {
15706     return false;
15707   }
15708
15709   return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
15710 };
15711
15712 /**
15713  * Check if the volume can be changed in this browser/device.
15714  * Volume cannot be changed in a lot of mobile devices.
15715  * Specifically, it can't be changed from 1 on iOS.
15716  *
15717  * @return {boolean}
15718  *         - True if volume can be controlled
15719  *         - False otherwise
15720  */
15721 Html5.canControlVolume = function () {
15722   // IE will error if Windows Media Player not installed #3315
15723   try {
15724     var volume = Html5.TEST_VID.volume;
15725
15726     Html5.TEST_VID.volume = volume / 2 + 0.1;
15727     return volume !== Html5.TEST_VID.volume;
15728   } catch (e) {
15729     return false;
15730   }
15731 };
15732
15733 /**
15734  * Check if the playback rate can be changed in this browser/device.
15735  *
15736  * @return {boolean}
15737  *         - True if playback rate can be controlled
15738  *         - False otherwise
15739  */
15740 Html5.canControlPlaybackRate = function () {
15741   // Playback rate API is implemented in Android Chrome, but doesn't do anything
15742   // https://github.com/videojs/video.js/issues/3180
15743   if (browser.IS_ANDROID && browser.IS_CHROME) {
15744     return false;
15745   }
15746   // IE will error if Windows Media Player not installed #3315
15747   try {
15748     var playbackRate = Html5.TEST_VID.playbackRate;
15749
15750     Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
15751     return playbackRate !== Html5.TEST_VID.playbackRate;
15752   } catch (e) {
15753     return false;
15754   }
15755 };
15756
15757 /**
15758  * Check to see if native `TextTrack`s are supported by this browser/device.
15759  *
15760  * @return {boolean}
15761  *         - True if native `TextTrack`s are supported.
15762  *         - False otherwise
15763  */
15764 Html5.supportsNativeTextTracks = function () {
15765   return browser.IS_ANY_SAFARI;
15766 };
15767
15768 /**
15769  * Check to see if native `VideoTrack`s are supported by this browser/device
15770  *
15771  * @return {boolean}
15772  *        - True if native `VideoTrack`s are supported.
15773  *        - False otherwise
15774  */
15775 Html5.supportsNativeVideoTracks = function () {
15776   return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
15777 };
15778
15779 /**
15780  * Check to see if native `AudioTrack`s are supported by this browser/device
15781  *
15782  * @return {boolean}
15783  *        - True if native `AudioTrack`s are supported.
15784  *        - False otherwise
15785  */
15786 Html5.supportsNativeAudioTracks = function () {
15787   return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
15788 };
15789
15790 /**
15791  * An array of events available on the Html5 tech.
15792  *
15793  * @private
15794  * @type {Array}
15795  */
15796 Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
15797
15798 /**
15799  * Boolean indicating whether the `Tech` supports volume control.
15800  *
15801  * @type {boolean}
15802  * @default {@link Html5.canControlVolume}
15803  */
15804 Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
15805
15806 /**
15807  * Boolean indicating whether the `Tech` supports changing the speed at which the media
15808  * plays. Examples:
15809  *   - Set player to play 2x (twice) as fast
15810  *   - Set player to play 0.5x (half) as fast
15811  *
15812  * @type {boolean}
15813  * @default {@link Html5.canControlPlaybackRate}
15814  */
15815 Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
15816
15817 /**
15818  * Boolean indicating whether the `HTML5` tech currently supports the media element
15819  * moving in the DOM. iOS breaks if you move the media element, so this is set this to
15820  * false there. Everywhere else this should be true.
15821  *
15822  * @type {boolean}
15823  * @default
15824  */
15825 Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
15826
15827 // TODO: Previous comment: No longer appears to be used. Can probably be removed.
15828 //       Is this true?
15829 /**
15830  * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
15831  * when going into fullscreen.
15832  *
15833  * @type {boolean}
15834  * @default
15835  */
15836 Html5.prototype.featuresFullscreenResize = true;
15837
15838 /**
15839  * Boolean indicating whether the `HTML5` tech currently supports the progress event.
15840  * If this is false, manual `progress` events will be triggred instead.
15841  *
15842  * @type {boolean}
15843  * @default
15844  */
15845 Html5.prototype.featuresProgressEvents = true;
15846
15847 /**
15848  * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
15849  * If this is false, manual `timeupdate` events will be triggred instead.
15850  *
15851  * @default
15852  */
15853 Html5.prototype.featuresTimeupdateEvents = true;
15854
15855 /**
15856  * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
15857  *
15858  * @type {boolean}
15859  * @default {@link Html5.supportsNativeTextTracks}
15860  */
15861 Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
15862
15863 /**
15864  * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
15865  *
15866  * @type {boolean}
15867  * @default {@link Html5.supportsNativeVideoTracks}
15868  */
15869 Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
15870
15871 /**
15872  * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
15873  *
15874  * @type {boolean}
15875  * @default {@link Html5.supportsNativeAudioTracks}
15876  */
15877 Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
15878
15879 // HTML5 Feature detection and Device Fixes --------------------------------- //
15880 var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
15881 var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15882 var mp4RE = /^video\/mp4/i;
15883
15884 Html5.patchCanPlayType = function () {
15885
15886   // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15887   if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
15888     Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15889       if (type && mpegurlRE.test(type)) {
15890         return 'maybe';
15891       }
15892       return canPlayType.call(this, type);
15893     };
15894
15895     // Override Android 2.2 and less canPlayType method which is broken
15896   } else if (browser.IS_OLD_ANDROID) {
15897     Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15898       if (type && mp4RE.test(type)) {
15899         return 'maybe';
15900       }
15901       return canPlayType.call(this, type);
15902     };
15903   }
15904 };
15905
15906 Html5.unpatchCanPlayType = function () {
15907   var r = Html5.TEST_VID.constructor.prototype.canPlayType;
15908
15909   Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
15910   return r;
15911 };
15912
15913 // by default, patch the media element
15914 Html5.patchCanPlayType();
15915
15916 Html5.disposeMediaElement = function (el) {
15917   if (!el) {
15918     return;
15919   }
15920
15921   if (el.parentNode) {
15922     el.parentNode.removeChild(el);
15923   }
15924
15925   // remove any child track or source nodes to prevent their loading
15926   while (el.hasChildNodes()) {
15927     el.removeChild(el.firstChild);
15928   }
15929
15930   // remove any src reference. not setting `src=''` because that causes a warning
15931   // in firefox
15932   el.removeAttribute('src');
15933
15934   // force the media element to update its loading state by calling load()
15935   // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
15936   if (typeof el.load === 'function') {
15937     // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15938     (function () {
15939       try {
15940         el.load();
15941       } catch (e) {
15942         // not supported
15943       }
15944     })();
15945   }
15946 };
15947
15948 Html5.resetMediaElement = function (el) {
15949   if (!el) {
15950     return;
15951   }
15952
15953   var sources = el.querySelectorAll('source');
15954   var i = sources.length;
15955
15956   while (i--) {
15957     el.removeChild(sources[i]);
15958   }
15959
15960   // remove any src reference.
15961   // not setting `src=''` because that throws an error
15962   el.removeAttribute('src');
15963
15964   if (typeof el.load === 'function') {
15965     // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15966     (function () {
15967       try {
15968         el.load();
15969       } catch (e) {
15970         // satisfy linter
15971       }
15972     })();
15973   }
15974 };
15975
15976 /* Native HTML5 element property wrapping ----------------------------------- */
15977 // Wrap native properties with a getter
15978 [
15979 /**
15980  * Get the value of `paused` from the media element. `paused` indicates whether the media element
15981  * is currently paused or not.
15982  *
15983  * @method Html5#paused
15984  * @return {boolean}
15985  *         The value of `paused` from the media element.
15986  *
15987  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
15988  */
15989 'paused',
15990
15991 /**
15992  * Get the value of `currentTime` from the media element. `currentTime` indicates
15993  * the current second that the media is at in playback.
15994  *
15995  * @method Html5#currentTime
15996  * @return {number}
15997  *         The value of `currentTime` from the media element.
15998  *
15999  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
16000  */
16001 'currentTime',
16002
16003 /**
16004  * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
16005  * object that represents the parts of the media that are already downloaded and
16006  * available for playback.
16007  *
16008  * @method Html5#buffered
16009  * @return {TimeRange}
16010  *         The value of `buffered` from the media element.
16011  *
16012  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
16013  */
16014 'buffered',
16015
16016 /**
16017  * Get the value of `volume` from the media element. `volume` indicates
16018  * the current playback volume of audio for a media. `volume` will be a value from 0
16019  * (silent) to 1 (loudest and default).
16020  *
16021  * @method Html5#volume
16022  * @return {number}
16023  *         The value of `volume` from the media element. Value will be between 0-1.
16024  *
16025  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16026  */
16027 'volume',
16028
16029 /**
16030  * Get the value of `muted` from the media element. `muted` indicates
16031  * that the volume for the media should be set to silent. This does not actually change
16032  * the `volume` attribute.
16033  *
16034  * @method Html5#muted
16035  * @return {boolean}
16036  *         - True if the value of `volume` should be ignored and the audio set to silent.
16037  *         - False if the value of `volume` should be used.
16038  *
16039  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16040  */
16041 'muted',
16042
16043 /**
16044  * Get the value of `poster` from the media element. `poster` indicates
16045  * that the url of an image file that can/will be shown when no media data is available.
16046  *
16047  * @method Html5#poster
16048  * @return {string}
16049  *         The value of `poster` from the media element. Value will be a url to an
16050  *         image.
16051  *
16052  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
16053  */
16054 'poster',
16055
16056 /**
16057  * Get the value of `preload` from the media element. `preload` indicates
16058  * what should download before the media is interacted with. It can have the following
16059  * values:
16060  * - none: nothing should be downloaded
16061  * - metadata: poster and the first few frames of the media may be downloaded to get
16062  *   media dimensions and other metadata
16063  * - auto: allow the media and metadata for the media to be downloaded before
16064  *    interaction
16065  *
16066  * @method Html5#preload
16067  * @return {string}
16068  *         The value of `preload` from the media element. Will be 'none', 'metadata',
16069  *         or 'auto'.
16070  *
16071  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16072  */
16073 'preload',
16074
16075 /**
16076  * Get the value of `autoplay` from the media element. `autoplay` indicates
16077  * that the media should start to play as soon as the page is ready.
16078  *
16079  * @method Html5#autoplay
16080  * @return {boolean}
16081  *         - The value of `autoplay` from the media element.
16082  *         - True indicates that the media should start as soon as the page loads.
16083  *         - False indicates that the media should not start as soon as the page loads.
16084  *
16085  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16086  */
16087 'autoplay',
16088
16089 /**
16090  * Get the value of `controls` from the media element. `controls` indicates
16091  * whether the native media controls should be shown or hidden.
16092  *
16093  * @method Html5#controls
16094  * @return {boolean}
16095  *         - The value of `controls` from the media element.
16096  *         - True indicates that native controls should be showing.
16097  *         - False indicates that native controls should be hidden.
16098  *
16099  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
16100  */
16101 'controls',
16102
16103 /**
16104  * Get the value of `loop` from the media element. `loop` indicates
16105  * that the media should return to the start of the media and continue playing once
16106  * it reaches the end.
16107  *
16108  * @method Html5#loop
16109  * @return {boolean}
16110  *         - The value of `loop` from the media element.
16111  *         - True indicates that playback should seek back to start once
16112  *           the end of a media is reached.
16113  *         - False indicates that playback should not loop back to the start when the
16114  *           end of the media is reached.
16115  *
16116  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16117  */
16118 'loop',
16119
16120 /**
16121  * Get the value of the `error` from the media element. `error` indicates any
16122  * MediaError that may have occured during playback. If error returns null there is no
16123  * current error.
16124  *
16125  * @method Html5#error
16126  * @return {MediaError|null}
16127  *         The value of `error` from the media element. Will be `MediaError` if there
16128  *         is a current error and null otherwise.
16129  *
16130  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
16131  */
16132 'error',
16133
16134 /**
16135  * Get the value of `seeking` from the media element. `seeking` indicates whether the
16136  * media is currently seeking to a new position or not.
16137  *
16138  * @method Html5#seeking
16139  * @return {boolean}
16140  *         - The value of `seeking` from the media element.
16141  *         - True indicates that the media is currently seeking to a new position.
16142  *         - Flase indicates that the media is not seeking to a new position at this time.
16143  *
16144  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
16145  */
16146 'seeking',
16147
16148 /**
16149  * Get the value of `seekable` from the media element. `seekable` returns a
16150  * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
16151  *
16152  * @method Html5#seekable
16153  * @return {TimeRange}
16154  *         The value of `seekable` from the media element. A `TimeRange` object
16155  *         indicating the current ranges of time that can be seeked to.
16156  *
16157  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
16158  */
16159 'seekable',
16160
16161 /**
16162  * Get the value of `ended` from the media element. `ended` indicates whether
16163  * the media has reached the end or not.
16164  *
16165  * @method Html5#ended
16166  * @return {boolean}
16167  *         - The value of `ended` from the media element.
16168  *         - True indicates that the media has ended.
16169  *         - False indicates that the media has not ended.
16170  *
16171  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
16172  */
16173 'ended',
16174
16175 /**
16176  * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
16177  * whether the media should start muted or not. Only changes the default state of the
16178  * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
16179  * current state.
16180  *
16181  * @method Html5#defaultMuted
16182  * @return {boolean}
16183  *         - The value of `defaultMuted` from the media element.
16184  *         - True indicates that the media should start muted.
16185  *         - False indicates that the media should not start muted
16186  *
16187  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
16188  */
16189 'defaultMuted',
16190
16191 /**
16192  * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16193  * the rate at which the media is currently playing back. Examples:
16194  *   - if playbackRate is set to 2, media will play twice as fast.
16195  *   - if playbackRate is set to 0.5, media will play half as fast.
16196  *
16197  * @method Html5#playbackRate
16198  * @return {number}
16199  *         The value of `playbackRate` from the media element. A number indicating
16200  *         the current playback speed of the media, where 1 is normal speed.
16201  *
16202  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16203  */
16204 'playbackRate',
16205
16206 /**
16207  * Get the value of `played` from the media element. `played` returns a `TimeRange`
16208  * object representing points in the media timeline that have been played.
16209  *
16210  * @method Html5#played
16211  * @return {TimeRange}
16212  *         The value of `played` from the media element. A `TimeRange` object indicating
16213  *         the ranges of time that have been played.
16214  *
16215  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
16216  */
16217 'played',
16218
16219 /**
16220  * Get the value of `networkState` from the media element. `networkState` indicates
16221  * the current network state. It returns an enumeration from the following list:
16222  * - 0: NETWORK_EMPTY
16223  * - 1: NEWORK_IDLE
16224  * - 2: NETWORK_LOADING
16225  * - 3: NETWORK_NO_SOURCE
16226  *
16227  * @method Html5#networkState
16228  * @return {number}
16229  *         The value of `networkState` from the media element. This will be a number
16230  *         from the list in the description.
16231  *
16232  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
16233  */
16234 'networkState',
16235
16236 /**
16237  * Get the value of `readyState` from the media element. `readyState` indicates
16238  * the current state of the media element. It returns an enumeration from the
16239  * following list:
16240  * - 0: HAVE_NOTHING
16241  * - 1: HAVE_METADATA
16242  * - 2: HAVE_CURRENT_DATA
16243  * - 3: HAVE_FUTURE_DATA
16244  * - 4: HAVE_ENOUGH_DATA
16245  *
16246  * @method Html5#readyState
16247  * @return {number}
16248  *         The value of `readyState` from the media element. This will be a number
16249  *         from the list in the description.
16250  *
16251  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
16252  */
16253 'readyState',
16254
16255 /**
16256  * Get the value of `videoWidth` from the video element. `videoWidth` indicates
16257  * the current width of the video in css pixels.
16258  *
16259  * @method Html5#videoWidth
16260  * @return {number}
16261  *         The value of `videoWidth` from the video element. This will be a number
16262  *         in css pixels.
16263  *
16264  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16265  */
16266 'videoWidth',
16267
16268 /**
16269  * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
16270  * the current height of the video in css pixels.
16271  *
16272  * @method Html5#videoHeight
16273  * @return {number}
16274  *         The value of `videoHeight` from the video element. This will be a number
16275  *         in css pixels.
16276  *
16277  * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16278  */
16279 'videoHeight'].forEach(function (prop) {
16280   Html5.prototype[prop] = function () {
16281     return this.el_[prop];
16282   };
16283 });
16284
16285 // Wrap native properties with a setter in this format:
16286 // set + toTitleCase(name)
16287 [
16288 /**
16289  * Set the value of `volume` on the media element. `volume` indicates the current
16290  * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
16291  * so on.
16292  *
16293  * @method Html5#setVolume
16294  * @param {number} percentAsDecimal
16295  *        The volume percent as a decimal. Valid range is from 0-1.
16296  *
16297  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16298  */
16299 'volume',
16300
16301 /**
16302  * Set the value of `muted` on the media element. `muted` indicates the current
16303  * audio level should be silent.
16304  *
16305  * @method Html5#setMuted
16306  * @param {boolean} muted
16307  *        - True if the audio should be set to silent
16308  *        - False otherwise
16309  *
16310  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16311  */
16312 'muted',
16313
16314 /**
16315  * Set the value of `src` on the media element. `src` indicates the current
16316  * {@link Tech~SourceObject} for the media.
16317  *
16318  * @method Html5#setSrc
16319  * @param {Tech~SourceObject} src
16320  *        The source object to set as the current source.
16321  *
16322  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
16323  */
16324 'src',
16325
16326 /**
16327  * Set the value of `poster` on the media element. `poster` is the url to
16328  * an image file that can/will be shown when no media data is available.
16329  *
16330  * @method Html5#setPoster
16331  * @param {string} poster
16332  *        The url to an image that should be used as the `poster` for the media
16333  *        element.
16334  *
16335  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
16336  */
16337 'poster',
16338
16339 /**
16340  * Set the value of `preload` on the media element. `preload` indicates
16341  * what should download before the media is interacted with. It can have the following
16342  * values:
16343  * - none: nothing should be downloaded
16344  * - metadata: poster and the first few frames of the media may be downloaded to get
16345  *   media dimensions and other metadata
16346  * - auto: allow the media and metadata for the media to be downloaded before
16347  *    interaction
16348  *
16349  * @method Html5#setPreload
16350  * @param {string} preload
16351  *         The value of `preload` to set on the media element. Must be 'none', 'metadata',
16352  *         or 'auto'.
16353  *
16354  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16355  */
16356 'preload',
16357
16358 /**
16359  * Set the value of `autoplay` on the media element. `autoplay` indicates
16360  * that the media should start to play as soon as the page is ready.
16361  *
16362  * @method Html5#setAutoplay
16363  * @param {boolean} autoplay
16364  *         - True indicates that the media should start as soon as the page loads.
16365  *         - False indicates that the media should not start as soon as the page loads.
16366  *
16367  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16368  */
16369 'autoplay',
16370
16371 /**
16372  * Set the value of `loop` on the media element. `loop` indicates
16373  * that the media should return to the start of the media and continue playing once
16374  * it reaches the end.
16375  *
16376  * @method Html5#setLoop
16377  * @param {boolean} loop
16378  *         - True indicates that playback should seek back to start once
16379  *           the end of a media is reached.
16380  *         - False indicates that playback should not loop back to the start when the
16381  *           end of the media is reached.
16382  *
16383  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16384  */
16385 'loop',
16386
16387 /**
16388  * Set the value of `playbackRate` on the media element. `playbackRate` indicates
16389  * the rate at which the media should play back. Examples:
16390  *   - if playbackRate is set to 2, media will play twice as fast.
16391  *   - if playbackRate is set to 0.5, media will play half as fast.
16392  *
16393  * @method Html5#setPlaybackRate
16394  * @return {number}
16395  *         The value of `playbackRate` from the media element. A number indicating
16396  *         the current playback speed of the media, where 1 is normal speed.
16397  *
16398  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16399  */
16400 'playbackRate'].forEach(function (prop) {
16401   Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
16402     this.el_[prop] = v;
16403   };
16404 });
16405
16406 // wrap native functions with a function
16407 [
16408 /**
16409  * A wrapper around the media elements `pause` function. This will call the `HTML5`
16410  * media elements `pause` function.
16411  *
16412  * @method Html5#pause
16413  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
16414  */
16415 'pause',
16416
16417 /**
16418  * A wrapper around the media elements `load` function. This will call the `HTML5`s
16419  * media element `load` function.
16420  *
16421  * @method Html5#load
16422  * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
16423  */
16424 'load'].forEach(function (prop) {
16425   Html5.prototype[prop] = function () {
16426     return this.el_[prop]();
16427   };
16428 });
16429
16430 _tech2['default'].withSourceHandlers(Html5);
16431
16432 /**
16433  * Native source handler for Html5, simply passes the source to the media element.
16434  *
16435  * @proprety {Tech~SourceObject} source
16436  *        The source object
16437  *
16438  * @proprety {Html5} tech
16439  *        The instance of the HTML5 tech.
16440  */
16441 Html5.nativeSourceHandler = {};
16442
16443 /**
16444  * Check if the media element can play the given mime type.
16445  *
16446  * @param {string} type
16447  *        The mimetype to check
16448  *
16449  * @return {string}
16450  *         'probably', 'maybe', or '' (empty string)
16451  */
16452 Html5.nativeSourceHandler.canPlayType = function (type) {
16453   // IE9 on Windows 7 without MediaPlayer throws an error here
16454   // https://github.com/videojs/video.js/issues/519
16455   try {
16456     return Html5.TEST_VID.canPlayType(type);
16457   } catch (e) {
16458     return '';
16459   }
16460 };
16461
16462 /**
16463  * Check if the media element can handle a source natively.
16464  *
16465  * @param {Tech~SourceObject} source
16466  *         The source object
16467  *
16468  * @param {Object} [options]
16469  *         Options to be passed to the tech.
16470  *
16471  * @return {string}
16472  *         'probably', 'maybe', or '' (empty string).
16473  */
16474 Html5.nativeSourceHandler.canHandleSource = function (source, options) {
16475
16476   // If a type was provided we should rely on that
16477   if (source.type) {
16478     return Html5.nativeSourceHandler.canPlayType(source.type);
16479
16480     // If no type, fall back to checking 'video/[EXTENSION]'
16481   } else if (source.src) {
16482     var ext = Url.getFileExtension(source.src);
16483
16484     return Html5.nativeSourceHandler.canPlayType('video/' + ext);
16485   }
16486
16487   return '';
16488 };
16489
16490 /**
16491  * Pass the source to the native media element.
16492  *
16493  * @param {Tech~SourceObject} source
16494  *        The source object
16495  *
16496  * @param {Html5} tech
16497  *        The instance of the Html5 tech
16498  *
16499  * @param {Object} [options]
16500  *        The options to pass to the source
16501  */
16502 Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
16503   tech.setSrc(source.src);
16504 };
16505
16506 /**
16507  * A noop for the native dispose function, as cleanup is not needed.
16508  */
16509 Html5.nativeSourceHandler.dispose = function () {};
16510
16511 // Register the native source handler
16512 Html5.registerSourceHandler(Html5.nativeSourceHandler);
16513
16514 _component2['default'].registerComponent('Html5', Html5);
16515 _tech2['default'].registerTech('Html5', Html5);
16516 exports['default'] = Html5;
16517
16518 },{"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){
16519 'use strict';
16520
16521 exports.__esModule = true;
16522
16523 var _component = _dereq_(5);
16524
16525 var _component2 = _interopRequireDefault(_component);
16526
16527 var _tech = _dereq_(62);
16528
16529 var _tech2 = _interopRequireDefault(_tech);
16530
16531 var _toTitleCase = _dereq_(91);
16532
16533 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
16534
16535 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16536
16537 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16538
16539 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; }
16540
16541 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; } /**
16542                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file loader.js
16543                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
16544
16545
16546 /**
16547  * The `MediaLoader` is the `Component` that decides which playback technology to load
16548  * when a player is initialized.
16549  *
16550  * @extends Component
16551  */
16552 var MediaLoader = function (_Component) {
16553   _inherits(MediaLoader, _Component);
16554
16555   /**
16556    * Create an instance of this class.
16557    *
16558    * @param {Player} player
16559    *        The `Player` that this class should attach to.
16560    *
16561    * @param {Object} [options]
16562    *        The key/value stroe of player options.
16563    *
16564    * @param {Component~ReadyCallback} [ready]
16565    *        The function that is run when this component is ready.
16566    */
16567   function MediaLoader(player, options, ready) {
16568     _classCallCheck(this, MediaLoader);
16569
16570     // If there are no sources when the player is initialized,
16571     // load the first supported playback technology.
16572
16573     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
16574
16575     if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
16576       for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
16577         var techName = (0, _toTitleCase2['default'])(j[i]);
16578         var tech = _tech2['default'].getTech(techName);
16579
16580         // Support old behavior of techs being registered as components.
16581         // Remove once that deprecated behavior is removed.
16582         if (!techName) {
16583           tech = _component2['default'].getComponent(techName);
16584         }
16585
16586         // Check if the browser supports this technology
16587         if (tech && tech.isSupported()) {
16588           player.loadTech_(techName);
16589           break;
16590         }
16591       }
16592     } else {
16593       // Loop through playback technologies (HTML5, Flash) and check for support.
16594       // Then load the best source.
16595       // A few assumptions here:
16596       //   All playback technologies respect preload false.
16597       player.src(options.playerOptions.sources);
16598     }
16599     return _this;
16600   }
16601
16602   return MediaLoader;
16603 }(_component2['default']);
16604
16605 _component2['default'].registerComponent('MediaLoader', MediaLoader);
16606 exports['default'] = MediaLoader;
16607
16608 },{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){
16609 'use strict';
16610
16611 exports.__esModule = true;
16612
16613 var _component = _dereq_(5);
16614
16615 var _component2 = _interopRequireDefault(_component);
16616
16617 var _htmlTrackElement = _dereq_(66);
16618
16619 var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
16620
16621 var _htmlTrackElementList = _dereq_(65);
16622
16623 var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
16624
16625 var _mergeOptions = _dereq_(87);
16626
16627 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
16628
16629 var _textTrack = _dereq_(72);
16630
16631 var _textTrack2 = _interopRequireDefault(_textTrack);
16632
16633 var _textTrackList = _dereq_(70);
16634
16635 var _textTrackList2 = _interopRequireDefault(_textTrackList);
16636
16637 var _videoTrackList = _dereq_(76);
16638
16639 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
16640
16641 var _audioTrackList = _dereq_(63);
16642
16643 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
16644
16645 var _fn = _dereq_(83);
16646
16647 var Fn = _interopRequireWildcard(_fn);
16648
16649 var _log = _dereq_(86);
16650
16651 var _log2 = _interopRequireDefault(_log);
16652
16653 var _timeRanges = _dereq_(90);
16654
16655 var _buffer = _dereq_(79);
16656
16657 var _mediaError = _dereq_(46);
16658
16659 var _mediaError2 = _interopRequireDefault(_mediaError);
16660
16661 var _window = _dereq_(95);
16662
16663 var _window2 = _interopRequireDefault(_window);
16664
16665 var _document = _dereq_(94);
16666
16667 var _document2 = _interopRequireDefault(_document);
16668
16669 var _obj = _dereq_(88);
16670
16671 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; } }
16672
16673 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16674
16675 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16676
16677 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; }
16678
16679 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; } /**
16680                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file tech.js
16681                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
16682
16683 /**
16684  * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
16685  * that just contains the src url alone.
16686  * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
16687    * `var SourceString = 'http://example.com/some-video.mp4';`
16688  *
16689  * @typedef {Object|string} Tech~SourceObject
16690  *
16691  * @property {string} src
16692  *           The url to the source
16693  *
16694  * @property {string} type
16695  *           The mime type of the source
16696  */
16697
16698 /**
16699  * A function used by {@link Tech} to create a new {@link TextTrack}.
16700  *
16701  * @param {Tech} self
16702  *        An instance of the Tech class.
16703  *
16704  * @param {string} kind
16705  *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
16706  *
16707  * @param {string} [label]
16708  *        Label to identify the text track
16709  *
16710  * @param {string} [language]
16711  *        Two letter language abbreviation
16712  *
16713  * @param {Object} [options={}]
16714  *        An object with additional text track options
16715  *
16716  * @return {TextTrack}
16717  *          The text track that was created.
16718  */
16719 function createTrackHelper(self, kind, label, language) {
16720   var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
16721
16722   var tracks = self.textTracks();
16723
16724   options.kind = kind;
16725
16726   if (label) {
16727     options.label = label;
16728   }
16729   if (language) {
16730     options.language = language;
16731   }
16732   options.tech = self;
16733
16734   var track = new _textTrack2['default'](options);
16735
16736   tracks.addTrack_(track);
16737
16738   return track;
16739 }
16740
16741 /**
16742  * This is the base class for media playback technology controllers, such as
16743  * {@link Flash} and {@link HTML5}
16744  *
16745  * @extends Component
16746  */
16747
16748 var Tech = function (_Component) {
16749   _inherits(Tech, _Component);
16750
16751   /**
16752    * Create an instance of this Tech.
16753    *
16754    * @param {Object} [options]
16755    *        The key/value store of player options.
16756    *
16757    * @param {Component~ReadyCallback} ready
16758    *        Callback function to call when the `HTML5` Tech is ready.
16759    */
16760   function Tech() {
16761     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
16762     var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
16763
16764     _classCallCheck(this, Tech);
16765
16766     // we don't want the tech to report user activity automatically.
16767     // This is done manually in addControlsListeners
16768     options.reportTouchActivity = false;
16769
16770     // keep track of whether the current source has played at all to
16771     // implement a very limited played()
16772     var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
16773
16774     _this.hasStarted_ = false;
16775     _this.on('playing', function () {
16776       this.hasStarted_ = true;
16777     });
16778     _this.on('loadstart', function () {
16779       this.hasStarted_ = false;
16780     });
16781
16782     _this.textTracks_ = options.textTracks;
16783     _this.videoTracks_ = options.videoTracks;
16784     _this.audioTracks_ = options.audioTracks;
16785
16786     // Manually track progress in cases where the browser/flash player doesn't report it.
16787     if (!_this.featuresProgressEvents) {
16788       _this.manualProgressOn();
16789     }
16790
16791     // Manually track timeupdates in cases where the browser/flash player doesn't report it.
16792     if (!_this.featuresTimeupdateEvents) {
16793       _this.manualTimeUpdatesOn();
16794     }
16795
16796     ['Text', 'Audio', 'Video'].forEach(function (track) {
16797       if (options['native' + track + 'Tracks'] === false) {
16798         _this['featuresNative' + track + 'Tracks'] = false;
16799       }
16800     });
16801
16802     if (options.nativeCaptions === false) {
16803       _this.featuresNativeTextTracks = false;
16804     }
16805
16806     if (!_this.featuresNativeTextTracks) {
16807       _this.emulateTextTracks();
16808     }
16809
16810     _this.autoRemoteTextTracks_ = new _textTrackList2['default']();
16811
16812     _this.initTextTrackListeners();
16813     _this.initTrackListeners();
16814
16815     // Turn on component tap events only if not using native controls
16816     if (!options.nativeControlsForTouch) {
16817       _this.emitTapEvents();
16818     }
16819
16820     if (_this.constructor) {
16821       _this.name_ = _this.constructor.name || 'Unknown Tech';
16822     }
16823     return _this;
16824   }
16825
16826   /* Fallbacks for unsupported event types
16827   ================================================================================ */
16828
16829   /**
16830    * Polyfill the `progress` event for browsers that don't support it natively.
16831    *
16832    * @see {@link Tech#trackProgress}
16833    */
16834
16835
16836   Tech.prototype.manualProgressOn = function manualProgressOn() {
16837     this.on('durationchange', this.onDurationChange);
16838
16839     this.manualProgress = true;
16840
16841     // Trigger progress watching when a source begins loading
16842     this.one('ready', this.trackProgress);
16843   };
16844
16845   /**
16846    * Turn off the polyfill for `progress` events that was created in
16847    * {@link Tech#manualProgressOn}
16848    */
16849
16850
16851   Tech.prototype.manualProgressOff = function manualProgressOff() {
16852     this.manualProgress = false;
16853     this.stopTrackingProgress();
16854
16855     this.off('durationchange', this.onDurationChange);
16856   };
16857
16858   /**
16859    * This is used to trigger a `progress` event when the buffered percent changes. It
16860    * sets an interval function that will be called every 500 milliseconds to check if the
16861    * buffer end percent has changed.
16862    *
16863    * > This function is called by {@link Tech#manualProgressOn}
16864    *
16865    * @param {EventTarget~Event} event
16866    *        The `ready` event that caused this to run.
16867    *
16868    * @listens Tech#ready
16869    * @fires Tech#progress
16870    */
16871
16872
16873   Tech.prototype.trackProgress = function trackProgress(event) {
16874     this.stopTrackingProgress();
16875     this.progressInterval = this.setInterval(Fn.bind(this, function () {
16876       // Don't trigger unless buffered amount is greater than last time
16877
16878       var numBufferedPercent = this.bufferedPercent();
16879
16880       if (this.bufferedPercent_ !== numBufferedPercent) {
16881         /**
16882          * See {@link Player#progress}
16883          *
16884          * @event Tech#progress
16885          * @type {EventTarget~Event}
16886          */
16887         this.trigger('progress');
16888       }
16889
16890       this.bufferedPercent_ = numBufferedPercent;
16891
16892       if (numBufferedPercent === 1) {
16893         this.stopTrackingProgress();
16894       }
16895     }), 500);
16896   };
16897
16898   /**
16899    * Update our internal duration on a `durationchange` event by calling
16900    * {@link Tech#duration}.
16901    *
16902    * @param {EventTarget~Event} event
16903    *        The `durationchange` event that caused this to run.
16904    *
16905    * @listens Tech#durationchange
16906    */
16907
16908
16909   Tech.prototype.onDurationChange = function onDurationChange(event) {
16910     this.duration_ = this.duration();
16911   };
16912
16913   /**
16914    * Get and create a `TimeRange` object for buffering.
16915    *
16916    * @return {TimeRange}
16917    *         The time range object that was created.
16918    */
16919
16920
16921   Tech.prototype.buffered = function buffered() {
16922     return (0, _timeRanges.createTimeRange)(0, 0);
16923   };
16924
16925   /**
16926    * Get the percentage of the current video that is currently buffered.
16927    *
16928    * @return {number}
16929    *         A number from 0 to 1 that represents the decimal percentage of the
16930    *         video that is buffered.
16931    *
16932    */
16933
16934
16935   Tech.prototype.bufferedPercent = function bufferedPercent() {
16936     return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
16937   };
16938
16939   /**
16940    * Turn off the polyfill for `progress` events that was created in
16941    * {@link Tech#manualProgressOn}
16942    * Stop manually tracking progress events by clearing the interval that was set in
16943    * {@link Tech#trackProgress}.
16944    */
16945
16946
16947   Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
16948     this.clearInterval(this.progressInterval);
16949   };
16950
16951   /**
16952    * Polyfill the `timeupdate` event for browsers that don't support it.
16953    *
16954    * @see {@link Tech#trackCurrentTime}
16955    */
16956
16957
16958   Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
16959     this.manualTimeUpdates = true;
16960
16961     this.on('play', this.trackCurrentTime);
16962     this.on('pause', this.stopTrackingCurrentTime);
16963   };
16964
16965   /**
16966    * Turn off the polyfill for `timeupdate` events that was created in
16967    * {@link Tech#manualTimeUpdatesOn}
16968    */
16969
16970
16971   Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
16972     this.manualTimeUpdates = false;
16973     this.stopTrackingCurrentTime();
16974     this.off('play', this.trackCurrentTime);
16975     this.off('pause', this.stopTrackingCurrentTime);
16976   };
16977
16978   /**
16979    * Sets up an interval function to track current time and trigger `timeupdate` every
16980    * 250 milliseconds.
16981    *
16982    * @listens Tech#play
16983    * @triggers Tech#timeupdate
16984    */
16985
16986
16987   Tech.prototype.trackCurrentTime = function trackCurrentTime() {
16988     if (this.currentTimeInterval) {
16989       this.stopTrackingCurrentTime();
16990     }
16991     this.currentTimeInterval = this.setInterval(function () {
16992       /**
16993        * Triggered at an interval of 250ms to indicated that time is passing in the video.
16994        *
16995        * @event Tech#timeupdate
16996        * @type {EventTarget~Event}
16997        */
16998       this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
16999
17000       // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
17001     }, 250);
17002   };
17003
17004   /**
17005    * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
17006    * `timeupdate` event is no longer triggered.
17007    *
17008    * @listens {Tech#pause}
17009    */
17010
17011
17012   Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
17013     this.clearInterval(this.currentTimeInterval);
17014
17015     // #1002 - if the video ends right before the next timeupdate would happen,
17016     // the progress bar won't make it all the way to the end
17017     this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17018   };
17019
17020   /**
17021    * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
17022    * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
17023    *
17024    * @fires Component#dispose
17025    */
17026
17027
17028   Tech.prototype.dispose = function dispose() {
17029
17030     // clear out all tracks because we can't reuse them between techs
17031     this.clearTracks(['audio', 'video', 'text']);
17032
17033     // Turn off any manual progress or timeupdate tracking
17034     if (this.manualProgress) {
17035       this.manualProgressOff();
17036     }
17037
17038     if (this.manualTimeUpdates) {
17039       this.manualTimeUpdatesOff();
17040     }
17041
17042     _Component.prototype.dispose.call(this);
17043   };
17044
17045   /**
17046    * Clear out a single `TrackList` or an array of `TrackLists` given their names.
17047    *
17048    * > Note: Techs without source handlers should call this between sources for `video`
17049    *         & `audio` tracks. You don't want to use them between tracks!
17050    *
17051    * @param {string[]|string} types
17052    *        TrackList names to clear, valid names are `video`, `audio`, and
17053    *        `text`.
17054    */
17055
17056
17057   Tech.prototype.clearTracks = function clearTracks(types) {
17058     var _this2 = this;
17059
17060     types = [].concat(types);
17061     // clear out all tracks because we can't reuse them between techs
17062     types.forEach(function (type) {
17063       var list = _this2[type + 'Tracks']() || [];
17064       var i = list.length;
17065
17066       while (i--) {
17067         var track = list[i];
17068
17069         if (type === 'text') {
17070           _this2.removeRemoteTextTrack(track);
17071         }
17072         list.removeTrack_(track);
17073       }
17074     });
17075   };
17076
17077   /**
17078    * Remove any TextTracks added via addRemoteTextTrack that are
17079    * flagged for automatic garbage collection
17080    */
17081
17082
17083   Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
17084     var list = this.autoRemoteTextTracks_ || [];
17085     var i = list.length;
17086
17087     while (i--) {
17088       var track = list[i];
17089
17090       this.removeRemoteTextTrack(track);
17091     }
17092   };
17093
17094   /**
17095    * Reset the tech, which will removes all sources and reset the internal readyState.
17096    *
17097    * @abstract
17098    */
17099
17100
17101   Tech.prototype.reset = function reset() {};
17102
17103   /**
17104    * Get or set an error on the Tech.
17105    *
17106    * @param {MediaError} [err]
17107    *        Error to set on the Tech
17108    *
17109    * @return {MediaError|null}
17110    *         The current error object on the tech, or null if there isn't one.
17111    */
17112
17113
17114   Tech.prototype.error = function error(err) {
17115     if (err !== undefined) {
17116       this.error_ = new _mediaError2['default'](err);
17117       this.trigger('error');
17118     }
17119     return this.error_;
17120   };
17121
17122   /**
17123    * Returns the `TimeRange`s that have been played through for the current source.
17124    *
17125    * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
17126    *         It only checks wether the source has played at all or not.
17127    *
17128    * @return {TimeRange}
17129    *         - A single time range if this video has played
17130    *         - An empty set of ranges if not.
17131    */
17132
17133
17134   Tech.prototype.played = function played() {
17135     if (this.hasStarted_) {
17136       return (0, _timeRanges.createTimeRange)(0, 0);
17137     }
17138     return (0, _timeRanges.createTimeRange)();
17139   };
17140
17141   /**
17142    * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
17143    * previously called.
17144    *
17145    * @fires Tech#timeupdate
17146    */
17147
17148
17149   Tech.prototype.setCurrentTime = function setCurrentTime() {
17150     // improve the accuracy of manual timeupdates
17151     if (this.manualTimeUpdates) {
17152       /**
17153        * A manual `timeupdate` event.
17154        *
17155        * @event Tech#timeupdate
17156        * @type {EventTarget~Event}
17157        */
17158       this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17159     }
17160   };
17161
17162   /**
17163    * Turn on listeners for {@link TextTrackList} events. This adds
17164    * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
17165    * `removetrack`.
17166    *
17167    * @fires Tech#texttrackchange
17168    */
17169
17170
17171   Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
17172     var textTrackListChanges = Fn.bind(this, function () {
17173       /**
17174        * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
17175        *
17176        * @event Tech#texttrackchange
17177        * @type {EventTarget~Event}
17178        */
17179       this.trigger('texttrackchange');
17180     });
17181
17182     var tracks = this.textTracks();
17183
17184     if (!tracks) {
17185       return;
17186     }
17187
17188     tracks.addEventListener('removetrack', textTrackListChanges);
17189     tracks.addEventListener('addtrack', textTrackListChanges);
17190
17191     this.on('dispose', Fn.bind(this, function () {
17192       tracks.removeEventListener('removetrack', textTrackListChanges);
17193       tracks.removeEventListener('addtrack', textTrackListChanges);
17194     }));
17195   };
17196
17197   /**
17198    * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
17199    * This adds {@link EventTarget~EventListeners} for `addtrack`, and  `removetrack`.
17200    *
17201    * @fires Tech#audiotrackchange
17202    * @fires Tech#videotrackchange
17203    */
17204
17205
17206   Tech.prototype.initTrackListeners = function initTrackListeners() {
17207     var _this3 = this;
17208
17209     var trackTypes = ['video', 'audio'];
17210
17211     trackTypes.forEach(function (type) {
17212       /**
17213        * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
17214        *
17215        * @event Tech#audiotrackchange
17216        * @type {EventTarget~Event}
17217        */
17218
17219       /**
17220        * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
17221        *
17222        * @event Tech#videotrackchange
17223        * @type {EventTarget~Event}
17224        */
17225       var trackListChanges = function trackListChanges() {
17226         _this3.trigger(type + 'trackchange');
17227       };
17228
17229       var tracks = _this3[type + 'Tracks']();
17230
17231       tracks.addEventListener('removetrack', trackListChanges);
17232       tracks.addEventListener('addtrack', trackListChanges);
17233
17234       _this3.on('dispose', function () {
17235         tracks.removeEventListener('removetrack', trackListChanges);
17236         tracks.removeEventListener('addtrack', trackListChanges);
17237       });
17238     });
17239   };
17240
17241   /**
17242    * Emulate TextTracks using vtt.js if necessary
17243    *
17244    * @fires Tech#vttjsloaded
17245    * @fires Tech#vttjserror
17246    */
17247
17248
17249   Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
17250     var _this4 = this;
17251
17252     if (_window2['default'].WebVTT) {
17253       return;
17254     }
17255
17256     // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
17257     // signals that the Tech is ready at which point Tech.el_ is part of the DOM
17258     // before inserting the WebVTT script
17259     if (_document2['default'].body.contains(this.el())) {
17260       var vtt = _dereq_(105);
17261
17262       // load via require if available and vtt.js script location was not passed in
17263       // as an option. novtt builds will turn the above require call into an empty object
17264       // which will cause this if check to always fail.
17265       if (!this.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) {
17266         this.trigger('vttjsloaded');
17267         return;
17268       }
17269
17270       // load vtt.js via the script location option or the cdn of no location was
17271       // passed in
17272       var script = _document2['default'].createElement('script');
17273
17274       script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.3/vtt.min.js';
17275       script.onload = function () {
17276         /**
17277          * Fired when vtt.js is loaded.
17278          *
17279          * @event Tech#vttjsloaded
17280          * @type {EventTarget~Event}
17281          */
17282         _this4.trigger('vttjsloaded');
17283       };
17284       script.onerror = function () {
17285         /**
17286          * Fired when vtt.js was not loaded due to an error
17287          *
17288          * @event Tech#vttjsloaded
17289          * @type {EventTarget~Event}
17290          */
17291         _this4.trigger('vttjserror');
17292       };
17293       this.on('dispose', function () {
17294         script.onload = null;
17295         script.onerror = null;
17296       });
17297       // but have not loaded yet and we set it to true before the inject so that
17298       // we don't overwrite the injected window.WebVTT if it loads right away
17299       _window2['default'].WebVTT = true;
17300       this.el().parentNode.appendChild(script);
17301     } else {
17302       this.ready(this.addWebVttScript_);
17303     }
17304   };
17305
17306   /**
17307    * Emulate texttracks
17308    *
17309    * @method emulateTextTracks
17310    */
17311
17312
17313   Tech.prototype.emulateTextTracks = function emulateTextTracks() {
17314     var _this5 = this;
17315
17316     var tracks = this.textTracks();
17317
17318     if (!tracks) {
17319       return;
17320     }
17321
17322     var remoteTracks = this.remoteTextTracks();
17323     var handleAddTrack = function handleAddTrack(e) {
17324       return tracks.addTrack_(e.track);
17325     };
17326     var handleRemoveTrack = function handleRemoveTrack(e) {
17327       return tracks.removeTrack_(e.track);
17328     };
17329
17330     remoteTracks.on('addtrack', handleAddTrack);
17331     remoteTracks.on('removetrack', handleRemoveTrack);
17332
17333     this.addWebVttScript_();
17334
17335     var updateDisplay = function updateDisplay() {
17336       return _this5.trigger('texttrackchange');
17337     };
17338
17339     var textTracksChanges = function textTracksChanges() {
17340       updateDisplay();
17341
17342       for (var i = 0; i < tracks.length; i++) {
17343         var track = tracks[i];
17344
17345         track.removeEventListener('cuechange', updateDisplay);
17346         if (track.mode === 'showing') {
17347           track.addEventListener('cuechange', updateDisplay);
17348         }
17349       }
17350     };
17351
17352     textTracksChanges();
17353     tracks.addEventListener('change', textTracksChanges);
17354     tracks.addEventListener('addtrack', textTracksChanges);
17355     tracks.addEventListener('removetrack', textTracksChanges);
17356
17357     this.on('dispose', function () {
17358       remoteTracks.off('addtrack', handleAddTrack);
17359       remoteTracks.off('removetrack', handleRemoveTrack);
17360       tracks.removeEventListener('change', textTracksChanges);
17361       tracks.removeEventListener('addtrack', textTracksChanges);
17362       tracks.removeEventListener('removetrack', textTracksChanges);
17363
17364       for (var i = 0; i < tracks.length; i++) {
17365         var track = tracks[i];
17366
17367         track.removeEventListener('cuechange', updateDisplay);
17368       }
17369     });
17370   };
17371
17372   /**
17373    * Get the `Tech`s {@link VideoTrackList}.
17374    *
17375    * @return {VideoTrackList}
17376    *          The video track list that the Tech is currently using.
17377    */
17378
17379
17380   Tech.prototype.videoTracks = function videoTracks() {
17381     this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
17382     return this.videoTracks_;
17383   };
17384
17385   /**
17386    * Get the `Tech`s {@link AudioTrackList}.
17387    *
17388    * @return {AudioTrackList}
17389    *          The audio track list that the Tech is currently using.
17390    */
17391
17392
17393   Tech.prototype.audioTracks = function audioTracks() {
17394     this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
17395     return this.audioTracks_;
17396   };
17397
17398   /**
17399    * Get the `Tech`s {@link TextTrackList}.
17400    *
17401    * @return {TextTrackList}
17402    *          The text track list that the Tech is currently using.
17403    */
17404
17405
17406   Tech.prototype.textTracks = function textTracks() {
17407     this.textTracks_ = this.textTracks_ || new _textTrackList2['default']();
17408     return this.textTracks_;
17409   };
17410
17411   /**
17412    * Get the `Tech`s remote {@link TextTrackList}, which is created from elements
17413    * that were added to the DOM.
17414    *
17415    * @return {TextTrackList}
17416    *          The remote text track list that the Tech is currently using.
17417    */
17418
17419
17420   Tech.prototype.remoteTextTracks = function remoteTextTracks() {
17421     this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default']();
17422     return this.remoteTextTracks_;
17423   };
17424
17425   /**
17426    * Get The `Tech`s  {HTMLTrackElementList}, which are the elements in the DOM that are
17427    * being used as TextTracks.
17428    *
17429    * @return {HTMLTrackElementList}
17430    *          The current HTML track elements that exist for the tech.
17431    */
17432
17433
17434   Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
17435     this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default']();
17436     return this.remoteTextTrackEls_;
17437   };
17438
17439   /**
17440    * Create and returns a remote {@link TextTrack} object.
17441    *
17442    * @param {string} kind
17443    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
17444    *
17445    * @param {string} [label]
17446    *        Label to identify the text track
17447    *
17448    * @param {string} [language]
17449    *        Two letter language abbreviation
17450    *
17451    * @return {TextTrack}
17452    *         The TextTrack that gets created.
17453    */
17454
17455
17456   Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
17457     if (!kind) {
17458       throw new Error('TextTrack kind is required but was not provided');
17459     }
17460
17461     return createTrackHelper(this, kind, label, language);
17462   };
17463
17464   /**
17465    * Create an emulated TextTrack for use by addRemoteTextTrack
17466    *
17467    * This is intended to be overridden by classes that inherit from
17468    * Tech in order to create native or custom TextTracks.
17469    *
17470    * @param {Object} options
17471    *        The object should contain the options to initialize the TextTrack with.
17472    *
17473    * @param {string} [options.kind]
17474    *        `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
17475    *
17476    * @param {string} [options.label].
17477    *        Label to identify the text track
17478    *
17479    * @param {string} [options.language]
17480    *        Two letter language abbreviation.
17481    *
17482    * @return {HTMLTrackElement}
17483    *         The track element that gets created.
17484    */
17485
17486
17487   Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
17488     var track = (0, _mergeOptions2['default'])(options, {
17489       tech: this
17490     });
17491
17492     return new _htmlTrackElement2['default'](track);
17493   };
17494
17495   /**
17496    * Creates a remote text track object and returns an html track element.
17497    *
17498    * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
17499    *
17500    * @param {Object} options
17501    *        See {@link Tech#createRemoteTextTrack} for more detailed properties.
17502    *
17503    * @param {boolean} [manualCleanup=true]
17504    *        - When false: the TextTrack will be automatically removed from the video
17505    *          element whenever the source changes
17506    *        - When True: The TextTrack will have to be cleaned up manually
17507    *
17508    * @return {HTMLTrackElement}
17509    *         An Html Track Element.
17510    *
17511    * @deprecated The default functionality for this function will be equivalent
17512    *             to "manualCleanup=false" in the future. The manualCleanup parameter will
17513    *             also be removed.
17514    */
17515
17516
17517   Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
17518     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
17519     var manualCleanup = arguments[1];
17520
17521     var htmlTrackElement = this.createRemoteTextTrack(options);
17522
17523     if (manualCleanup !== true && manualCleanup !== false) {
17524       // deprecation warning
17525       _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');
17526       manualCleanup = true;
17527     }
17528
17529     // store HTMLTrackElement and TextTrack to remote list
17530     this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
17531     this.remoteTextTracks().addTrack_(htmlTrackElement.track);
17532
17533     if (manualCleanup !== true) {
17534       // create the TextTrackList if it doesn't exist
17535       this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track);
17536     }
17537
17538     return htmlTrackElement;
17539   };
17540
17541   /**
17542    * Remove a remote text track from the remote `TextTrackList`.
17543    *
17544    * @param {TextTrack} track
17545    *        `TextTrack` to remove from the `TextTrackList`
17546    */
17547
17548
17549   Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
17550     var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
17551
17552     // remove HTMLTrackElement and TextTrack from remote list
17553     this.remoteTextTrackEls().removeTrackElement_(trackElement);
17554     this.remoteTextTracks().removeTrack_(track);
17555     this.autoRemoteTextTracks_.removeTrack_(track);
17556   };
17557
17558   /**
17559    * A method to set a poster from a `Tech`.
17560    *
17561    * @abstract
17562    */
17563
17564
17565   Tech.prototype.setPoster = function setPoster() {};
17566
17567   /*
17568    * Check if the tech can support the given mime-type.
17569    *
17570    * The base tech does not support any type, but source handlers might
17571    * overwrite this.
17572    *
17573    * @param  {string} type
17574    *         The mimetype to check for support
17575    *
17576    * @return {string}
17577    *         'probably', 'maybe', or empty string
17578    *
17579    * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
17580    *
17581    * @abstract
17582    */
17583
17584
17585   Tech.prototype.canPlayType = function canPlayType() {
17586     return '';
17587   };
17588
17589   /*
17590    * Return whether the argument is a Tech or not.
17591    * Can be passed either a Class like `Html5` or a instance like `player.tech_`
17592    *
17593    * @param {Object} component
17594    *        The item to check
17595    *
17596    * @return {boolean}
17597    *         Whether it is a tech or not
17598    *         - True if it is a tech
17599    *         - False if it is not
17600    */
17601
17602
17603   Tech.isTech = function isTech(component) {
17604     return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
17605   };
17606
17607   /**
17608    * Registers a `Tech` into a shared list for videojs.
17609    *
17610    * @param {string} name
17611    *        Name of the `Tech` to register.
17612    *
17613    * @param {Object} tech
17614    *        The `Tech` class to register.
17615    */
17616
17617
17618   Tech.registerTech = function registerTech(name, tech) {
17619     if (!Tech.techs_) {
17620       Tech.techs_ = {};
17621     }
17622
17623     if (!Tech.isTech(tech)) {
17624       throw new Error('Tech ' + name + ' must be a Tech');
17625     }
17626
17627     Tech.techs_[name] = tech;
17628     return tech;
17629   };
17630
17631   /**
17632    * Get a `Tech` from the shared list by name.
17633    *
17634    * @param {string} name
17635    *        Name of the component to get
17636    *
17637    * @return {Tech|undefined}
17638    *         The `Tech` or undefined if there was no tech with the name requsted.
17639    */
17640
17641
17642   Tech.getTech = function getTech(name) {
17643     if (Tech.techs_ && Tech.techs_[name]) {
17644       return Tech.techs_[name];
17645     }
17646
17647     if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
17648       _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
17649       return _window2['default'].videojs[name];
17650     }
17651   };
17652
17653   return Tech;
17654 }(_component2['default']);
17655
17656 /**
17657  * List of associated text tracks.
17658  *
17659  * @type {TextTrackList}
17660  * @private
17661  */
17662
17663
17664 Tech.prototype.textTracks_; // eslint-disable-line
17665
17666 /**
17667  * List of associated audio tracks.
17668  *
17669  * @type {AudioTrackList}
17670  * @private
17671  */
17672 Tech.prototype.audioTracks_; // eslint-disable-line
17673
17674 /**
17675  * List of associated video tracks.
17676  *
17677  * @type {VideoTrackList}
17678  * @private
17679  */
17680 Tech.prototype.videoTracks_; // eslint-disable-line
17681
17682 /**
17683  * Boolean indicating wether the `Tech` supports volume control.
17684  *
17685  * @type {boolean}
17686  * @default
17687  */
17688 Tech.prototype.featuresVolumeControl = true;
17689
17690 /**
17691  * Boolean indicating wether the `Tech` support fullscreen resize control.
17692  * Resizing plugins using request fullscreen reloads the plugin
17693  *
17694  * @type {boolean}
17695  * @default
17696  */
17697 Tech.prototype.featuresFullscreenResize = false;
17698
17699 /**
17700  * Boolean indicating wether the `Tech` supports changing the speed at which the video
17701  * plays. Examples:
17702  *   - Set player to play 2x (twice) as fast
17703  *   - Set player to play 0.5x (half) as fast
17704  *
17705  * @type {boolean}
17706  * @default
17707  */
17708 Tech.prototype.featuresPlaybackRate = false;
17709
17710 /**
17711  * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
17712  * not triggered by video-js-swf. This will be used to determine if
17713  * {@link Tech#manualProgressOn} should be called.
17714  *
17715  * @type {boolean}
17716  * @default
17717  */
17718 Tech.prototype.featuresProgressEvents = false;
17719
17720 /**
17721  * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
17722  * not triggered by video-js-swf. This will be used to determine if
17723  * {@link Tech#manualTimeUpdates} should be called.
17724  *
17725  * @type {boolean}
17726  * @default
17727  */
17728 Tech.prototype.featuresTimeupdateEvents = false;
17729
17730 /**
17731  * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
17732  * This will help us integrate with native `TextTrack`s if the browser supports them.
17733  *
17734  * @type {boolean}
17735  * @default
17736  */
17737 Tech.prototype.featuresNativeTextTracks = false;
17738
17739 /**
17740  * A functional mixin for techs that want to use the Source Handler pattern.
17741  * Source handlers are scripts for handling specific formats.
17742  * The source handler pattern is used for adaptive formats (HLS, DASH) that
17743  * manually load video data and feed it into a Source Buffer (Media Source Extensions)
17744  * Example: `Tech.withSourceHandlers.call(MyTech);`
17745  *
17746  * @param {Tech} _Tech
17747  *        The tech to add source handler functions to.
17748  *
17749  * @mixes Tech~SourceHandlerAdditions
17750  */
17751 Tech.withSourceHandlers = function (_Tech) {
17752
17753   /**
17754    * Register a source handler
17755    *
17756    * @param {Function} handler
17757    *        The source handler class
17758    *
17759    * @param {number} [index]
17760    *        Register it at the following index
17761    */
17762   _Tech.registerSourceHandler = function (handler, index) {
17763     var handlers = _Tech.sourceHandlers;
17764
17765     if (!handlers) {
17766       handlers = _Tech.sourceHandlers = [];
17767     }
17768
17769     if (index === undefined) {
17770       // add to the end of the list
17771       index = handlers.length;
17772     }
17773
17774     handlers.splice(index, 0, handler);
17775   };
17776
17777   /**
17778    * Check if the tech can support the given type. Also checks the
17779    * Techs sourceHandlers.
17780    *
17781    * @param {string} type
17782    *         The mimetype to check.
17783    *
17784    * @return {string}
17785    *         'probably', 'maybe', or '' (empty string)
17786    */
17787   _Tech.canPlayType = function (type) {
17788     var handlers = _Tech.sourceHandlers || [];
17789     var can = void 0;
17790
17791     for (var i = 0; i < handlers.length; i++) {
17792       can = handlers[i].canPlayType(type);
17793
17794       if (can) {
17795         return can;
17796       }
17797     }
17798
17799     return '';
17800   };
17801
17802   /**
17803    * Returns the first source handler that supports the source.
17804    *
17805    * TODO: Answer question: should 'probably' be prioritized over 'maybe'
17806    *
17807    * @param {Tech~SourceObject} source
17808    *        The source object
17809    *
17810    * @param {Object} options
17811    *        The options passed to the tech
17812    *
17813    * @return {SourceHandler|null}
17814    *          The first source handler that supports the source or null if
17815    *          no SourceHandler supports the source
17816    */
17817   _Tech.selectSourceHandler = function (source, options) {
17818     var handlers = _Tech.sourceHandlers || [];
17819     var can = void 0;
17820
17821     for (var i = 0; i < handlers.length; i++) {
17822       can = handlers[i].canHandleSource(source, options);
17823
17824       if (can) {
17825         return handlers[i];
17826       }
17827     }
17828
17829     return null;
17830   };
17831
17832   /**
17833    * Check if the tech can support the given source.
17834    *
17835    * @param {Tech~SourceObject} srcObj
17836    *        The source object
17837    *
17838    * @param {Object} options
17839    *        The options passed to the tech
17840    *
17841    * @return {string}
17842    *         'probably', 'maybe', or '' (empty string)
17843    */
17844   _Tech.canPlaySource = function (srcObj, options) {
17845     var sh = _Tech.selectSourceHandler(srcObj, options);
17846
17847     if (sh) {
17848       return sh.canHandleSource(srcObj, options);
17849     }
17850
17851     return '';
17852   };
17853
17854   /**
17855    * When using a source handler, prefer its implementation of
17856    * any function normally provided by the tech.
17857    */
17858   var deferrable = ['seekable', 'duration'];
17859
17860   /**
17861    * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
17862    * function if it exists, with a fallback to the Techs seekable function.
17863    *
17864    * @method _Tech.seekable
17865    */
17866
17867   /**
17868    * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
17869    * function if it exists, otherwise it will fallback to the techs duration function.
17870    *
17871    * @method _Tech.duration
17872    */
17873
17874   deferrable.forEach(function (fnName) {
17875     var originalFn = this[fnName];
17876
17877     if (typeof originalFn !== 'function') {
17878       return;
17879     }
17880
17881     this[fnName] = function () {
17882       if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
17883         return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
17884       }
17885       return originalFn.apply(this, arguments);
17886     };
17887   }, _Tech.prototype);
17888
17889   /**
17890    * Create a function for setting the source using a source object
17891    * and source handlers.
17892    * Should never be called unless a source handler was found.
17893    *
17894    * @param {Tech~SourceObject} source
17895    *        A source object with src and type keys
17896    *
17897    * @return {Tech}
17898    *         Returns itself; this method is chainable
17899    */
17900   _Tech.prototype.setSource = function (source) {
17901     var sh = _Tech.selectSourceHandler(source, this.options_);
17902
17903     if (!sh) {
17904       // Fall back to a native source hander when unsupported sources are
17905       // deliberately set
17906       if (_Tech.nativeSourceHandler) {
17907         sh = _Tech.nativeSourceHandler;
17908       } else {
17909         _log2['default'].error('No source hander found for the current source.');
17910       }
17911     }
17912
17913     // Dispose any existing source handler
17914     this.disposeSourceHandler();
17915     this.off('dispose', this.disposeSourceHandler);
17916
17917     if (sh !== _Tech.nativeSourceHandler) {
17918       this.currentSource_ = source;
17919
17920       // Catch if someone replaced the src without calling setSource.
17921       // If they do, set currentSource_ to null and dispose our source handler.
17922       this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17923       this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17924       this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17925     }
17926
17927     this.sourceHandler_ = sh.handleSource(source, this, this.options_);
17928     this.on('dispose', this.disposeSourceHandler);
17929
17930     return this;
17931   };
17932
17933   /**
17934    * Called once for the first loadstart of a video.
17935    *
17936    * @listens Tech#loadstart
17937    */
17938   _Tech.prototype.firstLoadStartListener_ = function () {
17939     this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17940   };
17941
17942   // On successive loadstarts when setSource has not been called again
17943   /**
17944    * Called after the first loadstart for a video occurs.
17945    *
17946    * @listens Tech#loadstart
17947    */
17948   _Tech.prototype.successiveLoadStartListener_ = function () {
17949     this.disposeSourceHandler();
17950     this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17951   };
17952
17953   /**
17954    * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
17955    *
17956    * @listens Tech#dispose
17957    */
17958   _Tech.prototype.disposeSourceHandler = function () {
17959     // if we have a source and get another one
17960     // then we are loading something new
17961     // than clear all of our current tracks
17962     if (this.currentSource_) {
17963       this.clearTracks(['audio', 'video']);
17964       this.currentSource_ = null;
17965     }
17966
17967     // always clean up auto-text tracks
17968     this.cleanupAutoTextTracks();
17969
17970     if (this.sourceHandler_) {
17971       this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17972       this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17973
17974       if (this.sourceHandler_.dispose) {
17975         this.sourceHandler_.dispose();
17976       }
17977
17978       this.sourceHandler_ = null;
17979     }
17980   };
17981 };
17982
17983 _component2['default'].registerComponent('Tech', Tech);
17984 // Old name for Tech
17985 // @deprecated
17986 _component2['default'].registerComponent('MediaTechController', Tech);
17987 Tech.registerTech('Tech', Tech);
17988 exports['default'] = Tech;
17989
17990 },{"105":105,"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"88":88,"90":90,"94":94,"95":95}],63:[function(_dereq_,module,exports){
17991 'use strict';
17992
17993 exports.__esModule = true;
17994
17995 var _trackList = _dereq_(74);
17996
17997 var _trackList2 = _interopRequireDefault(_trackList);
17998
17999 var _browser = _dereq_(78);
18000
18001 var browser = _interopRequireWildcard(_browser);
18002
18003 var _document = _dereq_(94);
18004
18005 var _document2 = _interopRequireDefault(_document);
18006
18007 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; } }
18008
18009 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18010
18011 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18012
18013 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; }
18014
18015 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; } /**
18016                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file audio-track-list.js
18017                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
18018
18019
18020 /**
18021  * Anywhere we call this function we diverge from the spec
18022  * as we only support one enabled audiotrack at a time
18023  *
18024  * @param {AudioTrackList} list
18025  *        list to work on
18026  *
18027  * @param {AudioTrack} track
18028  *        The track to skip
18029  *
18030  * @private
18031  */
18032 var disableOthers = function disableOthers(list, track) {
18033   for (var i = 0; i < list.length; i++) {
18034     if (track.id === list[i].id) {
18035       continue;
18036     }
18037     // another audio track is enabled, disable it
18038     list[i].enabled = false;
18039   }
18040 };
18041
18042 /**
18043  * The current list of {@link AudioTrack} for a media file.
18044  *
18045  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
18046  * @extends TrackList
18047  */
18048
18049 var AudioTrackList = function (_TrackList) {
18050   _inherits(AudioTrackList, _TrackList);
18051
18052   /**
18053    * Create an instance of this class.
18054    *
18055    * @param {AudioTrack[]} [tracks=[]]
18056    *        A list of `AudioTrack` to instantiate the list with.
18057    */
18058   function AudioTrackList() {
18059     var _this, _ret;
18060
18061     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18062
18063     _classCallCheck(this, AudioTrackList);
18064
18065     var list = void 0;
18066
18067     // make sure only 1 track is enabled
18068     // sorted from last index to first index
18069     for (var i = tracks.length - 1; i >= 0; i--) {
18070       if (tracks[i].enabled) {
18071         disableOthers(tracks, tracks[i]);
18072         break;
18073       }
18074     }
18075
18076     // IE8 forces us to implement inheritance ourselves
18077     // as it does not support Object.defineProperty properly
18078     if (browser.IS_IE8) {
18079       list = _document2['default'].createElement('custom');
18080       for (var prop in _trackList2['default'].prototype) {
18081         if (prop !== 'constructor') {
18082           list[prop] = _trackList2['default'].prototype[prop];
18083         }
18084       }
18085       for (var _prop in AudioTrackList.prototype) {
18086         if (_prop !== 'constructor') {
18087           list[_prop] = AudioTrackList.prototype[_prop];
18088         }
18089       }
18090     }
18091
18092     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
18093     list.changing_ = false;
18094
18095     return _ret = list, _possibleConstructorReturn(_this, _ret);
18096   }
18097
18098   /**
18099    * Add an {@link AudioTrack} to the `AudioTrackList`.
18100    *
18101    * @param {AudioTrack} track
18102    *        The AudioTrack to add to the list
18103    *
18104    * @fires Track#addtrack
18105    * @private
18106    */
18107
18108
18109   AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
18110     var _this2 = this;
18111
18112     if (track.enabled) {
18113       disableOthers(this, track);
18114     }
18115
18116     _TrackList.prototype.addTrack_.call(this, track);
18117     // native tracks don't have this
18118     if (!track.addEventListener) {
18119       return;
18120     }
18121
18122     /**
18123      * @listens AudioTrack#enabledchange
18124      * @fires TrackList#change
18125      */
18126     track.addEventListener('enabledchange', function () {
18127       // when we are disabling other tracks (since we don't support
18128       // more than one track at a time) we will set changing_
18129       // to true so that we don't trigger additional change events
18130       if (_this2.changing_) {
18131         return;
18132       }
18133       _this2.changing_ = true;
18134       disableOthers(_this2, track);
18135       _this2.changing_ = false;
18136       _this2.trigger('change');
18137     });
18138   };
18139
18140   /**
18141    * Add an {@link AudioTrack} to the `AudioTrackList`.
18142    *
18143    * @param {AudioTrack} track
18144    *        The AudioTrack to add to the list
18145    *
18146    * @fires Track#addtrack
18147    */
18148
18149
18150   AudioTrackList.prototype.addTrack = function addTrack(track) {
18151     this.addTrack_(track);
18152   };
18153
18154   /**
18155    * Remove an {@link AudioTrack} from the `AudioTrackList`.
18156    *
18157    * @param {AudioTrack} track
18158    *        The AudioTrack to remove from the list
18159    *
18160    * @fires Track#removetrack
18161    */
18162
18163
18164   AudioTrackList.prototype.removeTrack = function removeTrack(track) {
18165     _TrackList.prototype.removeTrack_.call(this, track);
18166   };
18167
18168   return AudioTrackList;
18169 }(_trackList2['default']);
18170
18171 exports['default'] = AudioTrackList;
18172
18173 },{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){
18174 'use strict';
18175
18176 exports.__esModule = true;
18177
18178 var _trackEnums = _dereq_(73);
18179
18180 var _track = _dereq_(75);
18181
18182 var _track2 = _interopRequireDefault(_track);
18183
18184 var _mergeOptions = _dereq_(87);
18185
18186 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
18187
18188 var _browser = _dereq_(78);
18189
18190 var browser = _interopRequireWildcard(_browser);
18191
18192 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; } }
18193
18194 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18195
18196 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18197
18198 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; }
18199
18200 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; }
18201
18202 /**
18203  * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
18204  * only one `AudioTrack` in the list will be enabled at a time.
18205  *
18206  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
18207  * @extends Track
18208  */
18209 var AudioTrack = function (_Track) {
18210   _inherits(AudioTrack, _Track);
18211
18212   /**
18213    * Create an instance of this class.
18214    *
18215    * @param {Object} [options={}]
18216    *        Object of option names and values
18217    *
18218    * @param {AudioTrack~Kind} [options.kind='']
18219    *        A valid audio track kind
18220    *
18221    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18222    *        A unique id for this AudioTrack.
18223    *
18224    * @param {string} [options.label='']
18225    *        The menu label for this track.
18226    *
18227    * @param {string} [options.language='']
18228    *        A valid two character language code.
18229    *
18230    * @param {boolean} [options.enabled]
18231    *        If this track is the one that is currently playing. If this track is part of
18232    *        an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
18233    */
18234   function AudioTrack() {
18235     var _this, _ret;
18236
18237     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18238
18239     _classCallCheck(this, AudioTrack);
18240
18241     var settings = (0, _mergeOptions2['default'])(options, {
18242       kind: _trackEnums.AudioTrackKind[options.kind] || ''
18243     });
18244     // on IE8 this will be a document element
18245     // for every other browser this will be a normal object
18246     var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
18247     var enabled = false;
18248
18249     if (browser.IS_IE8) {
18250       for (var prop in AudioTrack.prototype) {
18251         if (prop !== 'constructor') {
18252           track[prop] = AudioTrack.prototype[prop];
18253         }
18254       }
18255     }
18256     /**
18257      * @member {boolean} enabled
18258      *         If this `AudioTrack` is enabled or not. When setting this will
18259      *         fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
18260      *
18261      * @fires VideoTrack#selectedchange
18262      */
18263     Object.defineProperty(track, 'enabled', {
18264       get: function get() {
18265         return enabled;
18266       },
18267       set: function set(newEnabled) {
18268         // an invalid or unchanged value
18269         if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
18270           return;
18271         }
18272         enabled = newEnabled;
18273
18274         /**
18275          * An event that fires when enabled changes on this track. This allows
18276          * the AudioTrackList that holds this track to act accordingly.
18277          *
18278          * > Note: This is not part of the spec! Native tracks will do
18279          *         this internally without an event.
18280          *
18281          * @event AudioTrack#enabledchange
18282          * @type {EventTarget~Event}
18283          */
18284         this.trigger('enabledchange');
18285       }
18286     });
18287
18288     // if the user sets this track to selected then
18289     // set selected to that true value otherwise
18290     // we keep it false
18291     if (settings.enabled) {
18292       track.enabled = settings.enabled;
18293     }
18294     track.loaded_ = true;
18295
18296     return _ret = track, _possibleConstructorReturn(_this, _ret);
18297   }
18298
18299   return AudioTrack;
18300 }(_track2['default']);
18301
18302 exports['default'] = AudioTrack;
18303
18304 },{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){
18305 'use strict';
18306
18307 exports.__esModule = true;
18308
18309 var _browser = _dereq_(78);
18310
18311 var browser = _interopRequireWildcard(_browser);
18312
18313 var _document = _dereq_(94);
18314
18315 var _document2 = _interopRequireDefault(_document);
18316
18317 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18318
18319 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; } }
18320
18321 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18322                                                                                                                                                            * @file html-track-element-list.js
18323                                                                                                                                                            */
18324
18325 /**
18326  * The current list of {@link HtmlTrackElement}s.
18327  */
18328 var HtmlTrackElementList = function () {
18329
18330   /**
18331    * Create an instance of this class.
18332    *
18333    * @param {HtmlTrackElement[]} [tracks=[]]
18334    *        A list of `HtmlTrackElement` to instantiate the list with.
18335    */
18336   function HtmlTrackElementList() {
18337     var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18338
18339     _classCallCheck(this, HtmlTrackElementList);
18340
18341     var list = this; // eslint-disable-line
18342
18343     if (browser.IS_IE8) {
18344       list = _document2['default'].createElement('custom');
18345
18346       for (var prop in HtmlTrackElementList.prototype) {
18347         if (prop !== 'constructor') {
18348           list[prop] = HtmlTrackElementList.prototype[prop];
18349         }
18350       }
18351     }
18352
18353     list.trackElements_ = [];
18354
18355     /**
18356      * @member {number} length
18357      *         The current number of `Track`s in the this Trackist.
18358      */
18359     Object.defineProperty(list, 'length', {
18360       get: function get() {
18361         return this.trackElements_.length;
18362       }
18363     });
18364
18365     for (var i = 0, length = trackElements.length; i < length; i++) {
18366       list.addTrackElement_(trackElements[i]);
18367     }
18368
18369     if (browser.IS_IE8) {
18370       return list;
18371     }
18372   }
18373
18374   /**
18375    * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
18376    *
18377    * @param {HtmlTrackElement} trackElement
18378    *        The track element to add to the list.
18379    *
18380    * @private
18381    */
18382
18383
18384   HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
18385     var index = this.trackElements_.length;
18386
18387     if (!('' + index in this)) {
18388       Object.defineProperty(this, index, {
18389         get: function get() {
18390           return this.trackElements_[index];
18391         }
18392       });
18393     }
18394
18395     // Do not add duplicate elements
18396     if (this.trackElements_.indexOf(trackElement) === -1) {
18397       this.trackElements_.push(trackElement);
18398     }
18399   };
18400
18401   /**
18402    * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
18403    * {@link TextTrack}.
18404    *
18405    * @param {TextTrack} track
18406    *        The track associated with a track element.
18407    *
18408    * @return {HtmlTrackElement|undefined}
18409    *         The track element that was found or undefined.
18410    *
18411    * @private
18412    */
18413
18414
18415   HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
18416     var trackElement_ = void 0;
18417
18418     for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18419       if (track === this.trackElements_[i].track) {
18420         trackElement_ = this.trackElements_[i];
18421
18422         break;
18423       }
18424     }
18425
18426     return trackElement_;
18427   };
18428
18429   /**
18430    * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
18431    *
18432    * @param {HtmlTrackElement} trackElement
18433    *        The track element to remove from the list.
18434    *
18435    * @private
18436    */
18437
18438
18439   HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
18440     for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18441       if (trackElement === this.trackElements_[i]) {
18442         this.trackElements_.splice(i, 1);
18443
18444         break;
18445       }
18446     }
18447   };
18448
18449   return HtmlTrackElementList;
18450 }();
18451
18452 exports['default'] = HtmlTrackElementList;
18453
18454 },{"78":78,"94":94}],66:[function(_dereq_,module,exports){
18455 'use strict';
18456
18457 exports.__esModule = true;
18458
18459 var _browser = _dereq_(78);
18460
18461 var browser = _interopRequireWildcard(_browser);
18462
18463 var _document = _dereq_(94);
18464
18465 var _document2 = _interopRequireDefault(_document);
18466
18467 var _eventTarget = _dereq_(42);
18468
18469 var _eventTarget2 = _interopRequireDefault(_eventTarget);
18470
18471 var _textTrack = _dereq_(72);
18472
18473 var _textTrack2 = _interopRequireDefault(_textTrack);
18474
18475 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18476
18477 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; } }
18478
18479 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18480
18481 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; }
18482
18483 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; } /**
18484                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file html-track-element.js
18485                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
18486
18487 /**
18488  * @typedef {HTMLTrackElement~ReadyState}
18489  * @enum {number}
18490  */
18491 var NONE = 0;
18492 var LOADING = 1;
18493 var LOADED = 2;
18494 var ERROR = 3;
18495
18496 /**
18497  * A single track represented in the DOM.
18498  *
18499  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18500  * @extends EventTarget
18501  */
18502
18503 var HTMLTrackElement = function (_EventTarget) {
18504   _inherits(HTMLTrackElement, _EventTarget);
18505
18506   /**
18507    * Create an instance of this class.
18508    *
18509    * @param {Object} options={}
18510    *        Object of option names and values
18511    *
18512    * @param {Tech} options.tech
18513    *        A reference to the tech that owns this HTMLTrackElement.
18514    *
18515    * @param {TextTrack~Kind} [options.kind='subtitles']
18516    *        A valid text track kind.
18517    *
18518    * @param {TextTrack~Mode} [options.mode='disabled']
18519    *        A valid text track mode.
18520    *
18521    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18522    *        A unique id for this TextTrack.
18523    *
18524    * @param {string} [options.label='']
18525    *        The menu label for this track.
18526    *
18527    * @param {string} [options.language='']
18528    *        A valid two character language code.
18529    *
18530    * @param {string} [options.srclang='']
18531    *        A valid two character language code. An alternative, but deprioritized
18532    *        vesion of `options.language`
18533    *
18534    * @param {string} [options.src]
18535    *        A url to TextTrack cues.
18536    *
18537    * @param {boolean} [options.default]
18538    *        If this track should default to on or off.
18539    */
18540   function HTMLTrackElement() {
18541     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18542
18543     _classCallCheck(this, HTMLTrackElement);
18544
18545     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
18546
18547     var readyState = void 0;
18548     var trackElement = _this; // eslint-disable-line
18549
18550     if (browser.IS_IE8) {
18551       trackElement = _document2['default'].createElement('custom');
18552
18553       for (var prop in HTMLTrackElement.prototype) {
18554         if (prop !== 'constructor') {
18555           trackElement[prop] = HTMLTrackElement.prototype[prop];
18556         }
18557       }
18558     }
18559
18560     var track = new _textTrack2['default'](options);
18561
18562     trackElement.kind = track.kind;
18563     trackElement.src = track.src;
18564     trackElement.srclang = track.language;
18565     trackElement.label = track.label;
18566     trackElement['default'] = track['default'];
18567
18568     /**
18569      * @member {HTMLTrackElement~ReadyState} readyState
18570      *         The current ready state of the track element.
18571      */
18572     Object.defineProperty(trackElement, 'readyState', {
18573       get: function get() {
18574         return readyState;
18575       }
18576     });
18577
18578     /**
18579      * @member {TextTrack} track
18580      *         The underlying TextTrack object.
18581      */
18582     Object.defineProperty(trackElement, 'track', {
18583       get: function get() {
18584         return track;
18585       }
18586     });
18587
18588     readyState = NONE;
18589
18590     /**
18591      * @listens TextTrack#loadeddata
18592      * @fires HTMLTrackElement#load
18593      */
18594     track.addEventListener('loadeddata', function () {
18595       readyState = LOADED;
18596
18597       trackElement.trigger({
18598         type: 'load',
18599         target: trackElement
18600       });
18601     });
18602
18603     if (browser.IS_IE8) {
18604       var _ret;
18605
18606       return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
18607     }
18608     return _this;
18609   }
18610
18611   return HTMLTrackElement;
18612 }(_eventTarget2['default']);
18613
18614 HTMLTrackElement.prototype.allowedEvents_ = {
18615   load: 'load'
18616 };
18617
18618 HTMLTrackElement.NONE = NONE;
18619 HTMLTrackElement.LOADING = LOADING;
18620 HTMLTrackElement.LOADED = LOADED;
18621 HTMLTrackElement.ERROR = ERROR;
18622
18623 exports['default'] = HTMLTrackElement;
18624
18625 },{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){
18626 'use strict';
18627
18628 exports.__esModule = true;
18629
18630 var _browser = _dereq_(78);
18631
18632 var browser = _interopRequireWildcard(_browser);
18633
18634 var _document = _dereq_(94);
18635
18636 var _document2 = _interopRequireDefault(_document);
18637
18638 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18639
18640 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; } }
18641
18642 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18643                                                                                                                                                            * @file text-track-cue-list.js
18644                                                                                                                                                            */
18645
18646
18647 /**
18648  * @typedef {Object} TextTrackCue
18649  *
18650  * @property {string} id
18651  *           The unique id for this text track cue
18652  *
18653  * @property {number} startTime
18654  *           The start time for this text track cue
18655  *
18656  * @property {number} endTime
18657  *           The end time for this text track cue
18658  *
18659  * @property {boolean} pauseOnExit
18660  *           Pause when the end time is reached if true.
18661  *
18662  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
18663  */
18664
18665 /**
18666  * A List of TextTrackCues.
18667  *
18668  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
18669  */
18670 var TextTrackCueList = function () {
18671
18672   /**
18673    * Create an instance of this class..
18674    *
18675    * @param {Array} cues
18676    *        A list of cues to be initialized with
18677    */
18678   function TextTrackCueList(cues) {
18679     _classCallCheck(this, TextTrackCueList);
18680
18681     var list = this; // eslint-disable-line
18682
18683     if (browser.IS_IE8) {
18684       list = _document2['default'].createElement('custom');
18685
18686       for (var prop in TextTrackCueList.prototype) {
18687         if (prop !== 'constructor') {
18688           list[prop] = TextTrackCueList.prototype[prop];
18689         }
18690       }
18691     }
18692
18693     TextTrackCueList.prototype.setCues_.call(list, cues);
18694
18695     /**
18696      * @member {number} length
18697      *         The current number of `TextTrackCue`s in the TextTrackCueList.
18698      */
18699     Object.defineProperty(list, 'length', {
18700       get: function get() {
18701         return this.length_;
18702       }
18703     });
18704
18705     if (browser.IS_IE8) {
18706       return list;
18707     }
18708   }
18709
18710   /**
18711    * A setter for cues in this list. Creates getters
18712    * an an index for the cues.
18713    *
18714    * @param {Array} cues
18715    *        An array of cues to set
18716    *
18717    * @private
18718    */
18719
18720
18721   TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
18722     var oldLength = this.length || 0;
18723     var i = 0;
18724     var l = cues.length;
18725
18726     this.cues_ = cues;
18727     this.length_ = cues.length;
18728
18729     var defineProp = function defineProp(index) {
18730       if (!('' + index in this)) {
18731         Object.defineProperty(this, '' + index, {
18732           get: function get() {
18733             return this.cues_[index];
18734           }
18735         });
18736       }
18737     };
18738
18739     if (oldLength < l) {
18740       i = oldLength;
18741
18742       for (; i < l; i++) {
18743         defineProp.call(this, i);
18744       }
18745     }
18746   };
18747
18748   /**
18749    * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
18750    *
18751    * @param {string} id
18752    *        The id of the cue that should be searched for.
18753    *
18754    * @return {TextTrackCue|null}
18755    *         A single cue or null if none was found.
18756    */
18757
18758
18759   TextTrackCueList.prototype.getCueById = function getCueById(id) {
18760     var result = null;
18761
18762     for (var i = 0, l = this.length; i < l; i++) {
18763       var cue = this[i];
18764
18765       if (cue.id === id) {
18766         result = cue;
18767         break;
18768       }
18769     }
18770
18771     return result;
18772   };
18773
18774   return TextTrackCueList;
18775 }();
18776
18777 exports['default'] = TextTrackCueList;
18778
18779 },{"78":78,"94":94}],68:[function(_dereq_,module,exports){
18780 'use strict';
18781
18782 exports.__esModule = true;
18783
18784 var _component = _dereq_(5);
18785
18786 var _component2 = _interopRequireDefault(_component);
18787
18788 var _fn = _dereq_(83);
18789
18790 var Fn = _interopRequireWildcard(_fn);
18791
18792 var _window = _dereq_(95);
18793
18794 var _window2 = _interopRequireDefault(_window);
18795
18796 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; } }
18797
18798 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18799
18800 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18801
18802 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; }
18803
18804 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; } /**
18805                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-display.js
18806                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
18807
18808
18809 var darkGray = '#222';
18810 var lightGray = '#ccc';
18811 var fontMap = {
18812   monospace: 'monospace',
18813   sansSerif: 'sans-serif',
18814   serif: 'serif',
18815   monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
18816   monospaceSerif: '"Courier New", monospace',
18817   proportionalSansSerif: 'sans-serif',
18818   proportionalSerif: 'serif',
18819   casual: '"Comic Sans MS", Impact, fantasy',
18820   script: '"Monotype Corsiva", cursive',
18821   smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
18822 };
18823
18824 /**
18825  * Construct an rgba color from a given hex color code.
18826  *
18827  * @param {number} color
18828  *        Hex number for color, like #f0e.
18829  *
18830  * @param {number} opacity
18831  *        Value for opacity, 0.0 - 1.0.
18832  *
18833  * @return {string}
18834  *         The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
18835  *
18836  * @private
18837  */
18838 function constructColor(color, opacity) {
18839   return 'rgba(' +
18840   // color looks like "#f0e"
18841   parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
18842 }
18843
18844 /**
18845  * Try to update the style of a DOM element. Some style changes will throw an error,
18846  * particularly in IE8. Those should be noops.
18847  *
18848  * @param {Element} el
18849  *        The DOM element to be styled.
18850  *
18851  * @param {string} style
18852  *        The CSS property on the element that should be styled.
18853  *
18854  * @param {string} rule
18855  *        The style rule that should be applied to the property.
18856  */
18857 function tryUpdateStyle(el, style, rule) {
18858   try {
18859     el.style[style] = rule;
18860   } catch (e) {
18861
18862     // Satisfies linter.
18863     return;
18864   }
18865 }
18866
18867 /**
18868  * The component for displaying text track cues.
18869  *
18870  * @extends Component
18871  */
18872
18873 var TextTrackDisplay = function (_Component) {
18874   _inherits(TextTrackDisplay, _Component);
18875
18876   /**
18877    * Creates an instance of this class.
18878    *
18879    * @param {Player} player
18880    *        The `Player` that this class should be attached to.
18881    *
18882    * @param {Object} [options]
18883    *        The key/value store of player options.
18884    *
18885    * @param {Component~ReadyCallback} [ready]
18886    *        The function to call when `TextTrackDisplay` is ready.
18887    */
18888   function TextTrackDisplay(player, options, ready) {
18889     _classCallCheck(this, TextTrackDisplay);
18890
18891     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
18892
18893     player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
18894     player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
18895
18896     // This used to be called during player init, but was causing an error
18897     // if a track should show by default and the display hadn't loaded yet.
18898     // Should probably be moved to an external track loader when we support
18899     // tracks that don't need a display.
18900     player.ready(Fn.bind(_this, function () {
18901       if (player.tech_ && player.tech_.featuresNativeTextTracks) {
18902         this.hide();
18903         return;
18904       }
18905
18906       player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
18907
18908       var tracks = this.options_.playerOptions.tracks || [];
18909
18910       for (var i = 0; i < tracks.length; i++) {
18911         this.player_.addRemoteTextTrack(tracks[i], true);
18912       }
18913
18914       var modes = { captions: 1, subtitles: 1 };
18915       var trackList = this.player_.textTracks();
18916       var firstDesc = void 0;
18917       var firstCaptions = void 0;
18918
18919       if (trackList) {
18920         for (var _i = 0; _i < trackList.length; _i++) {
18921           var track = trackList[_i];
18922
18923           if (track['default']) {
18924             if (track.kind === 'descriptions' && !firstDesc) {
18925               firstDesc = track;
18926             } else if (track.kind in modes && !firstCaptions) {
18927               firstCaptions = track;
18928             }
18929           }
18930         }
18931
18932         // We want to show the first default track but captions and subtitles
18933         // take precedence over descriptions.
18934         // So, display the first default captions or subtitles track
18935         // and otherwise the first default descriptions track.
18936         if (firstCaptions) {
18937           firstCaptions.mode = 'showing';
18938         } else if (firstDesc) {
18939           firstDesc.mode = 'showing';
18940         }
18941       }
18942     }));
18943     return _this;
18944   }
18945
18946   /**
18947    * Turn display of {@link TextTrack}'s from the current state into the other state.
18948    * There are only two states:
18949    * - 'shown'
18950    * - 'hidden'
18951    *
18952    * @listens Player#loadstart
18953    */
18954
18955
18956   TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
18957     if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
18958       this.hide();
18959     } else {
18960       this.show();
18961     }
18962   };
18963
18964   /**
18965    * Create the {@link Component}'s DOM element.
18966    *
18967    * @return {Element}
18968    *         The element that was created.
18969    */
18970
18971
18972   TextTrackDisplay.prototype.createEl = function createEl() {
18973     return _Component.prototype.createEl.call(this, 'div', {
18974       className: 'vjs-text-track-display'
18975     }, {
18976       'aria-live': 'off',
18977       'aria-atomic': 'true'
18978     });
18979   };
18980
18981   /**
18982    * Clear all displayed {@link TextTrack}s.
18983    */
18984
18985
18986   TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
18987     if (typeof _window2['default'].WebVTT === 'function') {
18988       _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
18989     }
18990   };
18991
18992   /**
18993    * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
18994    * a {@link Player#fullscreenchange} is fired.
18995    *
18996    * @listens Player#texttrackchange
18997    * @listens Player#fullscreenchange
18998    */
18999
19000
19001   TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
19002     var tracks = this.player_.textTracks();
19003
19004     this.clearDisplay();
19005
19006     if (!tracks) {
19007       return;
19008     }
19009
19010     // Track display prioritization model: if multiple tracks are 'showing',
19011     //  display the first 'subtitles' or 'captions' track which is 'showing',
19012     //  otherwise display the first 'descriptions' track which is 'showing'
19013
19014     var descriptionsTrack = null;
19015     var captionsSubtitlesTrack = null;
19016
19017     var i = tracks.length;
19018
19019     while (i--) {
19020       var track = tracks[i];
19021
19022       if (track.mode === 'showing') {
19023         if (track.kind === 'descriptions') {
19024           descriptionsTrack = track;
19025         } else {
19026           captionsSubtitlesTrack = track;
19027         }
19028       }
19029     }
19030
19031     if (captionsSubtitlesTrack) {
19032       if (this.getAttribute('aria-live') !== 'off') {
19033         this.setAttribute('aria-live', 'off');
19034       }
19035       this.updateForTrack(captionsSubtitlesTrack);
19036     } else if (descriptionsTrack) {
19037       if (this.getAttribute('aria-live') !== 'assertive') {
19038         this.setAttribute('aria-live', 'assertive');
19039       }
19040       this.updateForTrack(descriptionsTrack);
19041     }
19042   };
19043
19044   /**
19045    * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
19046    *
19047    * @param {TextTrack} track
19048    *        Text track object to be added to the list.
19049    */
19050
19051
19052   TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
19053     if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
19054       return;
19055     }
19056
19057     var overrides = this.player_.textTrackSettings.getValues();
19058     var cues = [];
19059
19060     for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
19061       cues.push(track.activeCues[_i2]);
19062     }
19063
19064     _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
19065
19066     var i = cues.length;
19067
19068     while (i--) {
19069       var cue = cues[i];
19070
19071       if (!cue) {
19072         continue;
19073       }
19074
19075       var cueDiv = cue.displayState;
19076
19077       if (overrides.color) {
19078         cueDiv.firstChild.style.color = overrides.color;
19079       }
19080       if (overrides.textOpacity) {
19081         tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
19082       }
19083       if (overrides.backgroundColor) {
19084         cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
19085       }
19086       if (overrides.backgroundOpacity) {
19087         tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
19088       }
19089       if (overrides.windowColor) {
19090         if (overrides.windowOpacity) {
19091           tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
19092         } else {
19093           cueDiv.style.backgroundColor = overrides.windowColor;
19094         }
19095       }
19096       if (overrides.edgeStyle) {
19097         if (overrides.edgeStyle === 'dropshadow') {
19098           cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
19099         } else if (overrides.edgeStyle === 'raised') {
19100           cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
19101         } else if (overrides.edgeStyle === 'depressed') {
19102           cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
19103         } else if (overrides.edgeStyle === 'uniform') {
19104           cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
19105         }
19106       }
19107       if (overrides.fontPercent && overrides.fontPercent !== 1) {
19108         var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
19109
19110         cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
19111         cueDiv.style.height = 'auto';
19112         cueDiv.style.top = 'auto';
19113         cueDiv.style.bottom = '2px';
19114       }
19115       if (overrides.fontFamily && overrides.fontFamily !== 'default') {
19116         if (overrides.fontFamily === 'small-caps') {
19117           cueDiv.firstChild.style.fontVariant = 'small-caps';
19118         } else {
19119           cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
19120         }
19121       }
19122     }
19123   };
19124
19125   return TextTrackDisplay;
19126 }(_component2['default']);
19127
19128 _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
19129 exports['default'] = TextTrackDisplay;
19130
19131 },{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){
19132 'use strict';
19133
19134 exports.__esModule = true;
19135 /**
19136  * @file text-track-list-converter.js Utilities for capturing text track state and
19137  * re-creating tracks based on a capture.
19138  *
19139  * @module text-track-list-converter
19140  */
19141
19142 /**
19143  * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
19144  * represents the {@link TextTrack}'s state.
19145  *
19146  * @param {TextTrack} track
19147  *        The text track to query.
19148  *
19149  * @return {Object}
19150  *         A serializable javascript representation of the TextTrack.
19151  * @private
19152  */
19153 var trackToJson_ = function trackToJson_(track) {
19154   var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
19155
19156     if (track[prop]) {
19157       acc[prop] = track[prop];
19158     }
19159
19160     return acc;
19161   }, {
19162     cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
19163       return {
19164         startTime: cue.startTime,
19165         endTime: cue.endTime,
19166         text: cue.text,
19167         id: cue.id
19168       };
19169     })
19170   });
19171
19172   return ret;
19173 };
19174
19175 /**
19176  * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
19177  * state of all {@link TextTrack}s currently configured. The return array is compatible with
19178  * {@link text-track-list-converter:jsonToTextTracks}.
19179  *
19180  * @param {Tech} tech
19181  *        The tech object to query
19182  *
19183  * @return {Array}
19184  *         A serializable javascript representation of the {@link Tech}s
19185  *         {@link TextTrackList}.
19186  */
19187 var textTracksToJson = function textTracksToJson(tech) {
19188
19189   var trackEls = tech.$$('track');
19190
19191   var trackObjs = Array.prototype.map.call(trackEls, function (t) {
19192     return t.track;
19193   });
19194   var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
19195     var json = trackToJson_(trackEl.track);
19196
19197     if (trackEl.src) {
19198       json.src = trackEl.src;
19199     }
19200     return json;
19201   });
19202
19203   return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
19204     return trackObjs.indexOf(track) === -1;
19205   }).map(trackToJson_));
19206 };
19207
19208 /**
19209  * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
19210  * object {@link TextTrack} representations.
19211  *
19212  * @param {Array} json
19213  *        An array of `TextTrack` representation objects, like those that would be
19214  *        produced by `textTracksToJson`.
19215  *
19216  * @param {Tech} tech
19217  *        The `Tech` to create the `TextTrack`s on.
19218  */
19219 var jsonToTextTracks = function jsonToTextTracks(json, tech) {
19220   json.forEach(function (track) {
19221     var addedTrack = tech.addRemoteTextTrack(track).track;
19222
19223     if (!track.src && track.cues) {
19224       track.cues.forEach(function (cue) {
19225         return addedTrack.addCue(cue);
19226       });
19227     }
19228   });
19229
19230   return tech.textTracks();
19231 };
19232
19233 exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
19234
19235 },{}],70:[function(_dereq_,module,exports){
19236 'use strict';
19237
19238 exports.__esModule = true;
19239
19240 var _trackList = _dereq_(74);
19241
19242 var _trackList2 = _interopRequireDefault(_trackList);
19243
19244 var _fn = _dereq_(83);
19245
19246 var Fn = _interopRequireWildcard(_fn);
19247
19248 var _browser = _dereq_(78);
19249
19250 var browser = _interopRequireWildcard(_browser);
19251
19252 var _document = _dereq_(94);
19253
19254 var _document2 = _interopRequireDefault(_document);
19255
19256 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; } }
19257
19258 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19259
19260 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19261
19262 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; }
19263
19264 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; } /**
19265                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-list.js
19266                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19267
19268
19269 /**
19270  * The current list of {@link TextTrack} for a media file.
19271  *
19272  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
19273  * @extends TrackList
19274  */
19275 var TextTrackList = function (_TrackList) {
19276   _inherits(TextTrackList, _TrackList);
19277
19278   /**
19279    * Create an instance of this class.
19280    *
19281    * @param {TextTrack[]} [tracks=[]]
19282    *        A list of `TextTrack` to instantiate the list with.
19283    */
19284   function TextTrackList() {
19285     var _this, _ret;
19286
19287     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
19288
19289     _classCallCheck(this, TextTrackList);
19290
19291     var list = void 0;
19292
19293     // IE8 forces us to implement inheritance ourselves
19294     // as it does not support Object.defineProperty properly
19295     if (browser.IS_IE8) {
19296       list = _document2['default'].createElement('custom');
19297       for (var prop in _trackList2['default'].prototype) {
19298         if (prop !== 'constructor') {
19299           list[prop] = _trackList2['default'].prototype[prop];
19300         }
19301       }
19302       for (var _prop in TextTrackList.prototype) {
19303         if (_prop !== 'constructor') {
19304           list[_prop] = TextTrackList.prototype[_prop];
19305         }
19306       }
19307     }
19308
19309     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
19310     return _ret = list, _possibleConstructorReturn(_this, _ret);
19311   }
19312
19313   /**
19314    * Add a {@link TextTrack} to the `TextTrackList`
19315    *
19316    * @param {TextTrack} track
19317    *        The text track to add to the list.
19318    *
19319    * @fires TrackList#addtrack
19320    * @private
19321    */
19322
19323
19324   TextTrackList.prototype.addTrack_ = function addTrack_(track) {
19325     _TrackList.prototype.addTrack_.call(this, track);
19326
19327     /**
19328      * @listens TextTrack#modechange
19329      * @fires TrackList#change
19330      */
19331     track.addEventListener('modechange', Fn.bind(this, function () {
19332       this.trigger('change');
19333     }));
19334   };
19335
19336   return TextTrackList;
19337 }(_trackList2['default']);
19338
19339 exports['default'] = TextTrackList;
19340
19341 },{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){
19342 'use strict';
19343
19344 exports.__esModule = true;
19345
19346 var _window = _dereq_(95);
19347
19348 var _window2 = _interopRequireDefault(_window);
19349
19350 var _component = _dereq_(5);
19351
19352 var _component2 = _interopRequireDefault(_component);
19353
19354 var _dom = _dereq_(81);
19355
19356 var _fn = _dereq_(83);
19357
19358 var Fn = _interopRequireWildcard(_fn);
19359
19360 var _obj = _dereq_(88);
19361
19362 var Obj = _interopRequireWildcard(_obj);
19363
19364 var _log = _dereq_(86);
19365
19366 var _log2 = _interopRequireDefault(_log);
19367
19368 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; } }
19369
19370 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19371
19372 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19373
19374 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; }
19375
19376 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; } /**
19377                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track-settings.js
19378                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19379
19380
19381 var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
19382
19383 var COLOR_BLACK = ['#000', 'Black'];
19384 var COLOR_BLUE = ['#00F', 'Blue'];
19385 var COLOR_CYAN = ['#0FF', 'Cyan'];
19386 var COLOR_GREEN = ['#0F0', 'Green'];
19387 var COLOR_MAGENTA = ['#F0F', 'Magenta'];
19388 var COLOR_RED = ['#F00', 'Red'];
19389 var COLOR_WHITE = ['#FFF', 'White'];
19390 var COLOR_YELLOW = ['#FF0', 'Yellow'];
19391
19392 var OPACITY_OPAQUE = ['1', 'Opaque'];
19393 var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
19394 var OPACITY_TRANS = ['0', 'Transparent'];
19395
19396 // Configuration for the various <select> elements in the DOM of this component.
19397 //
19398 // Possible keys include:
19399 //
19400 // `default`:
19401 //   The default option index. Only needs to be provided if not zero.
19402 // `parser`:
19403 //   A function which is used to parse the value from the selected option in
19404 //   a customized way.
19405 // `selector`:
19406 //   The selector used to find the associated <select> element.
19407 var selectConfigs = {
19408   backgroundColor: {
19409     selector: '.vjs-bg-color > select',
19410     id: 'captions-background-color-%s',
19411     label: 'Color',
19412     options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19413   },
19414
19415   backgroundOpacity: {
19416     selector: '.vjs-bg-opacity > select',
19417     id: 'captions-background-opacity-%s',
19418     label: 'Transparency',
19419     options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
19420   },
19421
19422   color: {
19423     selector: '.vjs-fg-color > select',
19424     id: 'captions-foreground-color-%s',
19425     label: 'Color',
19426     options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19427   },
19428
19429   edgeStyle: {
19430     selector: '.vjs-edge-style > select',
19431     id: '%s',
19432     label: 'Text Edge Style',
19433     options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
19434   },
19435
19436   fontFamily: {
19437     selector: '.vjs-font-family > select',
19438     id: 'captions-font-family-%s',
19439     label: 'Font Family',
19440     options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
19441   },
19442
19443   fontPercent: {
19444     selector: '.vjs-font-percent > select',
19445     id: 'captions-font-size-%s',
19446     label: 'Font Size',
19447     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%']],
19448     'default': 2,
19449     parser: function parser(v) {
19450       return v === '1.00' ? null : Number(v);
19451     }
19452   },
19453
19454   textOpacity: {
19455     selector: '.vjs-text-opacity > select',
19456     id: 'captions-foreground-opacity-%s',
19457     label: 'Transparency',
19458     options: [OPACITY_OPAQUE, OPACITY_SEMI]
19459   },
19460
19461   // Options for this object are defined below.
19462   windowColor: {
19463     selector: '.vjs-window-color > select',
19464     id: 'captions-window-color-%s',
19465     label: 'Color'
19466   },
19467
19468   // Options for this object are defined below.
19469   windowOpacity: {
19470     selector: '.vjs-window-opacity > select',
19471     id: 'captions-window-opacity-%s',
19472     label: 'Transparency',
19473     options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
19474   }
19475 };
19476
19477 selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
19478
19479 /**
19480  * Get the actual value of an option.
19481  *
19482  * @param  {string} value
19483  *         The value to get
19484  *
19485  * @param  {Function} [parser]
19486  *         Optional function to adjust the value.
19487  *
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.
19492  *
19493  * @private
19494  */
19495 function parseOptionValue(value, parser) {
19496   if (parser) {
19497     value = parser(value);
19498   }
19499
19500   if (value && value !== 'none') {
19501     return value;
19502   }
19503 }
19504
19505 /**
19506  * Gets the value of the selected <option> element within a <select> element.
19507  *
19508  * @param  {Element} el
19509  *         the element to look in
19510  *
19511  * @param  {Function} [parser]
19512  *         Optional function to adjust the value.
19513  *
19514  * @return {Mixed}
19515  *         - Will be `undefined` if no value exists
19516  *         - Will be `undefined` if the given value is "none".
19517  *         - Will be the actual value otherwise.
19518  *
19519  * @private
19520  */
19521 function getSelectedOptionValue(el, parser) {
19522   var value = el.options[el.options.selectedIndex].value;
19523
19524   return parseOptionValue(value, parser);
19525 }
19526
19527 /**
19528  * Sets the selected <option> element within a <select> element based on a
19529  * given value.
19530  *
19531  * @param {Element} el
19532  *        The element to look in.
19533  *
19534  * @param {string} value
19535  *        the property to look on.
19536  *
19537  * @param {Function} [parser]
19538  *        Optional function to adjust the value before comparing.
19539  *
19540  * @private
19541  */
19542 function setSelectedOption(el, value, parser) {
19543   if (!value) {
19544     return;
19545   }
19546
19547   for (var i = 0; i < el.options.length; i++) {
19548     if (parseOptionValue(el.options[i].value, parser) === value) {
19549       el.selectedIndex = i;
19550       break;
19551     }
19552   }
19553 }
19554
19555 /**
19556  * Manipulate Text Tracks settings.
19557  *
19558  * @extends Component
19559  */
19560
19561 var TextTrackSettings = function (_Component) {
19562   _inherits(TextTrackSettings, _Component);
19563
19564   /**
19565    * Creates an instance of this class.
19566    *
19567    * @param {Player} player
19568    *         The `Player` that this class should be attached to.
19569    *
19570    * @param {Object} [options]
19571    *         The key/value store of player options.
19572    */
19573   function TextTrackSettings(player, options) {
19574     _classCallCheck(this, TextTrackSettings);
19575
19576     var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
19577
19578     _this.setDefaults();
19579     _this.hide();
19580
19581     _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
19582
19583     // Grab `persistTextTrackSettings` from the player options if not passed in child options
19584     if (options.persistTextTrackSettings === undefined) {
19585       _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
19586     }
19587
19588     _this.on(_this.$('.vjs-done-button'), 'click', function () {
19589       _this.saveSettings();
19590       _this.hide();
19591     });
19592
19593     _this.on(_this.$('.vjs-default-button'), 'click', function () {
19594       _this.setDefaults();
19595       _this.updateDisplay();
19596     });
19597
19598     Obj.each(selectConfigs, function (config) {
19599       _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
19600     });
19601
19602     if (_this.options_.persistTextTrackSettings) {
19603       _this.restoreSettings();
19604     }
19605     return _this;
19606   }
19607
19608   /**
19609    * Create a <select> element with configured options.
19610    *
19611    * @param {string} key
19612    *        Configuration key to use during creation.
19613    *
19614    * @return {Element}
19615    *         The DOM element that gets created.
19616    * @private
19617    */
19618
19619
19620   TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
19621     var _this2 = this;
19622
19623     var config = selectConfigs[key];
19624     var id = config.id.replace('%s', this.id_);
19625
19626     return [(0, _dom.createEl)('label', {
19627       className: 'vjs-label',
19628       textContent: config.label
19629     }, {
19630       'for': id
19631     }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
19632       return (0, _dom.createEl)('option', {
19633         textContent: _this2.localize(o[1]),
19634         value: o[0]
19635       });
19636     }))];
19637   };
19638
19639   /**
19640    * Create foreground color element for the component
19641    *
19642    * @return {Element}
19643    *         The element that was created.
19644    *
19645    * @private
19646    */
19647
19648
19649   TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
19650     var legend = (0, _dom.createEl)('legend', {
19651       textContent: this.localize('Text')
19652     });
19653
19654     var select = this.createElSelect_('color');
19655
19656     var opacity = (0, _dom.createEl)('span', {
19657       className: 'vjs-text-opacity vjs-opacity'
19658     }, undefined, this.createElSelect_('textOpacity'));
19659
19660     return (0, _dom.createEl)('fieldset', {
19661       className: 'vjs-fg-color vjs-tracksetting'
19662     }, undefined, [legend].concat(select, opacity));
19663   };
19664
19665   /**
19666    * Create background color element for the component
19667    *
19668    * @return {Element}
19669    *         The element that was created
19670    *
19671    * @private
19672    */
19673
19674
19675   TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
19676     var legend = (0, _dom.createEl)('legend', {
19677       textContent: this.localize('Background')
19678     });
19679
19680     var select = this.createElSelect_('backgroundColor');
19681
19682     var opacity = (0, _dom.createEl)('span', {
19683       className: 'vjs-bg-opacity vjs-opacity'
19684     }, undefined, this.createElSelect_('backgroundOpacity'));
19685
19686     return (0, _dom.createEl)('fieldset', {
19687       className: 'vjs-bg-color vjs-tracksetting'
19688     }, undefined, [legend].concat(select, opacity));
19689   };
19690
19691   /**
19692    * Create window color element for the component
19693    *
19694    * @return {Element}
19695    *         The element that was created
19696    *
19697    * @private
19698    */
19699
19700
19701   TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
19702     var legend = (0, _dom.createEl)('legend', {
19703       textContent: this.localize('Window')
19704     });
19705
19706     var select = this.createElSelect_('windowColor');
19707
19708     var opacity = (0, _dom.createEl)('span', {
19709       className: 'vjs-window-opacity vjs-opacity'
19710     }, undefined, this.createElSelect_('windowOpacity'));
19711
19712     return (0, _dom.createEl)('fieldset', {
19713       className: 'vjs-window-color vjs-tracksetting'
19714     }, undefined, [legend].concat(select, opacity));
19715   };
19716
19717   /**
19718    * Create color elements for the component
19719    *
19720    * @return {Element}
19721    *         The element that was created
19722    *
19723    * @private
19724    */
19725
19726
19727   TextTrackSettings.prototype.createElColors_ = function createElColors_() {
19728     return (0, _dom.createEl)('div', {
19729       className: 'vjs-tracksettings-colors'
19730     }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
19731   };
19732
19733   /**
19734    * Create font elements for the component
19735    *
19736    * @return {Element}
19737    *         The element that was created.
19738    *
19739    * @private
19740    */
19741
19742
19743   TextTrackSettings.prototype.createElFont_ = function createElFont_() {
19744     var fontPercent = (0, _dom.createEl)('div', {
19745       className: 'vjs-font-percent vjs-tracksetting'
19746     }, undefined, this.createElSelect_('fontPercent'));
19747
19748     var edgeStyle = (0, _dom.createEl)('div', {
19749       className: 'vjs-edge-style vjs-tracksetting'
19750     }, undefined, this.createElSelect_('edgeStyle'));
19751
19752     var fontFamily = (0, _dom.createEl)('div', {
19753       className: 'vjs-font-family vjs-tracksetting'
19754     }, undefined, this.createElSelect_('fontFamily'));
19755
19756     return (0, _dom.createEl)('div', {
19757       className: 'vjs-tracksettings-font'
19758     }, undefined, [fontPercent, edgeStyle, fontFamily]);
19759   };
19760
19761   /**
19762    * Create controls for the component
19763    *
19764    * @return {Element}
19765    *         The element that was created.
19766    *
19767    * @private
19768    */
19769
19770
19771   TextTrackSettings.prototype.createElControls_ = function createElControls_() {
19772     var defaultsButton = (0, _dom.createEl)('button', {
19773       className: 'vjs-default-button',
19774       textContent: this.localize('Defaults')
19775     });
19776
19777     var doneButton = (0, _dom.createEl)('button', {
19778       className: 'vjs-done-button',
19779       textContent: 'Done'
19780     });
19781
19782     return (0, _dom.createEl)('div', {
19783       className: 'vjs-tracksettings-controls'
19784     }, undefined, [defaultsButton, doneButton]);
19785   };
19786
19787   /**
19788    * Create the component's DOM element
19789    *
19790    * @return {Element}
19791    *         The element that was created.
19792    */
19793
19794
19795   TextTrackSettings.prototype.createEl = function createEl() {
19796     var settings = (0, _dom.createEl)('div', {
19797       className: 'vjs-tracksettings'
19798     }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
19799
19800     var heading = (0, _dom.createEl)('div', {
19801       className: 'vjs-control-text',
19802       id: 'TTsettingsDialogLabel-' + this.id_,
19803       textContent: 'Caption Settings Dialog'
19804     }, {
19805       'aria-level': '1',
19806       'role': 'heading'
19807     });
19808
19809     var description = (0, _dom.createEl)('div', {
19810       className: 'vjs-control-text',
19811       id: 'TTsettingsDialogDescription-' + this.id_,
19812       textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
19813     });
19814
19815     var doc = (0, _dom.createEl)('div', undefined, {
19816       role: 'document'
19817     }, [heading, description, settings]);
19818
19819     return (0, _dom.createEl)('div', {
19820       className: 'vjs-caption-settings vjs-modal-overlay',
19821       tabIndex: -1
19822     }, {
19823       'role': 'dialog',
19824       'aria-labelledby': heading.id,
19825       'aria-describedby': description.id
19826     }, doc);
19827   };
19828
19829   /**
19830    * Gets an object of text track settings (or null).
19831    *
19832    * @return {Object}
19833    *         An object with config values parsed from the DOM or localStorage.
19834    */
19835
19836
19837   TextTrackSettings.prototype.getValues = function getValues() {
19838     var _this3 = this;
19839
19840     return Obj.reduce(selectConfigs, function (accum, config, key) {
19841       var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
19842
19843       if (value !== undefined) {
19844         accum[key] = value;
19845       }
19846
19847       return accum;
19848     }, {});
19849   };
19850
19851   /**
19852    * Sets text track settings from an object of values.
19853    *
19854    * @param {Object} values
19855    *        An object with config values parsed from the DOM or localStorage.
19856    */
19857
19858
19859   TextTrackSettings.prototype.setValues = function setValues(values) {
19860     var _this4 = this;
19861
19862     Obj.each(selectConfigs, function (config, key) {
19863       setSelectedOption(_this4.$(config.selector), values[key], config.parser);
19864     });
19865   };
19866
19867   /**
19868    * Sets all <select> elements to their default values.
19869    */
19870
19871
19872   TextTrackSettings.prototype.setDefaults = function setDefaults() {
19873     var _this5 = this;
19874
19875     Obj.each(selectConfigs, function (config) {
19876       var index = config.hasOwnProperty('default') ? config['default'] : 0;
19877
19878       _this5.$(config.selector).selectedIndex = index;
19879     });
19880   };
19881
19882   /**
19883    * Restore texttrack settings from localStorage
19884    */
19885
19886
19887   TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
19888     var values = void 0;
19889
19890     try {
19891       values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
19892     } catch (err) {
19893       _log2['default'].warn(err);
19894     }
19895
19896     if (values) {
19897       this.setValues(values);
19898     }
19899   };
19900
19901   /**
19902    * Save text track settings to localStorage
19903    */
19904
19905
19906   TextTrackSettings.prototype.saveSettings = function saveSettings() {
19907     if (!this.options_.persistTextTrackSettings) {
19908       return;
19909     }
19910
19911     var values = this.getValues();
19912
19913     try {
19914       if (Object.keys(values).length) {
19915         _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
19916       } else {
19917         _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
19918       }
19919     } catch (err) {
19920       _log2['default'].warn(err);
19921     }
19922   };
19923
19924   /**
19925    * Update display of text track settings
19926    */
19927
19928
19929   TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
19930     var ttDisplay = this.player_.getChild('textTrackDisplay');
19931
19932     if (ttDisplay) {
19933       ttDisplay.updateDisplay();
19934     }
19935   };
19936
19937   return TextTrackSettings;
19938 }(_component2['default']);
19939
19940 _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
19941
19942 exports['default'] = TextTrackSettings;
19943
19944 },{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){
19945 'use strict';
19946
19947 exports.__esModule = true;
19948
19949 var _textTrackCueList = _dereq_(67);
19950
19951 var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
19952
19953 var _fn = _dereq_(83);
19954
19955 var Fn = _interopRequireWildcard(_fn);
19956
19957 var _trackEnums = _dereq_(73);
19958
19959 var _log = _dereq_(86);
19960
19961 var _log2 = _interopRequireDefault(_log);
19962
19963 var _window = _dereq_(95);
19964
19965 var _window2 = _interopRequireDefault(_window);
19966
19967 var _track = _dereq_(75);
19968
19969 var _track2 = _interopRequireDefault(_track);
19970
19971 var _url = _dereq_(92);
19972
19973 var _xhr = _dereq_(99);
19974
19975 var _xhr2 = _interopRequireDefault(_xhr);
19976
19977 var _mergeOptions = _dereq_(87);
19978
19979 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
19980
19981 var _browser = _dereq_(78);
19982
19983 var browser = _interopRequireWildcard(_browser);
19984
19985 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; } }
19986
19987 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19988
19989 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19990
19991 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; }
19992
19993 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; } /**
19994                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file text-track.js
19995                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
19996
19997
19998 /**
19999  * Takes a webvtt file contents and parses it into cues
20000  *
20001  * @param {string} srcContent
20002  *        webVTT file contents
20003  *
20004  * @param {TextTrack} track
20005  *        TextTrack to add cues to. Cues come from the srcContent.
20006  *
20007  * @private
20008  */
20009 var parseCues = function parseCues(srcContent, track) {
20010   var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
20011   var errors = [];
20012
20013   parser.oncue = function (cue) {
20014     track.addCue(cue);
20015   };
20016
20017   parser.onparsingerror = function (error) {
20018     errors.push(error);
20019   };
20020
20021   parser.onflush = function () {
20022     track.trigger({
20023       type: 'loadeddata',
20024       target: track
20025     });
20026   };
20027
20028   parser.parse(srcContent);
20029   if (errors.length > 0) {
20030     if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
20031       _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
20032     }
20033     errors.forEach(function (error) {
20034       return _log2['default'].error(error);
20035     });
20036     if (_window2['default'].console && _window2['default'].console.groupEnd) {
20037       _window2['default'].console.groupEnd();
20038     }
20039   }
20040
20041   parser.flush();
20042 };
20043
20044 /**
20045  * Load a `TextTrack` from a specifed url.
20046  *
20047  * @param {string} src
20048  *        Url to load track from.
20049  *
20050  * @param {TextTrack} track
20051  *        Track to add cues to. Comes from the content at the end of `url`.
20052  *
20053  * @private
20054  */
20055 var loadTrack = function loadTrack(src, track) {
20056   var opts = {
20057     uri: src
20058   };
20059   var crossOrigin = (0, _url.isCrossOrigin)(src);
20060
20061   if (crossOrigin) {
20062     opts.cors = crossOrigin;
20063   }
20064
20065   (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
20066     if (err) {
20067       return _log2['default'].error(err, response);
20068     }
20069
20070     track.loaded_ = true;
20071
20072     // Make sure that vttjs has loaded, otherwise, wait till it finished loading
20073     // NOTE: this is only used for the alt/video.novtt.js build
20074     if (typeof _window2['default'].WebVTT !== 'function') {
20075       if (track.tech_) {
20076         var loadHandler = function loadHandler() {
20077           return parseCues(responseBody, track);
20078         };
20079
20080         track.tech_.on('vttjsloaded', loadHandler);
20081         track.tech_.on('vttjserror', function () {
20082           _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
20083           track.tech_.off('vttjsloaded', loadHandler);
20084         });
20085       }
20086     } else {
20087       parseCues(responseBody, track);
20088     }
20089   }));
20090 };
20091
20092 /**
20093  * A representation of a single `TextTrack`.
20094  *
20095  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
20096  * @extends Track
20097  */
20098
20099 var TextTrack = function (_Track) {
20100   _inherits(TextTrack, _Track);
20101
20102   /**
20103    * Create an instance of this class.
20104    *
20105    * @param {Object} options={}
20106    *        Object of option names and values
20107    *
20108    * @param {Tech} options.tech
20109    *        A reference to the tech that owns this TextTrack.
20110    *
20111    * @param {TextTrack~Kind} [options.kind='subtitles']
20112    *        A valid text track kind.
20113    *
20114    * @param {TextTrack~Mode} [options.mode='disabled']
20115    *        A valid text track mode.
20116    *
20117    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20118    *        A unique id for this TextTrack.
20119    *
20120    * @param {string} [options.label='']
20121    *        The menu label for this track.
20122    *
20123    * @param {string} [options.language='']
20124    *        A valid two character language code.
20125    *
20126    * @param {string} [options.srclang='']
20127    *        A valid two character language code. An alternative, but deprioritized
20128    *        vesion of `options.language`
20129    *
20130    * @param {string} [options.src]
20131    *        A url to TextTrack cues.
20132    *
20133    * @param {boolean} [options.default]
20134    *        If this track should default to on or off.
20135    */
20136   function TextTrack() {
20137     var _this, _ret;
20138
20139     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20140
20141     _classCallCheck(this, TextTrack);
20142
20143     if (!options.tech) {
20144       throw new Error('A tech was not provided.');
20145     }
20146
20147     var settings = (0, _mergeOptions2['default'])(options, {
20148       kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
20149       language: options.language || options.srclang || ''
20150     });
20151     var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
20152     var default_ = settings['default'];
20153
20154     if (settings.kind === 'metadata' || settings.kind === 'chapters') {
20155       mode = 'hidden';
20156     }
20157     // on IE8 this will be a document element
20158     // for every other browser this will be a normal object
20159     var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
20160
20161     tt.tech_ = settings.tech;
20162
20163     if (browser.IS_IE8) {
20164       for (var prop in TextTrack.prototype) {
20165         if (prop !== 'constructor') {
20166           tt[prop] = TextTrack.prototype[prop];
20167         }
20168       }
20169     }
20170
20171     tt.cues_ = [];
20172     tt.activeCues_ = [];
20173
20174     var cues = new _textTrackCueList2['default'](tt.cues_);
20175     var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
20176     var changed = false;
20177     var timeupdateHandler = Fn.bind(tt, function () {
20178
20179       // Accessing this.activeCues for the side-effects of updating itself
20180       // due to it's nature as a getter function. Do not remove or cues will
20181       // stop updating!
20182       /* eslint-disable no-unused-expressions */
20183       this.activeCues;
20184       /* eslint-enable no-unused-expressions */
20185       if (changed) {
20186         this.trigger('cuechange');
20187         changed = false;
20188       }
20189     });
20190
20191     if (mode !== 'disabled') {
20192       tt.tech_.ready(function () {
20193         tt.tech_.on('timeupdate', timeupdateHandler);
20194       }, true);
20195     }
20196
20197     /**
20198      * @member {boolean} default
20199      *         If this track was set to be on or off by default. Cannot be changed after
20200      *         creation.
20201      *
20202      * @readonly
20203      */
20204     Object.defineProperty(tt, 'default', {
20205       get: function get() {
20206         return default_;
20207       },
20208       set: function set() {}
20209     });
20210
20211     /**
20212      * @member {string} mode
20213      *         Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
20214      *         not be set if setting to an invalid mode.
20215      *
20216      * @fires TextTrack#modechange
20217      */
20218     Object.defineProperty(tt, 'mode', {
20219       get: function get() {
20220         return mode;
20221       },
20222       set: function set(newMode) {
20223         var _this2 = this;
20224
20225         if (!_trackEnums.TextTrackMode[newMode]) {
20226           return;
20227         }
20228         mode = newMode;
20229         if (mode === 'showing') {
20230           this.tech_.ready(function () {
20231             _this2.tech_.on('timeupdate', timeupdateHandler);
20232           }, true);
20233         }
20234         /**
20235          * An event that fires when mode changes on this track. This allows
20236          * the TextTrackList that holds this track to act accordingly.
20237          *
20238          * > Note: This is not part of the spec!
20239          *
20240          * @event TextTrack#modechange
20241          * @type {EventTarget~Event}
20242          */
20243         this.trigger('modechange');
20244       }
20245     });
20246
20247     /**
20248      * @member {TextTrackCueList} cues
20249      *         The text track cue list for this TextTrack.
20250      */
20251     Object.defineProperty(tt, 'cues', {
20252       get: function get() {
20253         if (!this.loaded_) {
20254           return null;
20255         }
20256
20257         return cues;
20258       },
20259       set: function set() {}
20260     });
20261
20262     /**
20263      * @member {TextTrackCueList} activeCues
20264      *         The list text track cues that are currently active for this TextTrack.
20265      */
20266     Object.defineProperty(tt, 'activeCues', {
20267       get: function get() {
20268         if (!this.loaded_) {
20269           return null;
20270         }
20271
20272         // nothing to do
20273         if (this.cues.length === 0) {
20274           return activeCues;
20275         }
20276
20277         var ct = this.tech_.currentTime();
20278         var active = [];
20279
20280         for (var i = 0, l = this.cues.length; i < l; i++) {
20281           var cue = this.cues[i];
20282
20283           if (cue.startTime <= ct && cue.endTime >= ct) {
20284             active.push(cue);
20285           } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
20286             active.push(cue);
20287           }
20288         }
20289
20290         changed = false;
20291
20292         if (active.length !== this.activeCues_.length) {
20293           changed = true;
20294         } else {
20295           for (var _i = 0; _i < active.length; _i++) {
20296             if (this.activeCues_.indexOf(active[_i]) === -1) {
20297               changed = true;
20298             }
20299           }
20300         }
20301
20302         this.activeCues_ = active;
20303         activeCues.setCues_(this.activeCues_);
20304
20305         return activeCues;
20306       },
20307       set: function set() {}
20308     });
20309
20310     if (settings.src) {
20311       tt.src = settings.src;
20312       loadTrack(settings.src, tt);
20313     } else {
20314       tt.loaded_ = true;
20315     }
20316
20317     return _ret = tt, _possibleConstructorReturn(_this, _ret);
20318   }
20319
20320   /**
20321    * Add a cue to the internal list of cues.
20322    *
20323    * @param {TextTrack~Cue} cue
20324    *        The cue to add to our internal list
20325    */
20326
20327
20328   TextTrack.prototype.addCue = function addCue(originalCue) {
20329     var cue = originalCue;
20330
20331     if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
20332       cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
20333
20334       for (var prop in originalCue) {
20335         if (!(prop in cue)) {
20336           cue[prop] = originalCue[prop];
20337         }
20338       }
20339
20340       // make sure that `id` is copied over
20341       cue.id = originalCue.id;
20342       cue.originalCue_ = originalCue;
20343     }
20344
20345     var tracks = this.tech_.textTracks();
20346
20347     if (tracks) {
20348       for (var i = 0; i < tracks.length; i++) {
20349         if (tracks[i] !== this) {
20350           tracks[i].removeCue(cue);
20351         }
20352       }
20353     }
20354
20355     this.cues_.push(cue);
20356     this.cues.setCues_(this.cues_);
20357   };
20358
20359   /**
20360    * Remove a cue from our internal list
20361    *
20362    * @param {TextTrack~Cue} removeCue
20363    *        The cue to remove from our internal list
20364    */
20365
20366
20367   TextTrack.prototype.removeCue = function removeCue(_removeCue) {
20368     var i = this.cues_.length;
20369
20370     while (i--) {
20371       var cue = this.cues_[i];
20372
20373       if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
20374         this.cues_.splice(i, 1);
20375         this.cues.setCues_(this.cues_);
20376         break;
20377       }
20378     }
20379   };
20380
20381   return TextTrack;
20382 }(_track2['default']);
20383
20384 /**
20385  * cuechange - One or more cues in the track have become active or stopped being active.
20386  */
20387
20388
20389 TextTrack.prototype.allowedEvents_ = {
20390   cuechange: 'cuechange'
20391 };
20392
20393 exports['default'] = TextTrack;
20394
20395 },{"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){
20396 'use strict';
20397
20398 exports.__esModule = true;
20399 /**
20400  * @file track-kinds.js
20401  */
20402
20403 /**
20404  * All possible `VideoTrackKind`s
20405  *
20406  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
20407  * @typedef VideoTrack~Kind
20408  * @enum
20409  */
20410 var VideoTrackKind = exports.VideoTrackKind = {
20411   alternative: 'alternative',
20412   captions: 'captions',
20413   main: 'main',
20414   sign: 'sign',
20415   subtitles: 'subtitles',
20416   commentary: 'commentary'
20417 };
20418
20419 /**
20420  * All possible `AudioTrackKind`s
20421  *
20422  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
20423  * @typedef AudioTrack~Kind
20424  * @enum
20425  */
20426 var AudioTrackKind = exports.AudioTrackKind = {
20427   'alternative': 'alternative',
20428   'descriptions': 'descriptions',
20429   'main': 'main',
20430   'main-desc': 'main-desc',
20431   'translation': 'translation',
20432   'commentary': 'commentary'
20433 };
20434
20435 /**
20436  * All possible `TextTrackKind`s
20437  *
20438  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
20439  * @typedef TextTrack~Kind
20440  * @enum
20441  */
20442 var TextTrackKind = exports.TextTrackKind = {
20443   subtitles: 'subtitles',
20444   captions: 'captions',
20445   descriptions: 'descriptions',
20446   chapters: 'chapters',
20447   metadata: 'metadata'
20448 };
20449
20450 /**
20451  * All possible `TextTrackMode`s
20452  *
20453  * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
20454  * @typedef TextTrack~Mode
20455  * @enum
20456  */
20457 var TextTrackMode = exports.TextTrackMode = {
20458   disabled: 'disabled',
20459   hidden: 'hidden',
20460   showing: 'showing'
20461 };
20462
20463 },{}],74:[function(_dereq_,module,exports){
20464 'use strict';
20465
20466 exports.__esModule = true;
20467
20468 var _eventTarget = _dereq_(42);
20469
20470 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20471
20472 var _browser = _dereq_(78);
20473
20474 var browser = _interopRequireWildcard(_browser);
20475
20476 var _document = _dereq_(94);
20477
20478 var _document2 = _interopRequireDefault(_document);
20479
20480 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; } }
20481
20482 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20483
20484 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20485
20486 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; }
20487
20488 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; } /**
20489                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track-list.js
20490                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20491
20492
20493 /**
20494  * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
20495  * {@link VideoTrackList}
20496  *
20497  * @extends EventTarget
20498  */
20499 var TrackList = function (_EventTarget) {
20500   _inherits(TrackList, _EventTarget);
20501
20502   /**
20503    * Create an instance of this class
20504    *
20505    * @param {Track[]} tracks
20506    *        A list of tracks to initialize the list with.
20507    *
20508    * @param {Object} [list]
20509    *        The child object with inheritance done manually for ie8.
20510    *
20511    * @abstract
20512    */
20513   function TrackList() {
20514     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20515
20516     var _ret;
20517
20518     var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
20519
20520     _classCallCheck(this, TrackList);
20521
20522     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20523
20524     if (!list) {
20525       list = _this; // eslint-disable-line
20526       if (browser.IS_IE8) {
20527         list = _document2['default'].createElement('custom');
20528         for (var prop in TrackList.prototype) {
20529           if (prop !== 'constructor') {
20530             list[prop] = TrackList.prototype[prop];
20531           }
20532         }
20533       }
20534     }
20535
20536     list.tracks_ = [];
20537
20538     /**
20539      * @member {number} length
20540      *         The current number of `Track`s in the this Trackist.
20541      */
20542     Object.defineProperty(list, 'length', {
20543       get: function get() {
20544         return this.tracks_.length;
20545       }
20546     });
20547
20548     for (var i = 0; i < tracks.length; i++) {
20549       list.addTrack_(tracks[i]);
20550     }
20551
20552     // must return the object, as for ie8 it will not be this
20553     // but a reference to a document object
20554     return _ret = list, _possibleConstructorReturn(_this, _ret);
20555   }
20556
20557   /**
20558    * Add a {@link Track} to the `TrackList`
20559    *
20560    * @param {Track} track
20561    *        The audio, video, or text track to add to the list.
20562    *
20563    * @fires TrackList#addtrack
20564    * @private
20565    */
20566
20567
20568   TrackList.prototype.addTrack_ = function addTrack_(track) {
20569     var index = this.tracks_.length;
20570
20571     if (!('' + index in this)) {
20572       Object.defineProperty(this, index, {
20573         get: function get() {
20574           return this.tracks_[index];
20575         }
20576       });
20577     }
20578
20579     // Do not add duplicate tracks
20580     if (this.tracks_.indexOf(track) === -1) {
20581       this.tracks_.push(track);
20582       /**
20583        * Triggered when a track is added to a track list.
20584        *
20585        * @event TrackList#addtrack
20586        * @type {EventTarget~Event}
20587        * @property {Track} track
20588        *           A reference to track that was added.
20589        */
20590       this.trigger({
20591         track: track,
20592         type: 'addtrack'
20593       });
20594     }
20595   };
20596
20597   /**
20598    * Remove a {@link Track} from the `TrackList`
20599    *
20600    * @param {Track} track
20601    *        The audio, video, or text track to remove from the list.
20602    *
20603    * @fires TrackList#removetrack
20604    * @private
20605    */
20606
20607
20608   TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
20609     var track = void 0;
20610
20611     for (var i = 0, l = this.length; i < l; i++) {
20612       if (this[i] === rtrack) {
20613         track = this[i];
20614         if (track.off) {
20615           track.off();
20616         }
20617
20618         this.tracks_.splice(i, 1);
20619
20620         break;
20621       }
20622     }
20623
20624     if (!track) {
20625       return;
20626     }
20627
20628     /**
20629      * Triggered when a track is removed from track list.
20630      *
20631      * @event TrackList#removetrack
20632      * @type {EventTarget~Event}
20633      * @property {Track} track
20634      *           A reference to track that was removed.
20635      */
20636     this.trigger({
20637       track: track,
20638       type: 'removetrack'
20639     });
20640   };
20641
20642   /**
20643    * Get a Track from the TrackList by a tracks id
20644    *
20645    * @param {String} id - the id of the track to get
20646    * @method getTrackById
20647    * @return {Track}
20648    * @private
20649    */
20650
20651
20652   TrackList.prototype.getTrackById = function getTrackById(id) {
20653     var result = null;
20654
20655     for (var i = 0, l = this.length; i < l; i++) {
20656       var track = this[i];
20657
20658       if (track.id === id) {
20659         result = track;
20660         break;
20661       }
20662     }
20663
20664     return result;
20665   };
20666
20667   return TrackList;
20668 }(_eventTarget2['default']);
20669
20670 /**
20671  * Triggered when a different track is selected/enabled.
20672  *
20673  * @event TrackList#change
20674  * @type {EventTarget~Event}
20675  */
20676
20677 /**
20678  * Events that can be called with on + eventName. See {@link EventHandler}.
20679  *
20680  * @property {Object} TrackList#allowedEvents_
20681  * @private
20682  */
20683
20684
20685 TrackList.prototype.allowedEvents_ = {
20686   change: 'change',
20687   addtrack: 'addtrack',
20688   removetrack: 'removetrack'
20689 };
20690
20691 // emulate attribute EventHandler support to allow for feature detection
20692 for (var event in TrackList.prototype.allowedEvents_) {
20693   TrackList.prototype['on' + event] = null;
20694 }
20695
20696 exports['default'] = TrackList;
20697
20698 },{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){
20699 'use strict';
20700
20701 exports.__esModule = true;
20702
20703 var _browser = _dereq_(78);
20704
20705 var browser = _interopRequireWildcard(_browser);
20706
20707 var _document = _dereq_(94);
20708
20709 var _document2 = _interopRequireDefault(_document);
20710
20711 var _guid = _dereq_(85);
20712
20713 var Guid = _interopRequireWildcard(_guid);
20714
20715 var _eventTarget = _dereq_(42);
20716
20717 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20718
20719 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20720
20721 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; } }
20722
20723 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20724
20725 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; }
20726
20727 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; } /**
20728                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file track.js
20729                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20730
20731
20732 /**
20733  * A Track class that contains all of the common functionality for {@link AudioTrack},
20734  * {@link VideoTrack}, and {@link TextTrack}.
20735  *
20736  * > Note: This class should not be used directly
20737  *
20738  * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
20739  * @extends EventTarget
20740  * @abstract
20741  */
20742 var Track = function (_EventTarget) {
20743   _inherits(Track, _EventTarget);
20744
20745   /**
20746    * Create an instance of this class.
20747    *
20748    * @param {Object} [options={}]
20749    *        Object of option names and values
20750    *
20751    * @param {string} [options.kind='']
20752    *        A valid kind for the track type you are creating.
20753    *
20754    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20755    *        A unique id for this AudioTrack.
20756    *
20757    * @param {string} [options.label='']
20758    *        The menu label for this track.
20759    *
20760    * @param {string} [options.language='']
20761    *        A valid two character language code.
20762    *
20763    * @abstract
20764    */
20765   function Track() {
20766     var _ret;
20767
20768     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20769
20770     _classCallCheck(this, Track);
20771
20772     var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20773
20774     var track = _this; // eslint-disable-line
20775
20776     if (browser.IS_IE8) {
20777       track = _document2['default'].createElement('custom');
20778       for (var prop in Track.prototype) {
20779         if (prop !== 'constructor') {
20780           track[prop] = Track.prototype[prop];
20781         }
20782       }
20783     }
20784
20785     var trackProps = {
20786       id: options.id || 'vjs_track_' + Guid.newGUID(),
20787       kind: options.kind || '',
20788       label: options.label || '',
20789       language: options.language || ''
20790     };
20791
20792     /**
20793      * @member {string} id
20794      *         The id of this track. Cannot be changed after creation.
20795      *
20796      * @readonly
20797      */
20798
20799     /**
20800      * @member {string} kind
20801      *         The kind of track that this is. Cannot be changed after creation.
20802      *
20803      * @readonly
20804      */
20805
20806     /**
20807      * @member {string} label
20808      *         The label of this track. Cannot be changed after creation.
20809      *
20810      * @readonly
20811      */
20812
20813     /**
20814      * @member {string} language
20815      *         The two letter language code for this track. Cannot be changed after
20816      *         creation.
20817      *
20818      * @readonly
20819      */
20820
20821     var _loop = function _loop(key) {
20822       Object.defineProperty(track, key, {
20823         get: function get() {
20824           return trackProps[key];
20825         },
20826         set: function set() {}
20827       });
20828     };
20829
20830     for (var key in trackProps) {
20831       _loop(key);
20832     }
20833
20834     return _ret = track, _possibleConstructorReturn(_this, _ret);
20835   }
20836
20837   return Track;
20838 }(_eventTarget2['default']);
20839
20840 exports['default'] = Track;
20841
20842 },{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){
20843 'use strict';
20844
20845 exports.__esModule = true;
20846
20847 var _trackList = _dereq_(74);
20848
20849 var _trackList2 = _interopRequireDefault(_trackList);
20850
20851 var _browser = _dereq_(78);
20852
20853 var browser = _interopRequireWildcard(_browser);
20854
20855 var _document = _dereq_(94);
20856
20857 var _document2 = _interopRequireDefault(_document);
20858
20859 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; } }
20860
20861 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20862
20863 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20864
20865 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; }
20866
20867 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; } /**
20868                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * @file video-track-list.js
20869                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
20870
20871
20872 /**
20873  * Un-select all other {@link VideoTrack}s that are selected.
20874  *
20875  * @param {VideoTrackList} list
20876  *        list to work on
20877  *
20878  * @param {VideoTrack} track
20879  *        The track to skip
20880  *
20881  * @private
20882  */
20883 var disableOthers = function disableOthers(list, track) {
20884   for (var i = 0; i < list.length; i++) {
20885     if (track.id === list[i].id) {
20886       continue;
20887     }
20888     // another video track is enabled, disable it
20889     list[i].selected = false;
20890   }
20891 };
20892
20893 /**
20894  * The current list of {@link VideoTrack} for a video.
20895  *
20896  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
20897  * @extends TrackList
20898  */
20899
20900 var VideoTrackList = function (_TrackList) {
20901   _inherits(VideoTrackList, _TrackList);
20902
20903   /**
20904    * Create an instance of this class.
20905    *
20906    * @param {VideoTrack[]} [tracks=[]]
20907    *        A list of `VideoTrack` to instantiate the list with.
20908    */
20909   function VideoTrackList() {
20910     var _this, _ret;
20911
20912     var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20913
20914     _classCallCheck(this, VideoTrackList);
20915
20916     var list = void 0;
20917
20918     // make sure only 1 track is enabled
20919     // sorted from last index to first index
20920     for (var i = tracks.length - 1; i >= 0; i--) {
20921       if (tracks[i].selected) {
20922         disableOthers(tracks, tracks[i]);
20923         break;
20924       }
20925     }
20926
20927     // IE8 forces us to implement inheritance ourselves
20928     // as it does not support Object.defineProperty properly
20929     if (browser.IS_IE8) {
20930       list = _document2['default'].createElement('custom');
20931       for (var prop in _trackList2['default'].prototype) {
20932         if (prop !== 'constructor') {
20933           list[prop] = _trackList2['default'].prototype[prop];
20934         }
20935       }
20936       for (var _prop in VideoTrackList.prototype) {
20937         if (_prop !== 'constructor') {
20938           list[_prop] = VideoTrackList.prototype[_prop];
20939         }
20940       }
20941     }
20942
20943     list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
20944     list.changing_ = false;
20945
20946     /**
20947      * @member {number} VideoTrackList#selectedIndex
20948      *         The current index of the selected {@link VideoTrack`}.
20949      */
20950     Object.defineProperty(list, 'selectedIndex', {
20951       get: function get() {
20952         for (var _i = 0; _i < this.length; _i++) {
20953           if (this[_i].selected) {
20954             return _i;
20955           }
20956         }
20957         return -1;
20958       },
20959       set: function set() {}
20960     });
20961
20962     return _ret = list, _possibleConstructorReturn(_this, _ret);
20963   }
20964
20965   /**
20966    * Add a {@link VideoTrack} to the `VideoTrackList`.
20967    *
20968    * @param {VideoTrack} track
20969    *        The VideoTrack to add to the list
20970    *
20971    * @fires TrackList#addtrack
20972    * @private
20973    */
20974
20975
20976   VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
20977     var _this2 = this;
20978
20979     if (track.selected) {
20980       disableOthers(this, track);
20981     }
20982
20983     _TrackList.prototype.addTrack_.call(this, track);
20984     // native tracks don't have this
20985     if (!track.addEventListener) {
20986       return;
20987     }
20988
20989     /**
20990      * @listens VideoTrack#selectedchange
20991      * @fires TrackList#change
20992      */
20993     track.addEventListener('selectedchange', function () {
20994       if (_this2.changing_) {
20995         return;
20996       }
20997       _this2.changing_ = true;
20998       disableOthers(_this2, track);
20999       _this2.changing_ = false;
21000       _this2.trigger('change');
21001     });
21002   };
21003
21004   /**
21005    * Add a {@link VideoTrack} to the `VideoTrackList`.
21006    *
21007    * @param {VideoTrack} track
21008    *        The VideoTrack to add to the list
21009    *
21010    * @fires TrackList#addtrack
21011    */
21012
21013
21014   VideoTrackList.prototype.addTrack = function addTrack(track) {
21015     this.addTrack_(track);
21016   };
21017
21018   /**
21019    * Remove a {@link VideoTrack} to the `VideoTrackList`.
21020    *
21021    * @param {VideoTrack} track
21022    *        The VideoTrack to remove from the list.
21023    *
21024    * @fires TrackList#removetrack
21025    */
21026
21027
21028   VideoTrackList.prototype.removeTrack = function removeTrack(track) {
21029     _TrackList.prototype.removeTrack_.call(this, track);
21030   };
21031
21032   return VideoTrackList;
21033 }(_trackList2['default']);
21034
21035 exports['default'] = VideoTrackList;
21036
21037 },{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){
21038 'use strict';
21039
21040 exports.__esModule = true;
21041
21042 var _trackEnums = _dereq_(73);
21043
21044 var _track = _dereq_(75);
21045
21046 var _track2 = _interopRequireDefault(_track);
21047
21048 var _mergeOptions = _dereq_(87);
21049
21050 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
21051
21052 var _browser = _dereq_(78);
21053
21054 var browser = _interopRequireWildcard(_browser);
21055
21056 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; } }
21057
21058 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21059
21060 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21061
21062 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; }
21063
21064 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; }
21065
21066 /**
21067  * A representation of a single `VideoTrack`.
21068  *
21069  * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
21070  * @extends Track
21071  */
21072 var VideoTrack = function (_Track) {
21073   _inherits(VideoTrack, _Track);
21074
21075   /**
21076    * Create an instance of this class.
21077    *
21078    * @param {Object} [options={}]
21079    *        Object of option names and values
21080    *
21081    * @param {string} [options.kind='']
21082    *        A valid {@link VideoTrack~Kind}
21083    *
21084    * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
21085    *        A unique id for this AudioTrack.
21086    *
21087    * @param {string} [options.label='']
21088    *        The menu label for this track.
21089    *
21090    * @param {string} [options.language='']
21091    *        A valid two character language code.
21092    *
21093    * @param {boolean} [options.selected]
21094    *        If this track is the one that is currently playing.
21095    */
21096   function VideoTrack() {
21097     var _this, _ret;
21098
21099     var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21100
21101     _classCallCheck(this, VideoTrack);
21102
21103     var settings = (0, _mergeOptions2['default'])(options, {
21104       kind: _trackEnums.VideoTrackKind[options.kind] || ''
21105     });
21106
21107     // on IE8 this will be a document element
21108     // for every other browser this will be a normal object
21109     var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
21110     var selected = false;
21111
21112     if (browser.IS_IE8) {
21113       for (var prop in VideoTrack.prototype) {
21114         if (prop !== 'constructor') {
21115           track[prop] = VideoTrack.prototype[prop];
21116         }
21117       }
21118     }
21119
21120     /**
21121      * @member {boolean} selected
21122      *         If this `VideoTrack` is selected or not. When setting this will
21123      *         fire {@link VideoTrack#selectedchange} if the state of selected changed.
21124      *
21125      * @fires VideoTrack#selectedchange
21126      */
21127     Object.defineProperty(track, 'selected', {
21128       get: function get() {
21129         return selected;
21130       },
21131       set: function set(newSelected) {
21132         // an invalid or unchanged value
21133         if (typeof newSelected !== 'boolean' || newSelected === selected) {
21134           return;
21135         }
21136         selected = newSelected;
21137
21138         /**
21139          * An event that fires when selected changes on this track. This allows
21140          * the VideoTrackList that holds this track to act accordingly.
21141          *
21142          * > Note: This is not part of the spec! Native tracks will do
21143          *         this internally without an event.
21144          *
21145          * @event VideoTrack#selectedchange
21146          * @type {EventTarget~Event}
21147          */
21148         this.trigger('selectedchange');
21149       }
21150     });
21151
21152     // if the user sets this track to selected then
21153     // set selected to that true value otherwise
21154     // we keep it false
21155     if (settings.selected) {
21156       track.selected = settings.selected;
21157     }
21158
21159     return _ret = track, _possibleConstructorReturn(_this, _ret);
21160   }
21161
21162   return VideoTrack;
21163 }(_track2['default']);
21164
21165 exports['default'] = VideoTrack;
21166
21167 },{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){
21168 'use strict';
21169
21170 exports.__esModule = true;
21171 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;
21172
21173 var _dom = _dereq_(81);
21174
21175 var Dom = _interopRequireWildcard(_dom);
21176
21177 var _window = _dereq_(95);
21178
21179 var _window2 = _interopRequireDefault(_window);
21180
21181 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21182
21183 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; } }
21184
21185 /**
21186  * @file browser.js
21187  * @module browser
21188  */
21189 var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
21190 var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
21191 var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
21192
21193 /*
21194  * Device is an iPhone
21195  *
21196  * @type {Boolean}
21197  * @constant
21198  * @private
21199  */
21200 var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
21201
21202 // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
21203 // to identify iPhones, we need to exclude iPads.
21204 // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
21205 var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
21206 var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
21207 var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
21208
21209 var IOS_VERSION = exports.IOS_VERSION = function () {
21210   var match = USER_AGENT.match(/OS (\d+)_/i);
21211
21212   if (match && match[1]) {
21213     return match[1];
21214   }
21215   return null;
21216 }();
21217
21218 var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
21219 var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
21220   // This matches Android Major.Minor.Patch versions
21221   // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
21222   var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
21223
21224   if (!match) {
21225     return null;
21226   }
21227
21228   var major = match[1] && parseFloat(match[1]);
21229   var minor = match[2] && parseFloat(match[2]);
21230
21231   if (major && minor) {
21232     return parseFloat(match[1] + '.' + match[2]);
21233   } else if (major) {
21234     return major;
21235   }
21236   return null;
21237 }();
21238
21239 // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
21240 var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
21241 var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
21242
21243 var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
21244 var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
21245 var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
21246 var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
21247 var IE_VERSION = exports.IE_VERSION = function () {
21248   var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT);
21249   var version = result && parseFloat(result[1]);
21250
21251   if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) {
21252     // IE 11 has a different user agent string than other IE versions
21253     version = 11.0;
21254   }
21255
21256   return version;
21257 }();
21258
21259 var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
21260 var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
21261
21262 var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
21263
21264 var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
21265
21266 },{"81":81,"95":95}],79:[function(_dereq_,module,exports){
21267 'use strict';
21268
21269 exports.__esModule = true;
21270 exports.bufferedPercent = bufferedPercent;
21271
21272 var _timeRanges = _dereq_(90);
21273
21274 /**
21275  * Compute the percentage of the media that has been buffered.
21276  *
21277  * @param {TimeRange} buffered
21278  *        The current `TimeRange` object representing buffered time ranges
21279  *
21280  * @param {number} duration
21281  *        Total duration of the media
21282  *
21283  * @return {number}
21284  *         Percent buffered of the total duration in decimal form.
21285  */
21286 function bufferedPercent(buffered, duration) {
21287   var bufferedDuration = 0;
21288   var start = void 0;
21289   var end = void 0;
21290
21291   if (!duration) {
21292     return 0;
21293   }
21294
21295   if (!buffered || !buffered.length) {
21296     buffered = (0, _timeRanges.createTimeRange)(0, 0);
21297   }
21298
21299   for (var i = 0; i < buffered.length; i++) {
21300     start = buffered.start(i);
21301     end = buffered.end(i);
21302
21303     // buffered end can be bigger than duration by a very small fraction
21304     if (end > duration) {
21305       end = duration;
21306     }
21307
21308     bufferedDuration += end - start;
21309   }
21310
21311   return bufferedDuration / duration;
21312 } /**
21313    * @file buffer.js
21314    * @module buffer
21315    */
21316
21317 },{"90":90}],80:[function(_dereq_,module,exports){
21318 'use strict';
21319
21320 exports.__esModule = true;
21321 exports['default'] = computedStyle;
21322
21323 var _window = _dereq_(95);
21324
21325 var _window2 = _interopRequireDefault(_window);
21326
21327 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21328
21329 /**
21330  * A safe getComputedStyle with an IE8 fallback.
21331  *
21332  * This is needed because in Firefox, if the player is loaded in an iframe with
21333  * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
21334  * make sure  that the player doesn't break in these cases.
21335  *
21336  * @param {Element} el
21337  *        The element you want the computed style of
21338  *
21339  * @param {string} prop
21340  *        The property name you want
21341  *
21342  * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
21343  */
21344 function computedStyle(el, prop) {
21345   if (!el || !prop) {
21346     return '';
21347   }
21348
21349   if (typeof _window2['default'].getComputedStyle === 'function') {
21350     var cs = _window2['default'].getComputedStyle(el);
21351
21352     return cs ? cs[prop] : '';
21353   }
21354
21355   return el.currentStyle[prop] || '';
21356 } /**
21357    * @file computed-style.js
21358    * @module computed-style
21359    */
21360
21361 },{"95":95}],81:[function(_dereq_,module,exports){
21362 'use strict';
21363
21364 exports.__esModule = true;
21365 exports.$$ = exports.$ = undefined;
21366
21367 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 ', '.']);
21368
21369 exports.isReal = isReal;
21370 exports.isEl = isEl;
21371 exports.getEl = getEl;
21372 exports.createEl = createEl;
21373 exports.textContent = textContent;
21374 exports.insertElFirst = insertElFirst;
21375 exports.getElData = getElData;
21376 exports.hasElData = hasElData;
21377 exports.removeElData = removeElData;
21378 exports.hasElClass = hasElClass;
21379 exports.addElClass = addElClass;
21380 exports.removeElClass = removeElClass;
21381 exports.toggleElClass = toggleElClass;
21382 exports.setElAttributes = setElAttributes;
21383 exports.getElAttributes = getElAttributes;
21384 exports.getAttribute = getAttribute;
21385 exports.setAttribute = setAttribute;
21386 exports.removeAttribute = removeAttribute;
21387 exports.blockTextSelection = blockTextSelection;
21388 exports.unblockTextSelection = unblockTextSelection;
21389 exports.findElPosition = findElPosition;
21390 exports.getPointerPosition = getPointerPosition;
21391 exports.isTextNode = isTextNode;
21392 exports.emptyEl = emptyEl;
21393 exports.normalizeContent = normalizeContent;
21394 exports.appendContent = appendContent;
21395 exports.insertContent = insertContent;
21396
21397 var _document = _dereq_(94);
21398
21399 var _document2 = _interopRequireDefault(_document);
21400
21401 var _window = _dereq_(95);
21402
21403 var _window2 = _interopRequireDefault(_window);
21404
21405 var _guid = _dereq_(85);
21406
21407 var Guid = _interopRequireWildcard(_guid);
21408
21409 var _log = _dereq_(86);
21410
21411 var _log2 = _interopRequireDefault(_log);
21412
21413 var _tsml = _dereq_(98);
21414
21415 var _tsml2 = _interopRequireDefault(_tsml);
21416
21417 var _obj = _dereq_(88);
21418
21419 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; } }
21420
21421 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21422
21423 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
21424                                                                                            * @file dom.js
21425                                                                                            * @module dom
21426                                                                                            */
21427
21428
21429 /**
21430  * Detect if a value is a string with any non-whitespace characters.
21431  *
21432  * @param {string} str
21433  *        The string to check
21434  *
21435  * @return {boolean}
21436  *         - True if the string is non-blank
21437  *         - False otherwise
21438  *
21439  */
21440 function isNonBlankString(str) {
21441   return typeof str === 'string' && /\S/.test(str);
21442 }
21443
21444 /**
21445  * Throws an error if the passed string has whitespace. This is used by
21446  * class methods to be relatively consistent with the classList API.
21447  *
21448  * @param {string} str
21449  *         The string to check for whitespace.
21450  *
21451  * @throws {Error}
21452  *         Throws an error if there is whitespace in the string.
21453  *
21454  */
21455 function throwIfWhitespace(str) {
21456   if (/\s/.test(str)) {
21457     throw new Error('class has illegal whitespace characters');
21458   }
21459 }
21460
21461 /**
21462  * Produce a regular expression for matching a className within an elements className.
21463  *
21464  * @param {string} className
21465  *         The className to generate the RegExp for.
21466  *
21467  * @return {RegExp}
21468  *         The RegExp that will check for a specific `className` in an elements
21469  *         className.
21470  */
21471 function classRegExp(className) {
21472   return new RegExp('(^|\\s)' + className + '($|\\s)');
21473 }
21474
21475 /**
21476  * Whether the current DOM interface appears to be real.
21477  *
21478  * @return {Boolean}
21479  */
21480 function isReal() {
21481   return (
21482
21483     // Both document and window will never be undefined thanks to `global`.
21484     _document2['default'] === _window2['default'].document &&
21485
21486     // In IE < 9, DOM methods return "object" as their type, so all we can
21487     // confidently check is that it exists.
21488     typeof _document2['default'].createElement !== 'undefined'
21489   );
21490 }
21491
21492 /**
21493  * Determines, via duck typing, whether or not a value is a DOM element.
21494  *
21495  * @param {Mixed} value
21496  *        The thing to check
21497  *
21498  * @return {boolean}
21499  *         - True if it is a DOM element
21500  *         - False otherwise
21501  */
21502 function isEl(value) {
21503   return (0, _obj.isObject)(value) && value.nodeType === 1;
21504 }
21505
21506 /**
21507  * Creates functions to query the DOM using a given method.
21508  *
21509  * @param {string} method
21510  *         The method to create the query with.
21511  *
21512  * @return {Function}
21513  *         The query method
21514  */
21515 function createQuerier(method) {
21516   return function (selector, context) {
21517     if (!isNonBlankString(selector)) {
21518       return _document2['default'][method](null);
21519     }
21520     if (isNonBlankString(context)) {
21521       context = _document2['default'].querySelector(context);
21522     }
21523
21524     var ctx = isEl(context) ? context : _document2['default'];
21525
21526     return ctx[method] && ctx[method](selector);
21527   };
21528 }
21529
21530 /**
21531  * Shorthand for document.getElementById()
21532  * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
21533  *
21534  * @param {string} id
21535  *         The id of the element to get
21536  *
21537  * @return {Element|null}
21538  *         Element with supplied ID or null if there wasn't one.
21539  */
21540 function getEl(id) {
21541   if (id.indexOf('#') === 0) {
21542     id = id.slice(1);
21543   }
21544
21545   return _document2['default'].getElementById(id);
21546 }
21547
21548 /**
21549  * Creates an element and applies properties.
21550  *
21551  * @param {string} [tagName='div']
21552  *         Name of tag to be created.
21553  *
21554  * @param {Object} [properties={}]
21555  *         Element properties to be applied.
21556  *
21557  * @param {Object} [attributes={}]
21558  *         Element attributes to be applied.
21559  *
21560  * @param {String|Element|TextNode|Array|Function} [content]
21561  *         Contents for the element (see: {@link dom:normalizeContent})
21562  *
21563  * @return {Element}
21564  *         The element that was created.
21565  */
21566 function createEl() {
21567   var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
21568   var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
21569   var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
21570   var content = arguments[3];
21571
21572   var el = _document2['default'].createElement(tagName);
21573
21574   Object.getOwnPropertyNames(properties).forEach(function (propName) {
21575     var val = properties[propName];
21576
21577     // See #2176
21578     // We originally were accepting both properties and attributes in the
21579     // same object, but that doesn't work so well.
21580     if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
21581       _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
21582       el.setAttribute(propName, val);
21583
21584       // Handle textContent since it's not supported everywhere and we have a
21585       // method for it.
21586     } else if (propName === 'textContent') {
21587       textContent(el, val);
21588     } else {
21589       el[propName] = val;
21590     }
21591   });
21592
21593   Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21594     el.setAttribute(attrName, attributes[attrName]);
21595   });
21596
21597   if (content) {
21598     appendContent(el, content);
21599   }
21600
21601   return el;
21602 }
21603
21604 /**
21605  * Injects text into an element, replacing any existing contents entirely.
21606  *
21607  * @param {Element} el
21608  *        The element to add text content into
21609  *
21610  * @param {string} text
21611  *        The text content to add.
21612  *
21613  * @return {Element}
21614  *         The element with added text content.
21615  */
21616 function textContent(el, text) {
21617   if (typeof el.textContent === 'undefined') {
21618     el.innerText = text;
21619   } else {
21620     el.textContent = text;
21621   }
21622   return el;
21623 }
21624
21625 /**
21626  * Insert an element as the first child node of another
21627  *
21628  * @param {Element} child
21629  *        Element to insert
21630  *
21631  * @param {Element} parent
21632  *        Element to insert child into
21633  *
21634  */
21635 function insertElFirst(child, parent) {
21636   if (parent.firstChild) {
21637     parent.insertBefore(child, parent.firstChild);
21638   } else {
21639     parent.appendChild(child);
21640   }
21641 }
21642
21643 /**
21644  * Element Data Store. Allows for binding data to an element without putting it directly on the element.
21645  * Ex. Event listeners are stored here.
21646  * (also from jsninja.com, slightly modified and updated for closure compiler)
21647  *
21648  * @type {Object}
21649  * @private
21650  */
21651 var elData = {};
21652
21653 /*
21654  * Unique attribute name to store an element's guid in
21655  *
21656  * @type {string}
21657  * @constant
21658  * @private
21659  */
21660 var elIdAttr = 'vdata' + new Date().getTime();
21661
21662 /**
21663  * Returns the cache object where data for an element is stored
21664  *
21665  * @param {Element} el
21666  *        Element to store data for.
21667  *
21668  * @return {Object}
21669  *         The cache object for that el that was passed in.
21670  */
21671 function getElData(el) {
21672   var id = el[elIdAttr];
21673
21674   if (!id) {
21675     id = el[elIdAttr] = Guid.newGUID();
21676   }
21677
21678   if (!elData[id]) {
21679     elData[id] = {};
21680   }
21681
21682   return elData[id];
21683 }
21684
21685 /**
21686  * Returns whether or not an element has cached data
21687  *
21688  * @param {Element} el
21689  *        Check if this element has cached data.
21690  *
21691  * @return {boolean}
21692  *         - True if the DOM element has cached data.
21693  *         - False otherwise.
21694  */
21695 function hasElData(el) {
21696   var id = el[elIdAttr];
21697
21698   if (!id) {
21699     return false;
21700   }
21701
21702   return !!Object.getOwnPropertyNames(elData[id]).length;
21703 }
21704
21705 /**
21706  * Delete data for the element from the cache and the guid attr from getElementById
21707  *
21708  * @param {Element} el
21709  *        Remove cached data for this element.
21710  */
21711 function removeElData(el) {
21712   var id = el[elIdAttr];
21713
21714   if (!id) {
21715     return;
21716   }
21717
21718   // Remove all stored data
21719   delete elData[id];
21720
21721   // Remove the elIdAttr property from the DOM node
21722   try {
21723     delete el[elIdAttr];
21724   } catch (e) {
21725     if (el.removeAttribute) {
21726       el.removeAttribute(elIdAttr);
21727     } else {
21728       // IE doesn't appear to support removeAttribute on the document element
21729       el[elIdAttr] = null;
21730     }
21731   }
21732 }
21733
21734 /**
21735  * Check if an element has a CSS class
21736  *
21737  * @param {Element} element
21738  *        Element to check
21739  *
21740  * @param {string} classToCheck
21741  *        Class name to check for
21742  *
21743  * @return {boolean}
21744  *         - True if the element had the class
21745  *         - False otherwise.
21746  *
21747  * @throws {Error}
21748  *         Throws an error if `classToCheck` has white space.
21749  */
21750 function hasElClass(element, classToCheck) {
21751   throwIfWhitespace(classToCheck);
21752   if (element.classList) {
21753     return element.classList.contains(classToCheck);
21754   }
21755   return classRegExp(classToCheck).test(element.className);
21756 }
21757
21758 /**
21759  * Add a CSS class name to an element
21760  *
21761  * @param {Element} element
21762  *        Element to add class name to.
21763  *
21764  * @param {string} classToAdd
21765  *        Class name to add.
21766  *
21767  * @return {Element}
21768  *         The dom element with the added class name.
21769  */
21770 function addElClass(element, classToAdd) {
21771   if (element.classList) {
21772     element.classList.add(classToAdd);
21773
21774     // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
21775     // in the case of classList not being supported.
21776   } else if (!hasElClass(element, classToAdd)) {
21777     element.className = (element.className + ' ' + classToAdd).trim();
21778   }
21779
21780   return element;
21781 }
21782
21783 /**
21784  * Remove a CSS class name from an element
21785  *
21786  * @param {Element} element
21787  *        Element to remove a class name from.
21788  *
21789  * @param {string} classToRemove
21790  *        Class name to remove
21791  *
21792  * @return {Element}
21793  *         The dom element with class name removed.
21794  */
21795 function removeElClass(element, classToRemove) {
21796   if (element.classList) {
21797     element.classList.remove(classToRemove);
21798   } else {
21799     throwIfWhitespace(classToRemove);
21800     element.className = element.className.split(/\s+/).filter(function (c) {
21801       return c !== classToRemove;
21802     }).join(' ');
21803   }
21804
21805   return element;
21806 }
21807
21808 /**
21809  * The callback definition for toggleElClass.
21810  *
21811  * @callback Dom~PredicateCallback
21812  * @param {Element} element
21813  *        The DOM element of the Component.
21814  *
21815  * @param {string} classToToggle
21816  *        The `className` that wants to be toggled
21817  *
21818  * @return {boolean|undefined}
21819  *         - If true the `classToToggle` will get added to `element`.
21820  *         - If false the `classToToggle` will get removed from `element`.
21821  *         - If undefined this callback will be ignored
21822  */
21823
21824 /**
21825  * Adds or removes a CSS class name on an element depending on an optional
21826  * condition or the presence/absence of the class name.
21827  *
21828  * @param {Element} element
21829  *        The element to toggle a class name on.
21830  *
21831  * @param {string} classToToggle
21832  *        The class that should be toggled
21833  *
21834  * @param {boolean|PredicateCallback} [predicate]
21835  *        See the return value for {@link Dom~PredicateCallback}
21836  *
21837  * @return {Element}
21838  *         The element with a class that has been toggled.
21839  */
21840 function toggleElClass(element, classToToggle, predicate) {
21841
21842   // This CANNOT use `classList` internally because IE does not support the
21843   // second parameter to the `classList.toggle()` method! Which is fine because
21844   // `classList` will be used by the add/remove functions.
21845   var has = hasElClass(element, classToToggle);
21846
21847   if (typeof predicate === 'function') {
21848     predicate = predicate(element, classToToggle);
21849   }
21850
21851   if (typeof predicate !== 'boolean') {
21852     predicate = !has;
21853   }
21854
21855   // If the necessary class operation matches the current state of the
21856   // element, no action is required.
21857   if (predicate === has) {
21858     return;
21859   }
21860
21861   if (predicate) {
21862     addElClass(element, classToToggle);
21863   } else {
21864     removeElClass(element, classToToggle);
21865   }
21866
21867   return element;
21868 }
21869
21870 /**
21871  * Apply attributes to an HTML element.
21872  *
21873  * @param {Element} el
21874  *        Element to add attributes to.
21875  *
21876  * @param {Object} [attributes]
21877  *        Attributes to be applied.
21878  */
21879 function setElAttributes(el, attributes) {
21880   Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21881     var attrValue = attributes[attrName];
21882
21883     if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
21884       el.removeAttribute(attrName);
21885     } else {
21886       el.setAttribute(attrName, attrValue === true ? '' : attrValue);
21887     }
21888   });
21889 }
21890
21891 /**
21892  * Get an element's attribute values, as defined on the HTML tag
21893  * Attributes are not the same as properties. They're defined on the tag
21894  * or with setAttribute (which shouldn't be used with HTML)
21895  * This will return true or false for boolean attributes.
21896  *
21897  * @param {Element} tag
21898  *        Element from which to get tag attributes.
21899  *
21900  * @return {Object}
21901  *         All attributes of the element.
21902  */
21903 function getElAttributes(tag) {
21904   var obj = {};
21905
21906   // known boolean attributes
21907   // we can check for matching boolean properties, but older browsers
21908   // won't know about HTML5 boolean attributes that we still read from
21909   var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
21910
21911   if (tag && tag.attributes && tag.attributes.length > 0) {
21912     var attrs = tag.attributes;
21913
21914     for (var i = attrs.length - 1; i >= 0; i--) {
21915       var attrName = attrs[i].name;
21916       var attrVal = attrs[i].value;
21917
21918       // check for known booleans
21919       // the matching element property will return a value for typeof
21920       if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
21921         // the value of an included boolean attribute is typically an empty
21922         // string ('') which would equal false if we just check for a false value.
21923         // we also don't want support bad code like autoplay='false'
21924         attrVal = attrVal !== null ? true : false;
21925       }
21926
21927       obj[attrName] = attrVal;
21928     }
21929   }
21930
21931   return obj;
21932 }
21933
21934 /**
21935  * Get the value of an element's attribute
21936  *
21937  * @param {Element} el
21938  *        A DOM element
21939  *
21940  * @param {string} attribute
21941  *        Attribute to get the value of
21942  *
21943  * @return {string}
21944  *         value of the attribute
21945  */
21946 function getAttribute(el, attribute) {
21947   return el.getAttribute(attribute);
21948 }
21949
21950 /**
21951  * Set the value of an element's attribute
21952  *
21953  * @param {Element} el
21954  *        A DOM element
21955  *
21956  * @param {string} attribute
21957  *        Attribute to set
21958  *
21959  * @param {string} value
21960  *        Value to set the attribute to
21961  */
21962 function setAttribute(el, attribute, value) {
21963   el.setAttribute(attribute, value);
21964 }
21965
21966 /**
21967  * Remove an element's attribute
21968  *
21969  * @param {Element} el
21970  *        A DOM element
21971  *
21972  * @param {string} attribute
21973  *        Attribute to remove
21974  */
21975 function removeAttribute(el, attribute) {
21976   el.removeAttribute(attribute);
21977 }
21978
21979 /**
21980  * Attempt to block the ability to select text while dragging controls
21981  */
21982 function blockTextSelection() {
21983   _document2['default'].body.focus();
21984   _document2['default'].onselectstart = function () {
21985     return false;
21986   };
21987 }
21988
21989 /**
21990  * Turn off text selection blocking
21991  */
21992 function unblockTextSelection() {
21993   _document2['default'].onselectstart = function () {
21994     return true;
21995   };
21996 }
21997
21998 /**
21999  * The postion of a DOM element on the page.
22000  *
22001  * @typedef {Object} Dom~Position
22002  *
22003  * @property {number} left
22004  *           Pixels to the left
22005  *
22006  * @property {number} top
22007  *           Pixels on top
22008  */
22009
22010 /**
22011  * Offset Left.
22012  * getBoundingClientRect technique from
22013  * John Resig
22014  *
22015  * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
22016  *
22017  * @param {Element} el
22018  *        Element from which to get offset
22019  *
22020  * @return {Dom~Position}
22021  *         The position of the element that was passed in.
22022  */
22023 function findElPosition(el) {
22024   var box = void 0;
22025
22026   if (el.getBoundingClientRect && el.parentNode) {
22027     box = el.getBoundingClientRect();
22028   }
22029
22030   if (!box) {
22031     return {
22032       left: 0,
22033       top: 0
22034     };
22035   }
22036
22037   var docEl = _document2['default'].documentElement;
22038   var body = _document2['default'].body;
22039
22040   var clientLeft = docEl.clientLeft || body.clientLeft || 0;
22041   var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
22042   var left = box.left + scrollLeft - clientLeft;
22043
22044   var clientTop = docEl.clientTop || body.clientTop || 0;
22045   var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
22046   var top = box.top + scrollTop - clientTop;
22047
22048   // Android sometimes returns slightly off decimal values, so need to round
22049   return {
22050     left: Math.round(left),
22051     top: Math.round(top)
22052   };
22053 }
22054
22055 /**
22056  * x and y coordinates for a dom element or mouse pointer
22057  *
22058  * @typedef {Object} Dom~Coordinates
22059  *
22060  * @property {number} x
22061  *           x coordinate in pixels
22062  *
22063  * @property {number} y
22064  *           y coordinate in pixels
22065  */
22066
22067 /**
22068  * Get pointer position in element
22069  * Returns an object with x and y coordinates.
22070  * The base on the coordinates are the bottom left of the element.
22071  *
22072  * @param {Element} el
22073  *        Element on which to get the pointer position on
22074  *
22075  * @param {EventTarget~Event} event
22076  *        Event object
22077  *
22078  * @return {Dom~Coordinates}
22079  *         A Coordinates object corresponding to the mouse position.
22080  *
22081  */
22082 function getPointerPosition(el, event) {
22083   var position = {};
22084   var box = findElPosition(el);
22085   var boxW = el.offsetWidth;
22086   var boxH = el.offsetHeight;
22087
22088   var boxY = box.top;
22089   var boxX = box.left;
22090   var pageY = event.pageY;
22091   var pageX = event.pageX;
22092
22093   if (event.changedTouches) {
22094     pageX = event.changedTouches[0].pageX;
22095     pageY = event.changedTouches[0].pageY;
22096   }
22097
22098   position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
22099   position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
22100
22101   return position;
22102 }
22103
22104 /**
22105  * Determines, via duck typing, whether or not a value is a text node.
22106  *
22107  * @param {Mixed} value
22108  *        Check if this value is a text node.
22109  *
22110  * @return {boolean}
22111  *         - True if it is a text node
22112  *         - False otherwise
22113  */
22114 function isTextNode(value) {
22115   return (0, _obj.isObject)(value) && value.nodeType === 3;
22116 }
22117
22118 /**
22119  * Empties the contents of an element.
22120  *
22121  * @param {Element} el
22122  *        The element to empty children from
22123  *
22124  * @return {Element}
22125  *         The element with no children
22126  */
22127 function emptyEl(el) {
22128   while (el.firstChild) {
22129     el.removeChild(el.firstChild);
22130   }
22131   return el;
22132 }
22133
22134 /**
22135  * Normalizes content for eventual insertion into the DOM.
22136  *
22137  * This allows a wide range of content definition methods, but protects
22138  * from falling into the trap of simply writing to `innerHTML`, which is
22139  * an XSS concern.
22140  *
22141  * The content for an element can be passed in multiple types and
22142  * combinations, whose behavior is as follows:
22143  *
22144  * @param {String|Element|TextNode|Array|Function} content
22145  *        - String: Normalized into a text node.
22146  *        - Element/TextNode: Passed through.
22147  *        - Array: A one-dimensional array of strings, elements, nodes, or functions
22148  *          (which return single strings, elements, or nodes).
22149  *        - Function: If the sole argument, is expected to produce a string, element,
22150  *          node, or array as defined above.
22151  *
22152  * @return {Array}
22153  *         All of the content that was passed in normalized.
22154  */
22155 function normalizeContent(content) {
22156
22157   // First, invoke content if it is a function. If it produces an array,
22158   // that needs to happen before normalization.
22159   if (typeof content === 'function') {
22160     content = content();
22161   }
22162
22163   // Next up, normalize to an array, so one or many items can be normalized,
22164   // filtered, and returned.
22165   return (Array.isArray(content) ? content : [content]).map(function (value) {
22166
22167     // First, invoke value if it is a function to produce a new value,
22168     // which will be subsequently normalized to a Node of some kind.
22169     if (typeof value === 'function') {
22170       value = value();
22171     }
22172
22173     if (isEl(value) || isTextNode(value)) {
22174       return value;
22175     }
22176
22177     if (typeof value === 'string' && /\S/.test(value)) {
22178       return _document2['default'].createTextNode(value);
22179     }
22180   }).filter(function (value) {
22181     return value;
22182   });
22183 }
22184
22185 /**
22186  * Normalizes and appends content to an element.
22187  *
22188  * @param {Element} el
22189  *        Element to append normalized content to.
22190  *
22191  *
22192  * @param {String|Element|TextNode|Array|Function} content
22193  *        See the `content` argument of {@link dom:normalizeContent}
22194  *
22195  * @return {Element}
22196  *         The element with appended normalized content.
22197  */
22198 function appendContent(el, content) {
22199   normalizeContent(content).forEach(function (node) {
22200     return el.appendChild(node);
22201   });
22202   return el;
22203 }
22204
22205 /**
22206  * Normalizes and inserts content into an element; this is identical to
22207  * `appendContent()`, except it empties the element first.
22208  *
22209  * @param {Element} el
22210  *        Element to insert normalized content into.
22211  *
22212  * @param {String|Element|TextNode|Array|Function} content
22213  *        See the `content` argument of {@link dom:normalizeContent}
22214  *
22215  * @return {Element}
22216  *         The element with inserted normalized content.
22217  *
22218  */
22219 function insertContent(el, content) {
22220   return appendContent(emptyEl(el), content);
22221 }
22222
22223 /**
22224  * Finds a single DOM element matching `selector` within the optional
22225  * `context` of another DOM element (defaulting to `document`).
22226  *
22227  * @param {string} selector
22228  *        A valid CSS selector, which will be passed to `querySelector`.
22229  *
22230  * @param {Element|String} [context=document]
22231  *        A DOM element within which to query. Can also be a selector
22232  *        string in which case the first matching element will be used
22233  *        as context. If missing (or no element matches selector), falls
22234  *        back to `document`.
22235  *
22236  * @return {Element|null}
22237  *         The element that was found or null.
22238  */
22239 var $ = exports.$ = createQuerier('querySelector');
22240
22241 /**
22242  * Finds a all DOM elements matching `selector` within the optional
22243  * `context` of another DOM element (defaulting to `document`).
22244  *
22245  * @param {string} selector
22246  *           A valid CSS selector, which will be passed to `querySelectorAll`.
22247  *
22248  * @param {Element|String} [context=document]
22249  *           A DOM element within which to query. Can also be a selector
22250  *           string in which case the first matching element will be used
22251  *           as context. If missing (or no element matches selector), falls
22252  *           back to `document`.
22253  *
22254  * @return {NodeList}
22255  *         A element list of elements that were found. Will be empty if none were found.
22256  *
22257  */
22258 var $$ = exports.$$ = createQuerier('querySelectorAll');
22259
22260 },{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){
22261 'use strict';
22262
22263 exports.__esModule = true;
22264 exports.fixEvent = fixEvent;
22265 exports.on = on;
22266 exports.off = off;
22267 exports.trigger = trigger;
22268 exports.one = one;
22269
22270 var _dom = _dereq_(81);
22271
22272 var Dom = _interopRequireWildcard(_dom);
22273
22274 var _guid = _dereq_(85);
22275
22276 var Guid = _interopRequireWildcard(_guid);
22277
22278 var _log = _dereq_(86);
22279
22280 var _log2 = _interopRequireDefault(_log);
22281
22282 var _window = _dereq_(95);
22283
22284 var _window2 = _interopRequireDefault(_window);
22285
22286 var _document = _dereq_(94);
22287
22288 var _document2 = _interopRequireDefault(_document);
22289
22290 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22291
22292 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; } }
22293
22294 /**
22295  * Clean up the listener cache and dispatchers
22296  *
22297  * @param {Element|Object} elem
22298  *        Element to clean up
22299  *
22300  * @param {string} type
22301  *        Type of event to clean up
22302  */
22303 function _cleanUpEvents(elem, type) {
22304   var data = Dom.getElData(elem);
22305
22306   // Remove the events of a particular type if there are none left
22307   if (data.handlers[type].length === 0) {
22308     delete data.handlers[type];
22309     // data.handlers[type] = null;
22310     // Setting to null was causing an error with data.handlers
22311
22312     // Remove the meta-handler from the element
22313     if (elem.removeEventListener) {
22314       elem.removeEventListener(type, data.dispatcher, false);
22315     } else if (elem.detachEvent) {
22316       elem.detachEvent('on' + type, data.dispatcher);
22317     }
22318   }
22319
22320   // Remove the events object if there are no types left
22321   if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
22322     delete data.handlers;
22323     delete data.dispatcher;
22324     delete data.disabled;
22325   }
22326
22327   // Finally remove the element data if there is no data left
22328   if (Object.getOwnPropertyNames(data).length === 0) {
22329     Dom.removeElData(elem);
22330   }
22331 }
22332
22333 /**
22334  * Loops through an array of event types and calls the requested method for each type.
22335  *
22336  * @param {Function} fn
22337  *        The event method we want to use.
22338  *
22339  * @param {Element|Object} elem
22340  *        Element or object to bind listeners to
22341  *
22342  * @param {string} type
22343  *        Type of event to bind to.
22344  *
22345  * @param {EventTarget~EventListener} callback
22346  *        Event listener.
22347  */
22348 /**
22349  * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
22350  * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
22351  * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
22352  * robust as jquery's, so there's probably some differences.
22353  *
22354  * @module events
22355  */
22356
22357 function _handleMultipleEvents(fn, elem, types, callback) {
22358   types.forEach(function (type) {
22359     // Call the event method for each one of the types
22360     fn(elem, type, callback);
22361   });
22362 }
22363
22364 /**
22365  * Fix a native event to have standard property values
22366  *
22367  * @param {Object} event
22368  *        Event object to fix.
22369  *
22370  * @return {Object}
22371  *         Fixed event object.
22372  */
22373 function fixEvent(event) {
22374
22375   function returnTrue() {
22376     return true;
22377   }
22378
22379   function returnFalse() {
22380     return false;
22381   }
22382
22383   // Test if fixing up is needed
22384   // Used to check if !event.stopPropagation instead of isPropagationStopped
22385   // But native events return true for stopPropagation, but don't have
22386   // other expected methods like isPropagationStopped. Seems to be a problem
22387   // with the Javascript Ninja code. So we're just overriding all events now.
22388   if (!event || !event.isPropagationStopped) {
22389     var old = event || _window2['default'].event;
22390
22391     event = {};
22392     // Clone the old object so that we can modify the values event = {};
22393     // IE8 Doesn't like when you mess with native event properties
22394     // Firefox returns false for event.hasOwnProperty('type') and other props
22395     //  which makes copying more difficult.
22396     // TODO: Probably best to create a whitelist of event props
22397     for (var key in old) {
22398       // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
22399       // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
22400       // and webkitMovementX/Y
22401       if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
22402         // Chrome 32+ warns if you try to copy deprecated returnValue, but
22403         // we still want to if preventDefault isn't supported (IE8).
22404         if (!(key === 'returnValue' && old.preventDefault)) {
22405           event[key] = old[key];
22406         }
22407       }
22408     }
22409
22410     // The event occurred on this element
22411     if (!event.target) {
22412       event.target = event.srcElement || _document2['default'];
22413     }
22414
22415     // Handle which other element the event is related to
22416     if (!event.relatedTarget) {
22417       event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
22418     }
22419
22420     // Stop the default browser action
22421     event.preventDefault = function () {
22422       if (old.preventDefault) {
22423         old.preventDefault();
22424       }
22425       event.returnValue = false;
22426       old.returnValue = false;
22427       event.defaultPrevented = true;
22428     };
22429
22430     event.defaultPrevented = false;
22431
22432     // Stop the event from bubbling
22433     event.stopPropagation = function () {
22434       if (old.stopPropagation) {
22435         old.stopPropagation();
22436       }
22437       event.cancelBubble = true;
22438       old.cancelBubble = true;
22439       event.isPropagationStopped = returnTrue;
22440     };
22441
22442     event.isPropagationStopped = returnFalse;
22443
22444     // Stop the event from bubbling and executing other handlers
22445     event.stopImmediatePropagation = function () {
22446       if (old.stopImmediatePropagation) {
22447         old.stopImmediatePropagation();
22448       }
22449       event.isImmediatePropagationStopped = returnTrue;
22450       event.stopPropagation();
22451     };
22452
22453     event.isImmediatePropagationStopped = returnFalse;
22454
22455     // Handle mouse position
22456     if (event.clientX !== null && event.clientX !== undefined) {
22457       var doc = _document2['default'].documentElement;
22458       var body = _document2['default'].body;
22459
22460       event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
22461       event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
22462     }
22463
22464     // Handle key presses
22465     event.which = event.charCode || event.keyCode;
22466
22467     // Fix button for mouse clicks:
22468     // 0 == left; 1 == middle; 2 == right
22469     if (event.button !== null && event.button !== undefined) {
22470
22471       // The following is disabled because it does not pass videojs-standard
22472       // and... yikes.
22473       /* eslint-disable */
22474       event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
22475       /* eslint-enable */
22476     }
22477   }
22478
22479   // Returns fixed-up instance
22480   return event;
22481 }
22482
22483 /**
22484  * Add an event listener to element
22485  * It stores the handler function in a separate cache object
22486  * and adds a generic handler to the element's event,
22487  * along with a unique id (guid) to the element.
22488  *
22489  * @param {Element|Object} elem
22490  *        Element or object to bind listeners to
22491  *
22492  * @param {string|string[]} type
22493  *        Type of event to bind to.
22494  *
22495  * @param {EventTarget~EventListener} fn
22496  *        Event listener.
22497  */
22498 function on(elem, type, fn) {
22499   if (Array.isArray(type)) {
22500     return _handleMultipleEvents(on, elem, type, fn);
22501   }
22502
22503   var data = Dom.getElData(elem);
22504
22505   // We need a place to store all our handler data
22506   if (!data.handlers) {
22507     data.handlers = {};
22508   }
22509
22510   if (!data.handlers[type]) {
22511     data.handlers[type] = [];
22512   }
22513
22514   if (!fn.guid) {
22515     fn.guid = Guid.newGUID();
22516   }
22517
22518   data.handlers[type].push(fn);
22519
22520   if (!data.dispatcher) {
22521     data.disabled = false;
22522
22523     data.dispatcher = function (event, hash) {
22524
22525       if (data.disabled) {
22526         return;
22527       }
22528
22529       event = fixEvent(event);
22530
22531       var handlers = data.handlers[event.type];
22532
22533       if (handlers) {
22534         // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
22535         var handlersCopy = handlers.slice(0);
22536
22537         for (var m = 0, n = handlersCopy.length; m < n; m++) {
22538           if (event.isImmediatePropagationStopped()) {
22539             break;
22540           } else {
22541             try {
22542               handlersCopy[m].call(elem, event, hash);
22543             } catch (e) {
22544               _log2['default'].error(e);
22545             }
22546           }
22547         }
22548       }
22549     };
22550   }
22551
22552   if (data.handlers[type].length === 1) {
22553     if (elem.addEventListener) {
22554       elem.addEventListener(type, data.dispatcher, false);
22555     } else if (elem.attachEvent) {
22556       elem.attachEvent('on' + type, data.dispatcher);
22557     }
22558   }
22559 }
22560
22561 /**
22562  * Removes event listeners from an element
22563  *
22564  * @param {Element|Object} elem
22565  *        Object to remove listeners from.
22566  *
22567  * @param {string|string[]} [type]
22568  *        Type of listener to remove. Don't include to remove all events from element.
22569  *
22570  * @param {EventTarget~EventListener} [fn]
22571  *        Specific listener to remove. Don't include to remove listeners for an event
22572  *        type.
22573  */
22574 function off(elem, type, fn) {
22575   // Don't want to add a cache object through getElData if not needed
22576   if (!Dom.hasElData(elem)) {
22577     return;
22578   }
22579
22580   var data = Dom.getElData(elem);
22581
22582   // If no events exist, nothing to unbind
22583   if (!data.handlers) {
22584     return;
22585   }
22586
22587   if (Array.isArray(type)) {
22588     return _handleMultipleEvents(off, elem, type, fn);
22589   }
22590
22591   // Utility function
22592   var removeType = function removeType(t) {
22593     data.handlers[t] = [];
22594     _cleanUpEvents(elem, t);
22595   };
22596
22597   // Are we removing all bound events?
22598   if (!type) {
22599     for (var t in data.handlers) {
22600       removeType(t);
22601     }
22602     return;
22603   }
22604
22605   var handlers = data.handlers[type];
22606
22607   // If no handlers exist, nothing to unbind
22608   if (!handlers) {
22609     return;
22610   }
22611
22612   // If no listener was provided, remove all listeners for type
22613   if (!fn) {
22614     removeType(type);
22615     return;
22616   }
22617
22618   // We're only removing a single handler
22619   if (fn.guid) {
22620     for (var n = 0; n < handlers.length; n++) {
22621       if (handlers[n].guid === fn.guid) {
22622         handlers.splice(n--, 1);
22623       }
22624     }
22625   }
22626
22627   _cleanUpEvents(elem, type);
22628 }
22629
22630 /**
22631  * Trigger an event for an element
22632  *
22633  * @param {Element|Object} elem
22634  *        Element to trigger an event on
22635  *
22636  * @param {EventTarget~Event|string} event
22637  *        A string (the type) or an event object with a type attribute
22638  *
22639  * @param {Object} [hash]
22640  *        data hash to pass along with the event
22641  *
22642  * @return {boolean|undefined}
22643  *         - Returns the opposite of `defaultPrevented` if default was prevented
22644  *         - Otherwise returns undefined
22645  */
22646 function trigger(elem, event, hash) {
22647   // Fetches element data and a reference to the parent (for bubbling).
22648   // Don't want to add a data object to cache for every parent,
22649   // so checking hasElData first.
22650   var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
22651   var parent = elem.parentNode || elem.ownerDocument;
22652   // type = event.type || event,
22653   // handler;
22654
22655   // If an event name was passed as a string, creates an event out of it
22656   if (typeof event === 'string') {
22657     event = { type: event, target: elem };
22658   }
22659   // Normalizes the event properties.
22660   event = fixEvent(event);
22661
22662   // If the passed element has a dispatcher, executes the established handlers.
22663   if (elemData.dispatcher) {
22664     elemData.dispatcher.call(elem, event, hash);
22665   }
22666
22667   // Unless explicitly stopped or the event does not bubble (e.g. media events)
22668   // recursively calls this function to bubble the event up the DOM.
22669   if (parent && !event.isPropagationStopped() && event.bubbles === true) {
22670     trigger.call(null, parent, event, hash);
22671
22672     // If at the top of the DOM, triggers the default action unless disabled.
22673   } else if (!parent && !event.defaultPrevented) {
22674     var targetData = Dom.getElData(event.target);
22675
22676     // Checks if the target has a default action for this event.
22677     if (event.target[event.type]) {
22678       // Temporarily disables event dispatching on the target as we have already executed the handler.
22679       targetData.disabled = true;
22680       // Executes the default action.
22681       if (typeof event.target[event.type] === 'function') {
22682         event.target[event.type]();
22683       }
22684       // Re-enables event dispatching.
22685       targetData.disabled = false;
22686     }
22687   }
22688
22689   // Inform the triggerer if the default was prevented by returning false
22690   return !event.defaultPrevented;
22691 }
22692
22693 /**
22694  * Trigger a listener only once for an event
22695  *
22696  * @param {Element|Object} elem
22697  *        Element or object to bind to.
22698  *
22699  * @param {string|string[]} type
22700  *        Name/type of event
22701  *
22702  * @param {Event~EventListener} fn
22703  *        Event Listener function
22704  */
22705 function one(elem, type, fn) {
22706   if (Array.isArray(type)) {
22707     return _handleMultipleEvents(one, elem, type, fn);
22708   }
22709   var func = function func() {
22710     off(elem, type, func);
22711     fn.apply(this, arguments);
22712   };
22713
22714   // copy the guid to the new function so it can removed using the original function's ID
22715   func.guid = fn.guid = fn.guid || Guid.newGUID();
22716   on(elem, type, func);
22717 }
22718
22719 },{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){
22720 'use strict';
22721
22722 exports.__esModule = true;
22723 exports.throttle = exports.bind = undefined;
22724
22725 var _guid = _dereq_(85);
22726
22727 /**
22728  * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
22729  * It also stores a unique id on the function so it can be easily removed from events.
22730  *
22731  * @param {Mixed} context
22732  *        The object to bind as scope.
22733  *
22734  * @param {Function} fn
22735  *        The function to be bound to a scope.
22736  *
22737  * @param {number} [uid]
22738  *        An optional unique ID for the function to be set
22739  *
22740  * @return {Function}
22741  *         The new function that will be bound into the context given
22742  */
22743 var bind = exports.bind = function bind(context, fn, uid) {
22744   // Make sure the function has a unique ID
22745   if (!fn.guid) {
22746     fn.guid = (0, _guid.newGUID)();
22747   }
22748
22749   // Create the new function that changes the context
22750   var bound = function bound() {
22751     return fn.apply(context, arguments);
22752   };
22753
22754   // Allow for the ability to individualize this function
22755   // Needed in the case where multiple objects might share the same prototype
22756   // IF both items add an event listener with the same function, then you try to remove just one
22757   // it will remove both because they both have the same guid.
22758   // when using this, you need to use the bind method when you remove the listener as well.
22759   // currently used in text tracks
22760   bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
22761
22762   return bound;
22763 };
22764
22765 /**
22766  * Wraps the given function, `fn`, with a new function that only invokes `fn`
22767  * at most once per every `wait` milliseconds.
22768  *
22769  * @param  {Function} fn
22770  *         The function to be throttled.
22771  *
22772  * @param  {Number}   wait
22773  *         The number of milliseconds by which to throttle.
22774  *
22775  * @return {Function}
22776  */
22777 /**
22778  * @file fn.js
22779  * @module fn
22780  */
22781 var throttle = exports.throttle = function throttle(fn, wait) {
22782   var last = Date.now();
22783
22784   var throttled = function throttled() {
22785     var now = Date.now();
22786
22787     if (now - last >= wait) {
22788       fn.apply(undefined, arguments);
22789       last = now;
22790     }
22791   };
22792
22793   return throttled;
22794 };
22795
22796 },{"85":85}],84:[function(_dereq_,module,exports){
22797 'use strict';
22798
22799 exports.__esModule = true;
22800 /**
22801  * @file format-time.js
22802  * @module Format-time
22803  */
22804
22805 /**
22806  * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
22807  * will force a number of leading zeros to cover the length of the guide.
22808  *
22809  * @param {number} seconds
22810  *        Number of seconds to be turned into a string
22811  *
22812  * @param {number} guide
22813  *        Number (in seconds) to model the string after
22814  *
22815  * @return {string}
22816  *         Time formatted as H:MM:SS or M:SS
22817  */
22818 function formatTime(seconds) {
22819   var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
22820
22821   seconds = seconds < 0 ? 0 : seconds;
22822   var s = Math.floor(seconds % 60);
22823   var m = Math.floor(seconds / 60 % 60);
22824   var h = Math.floor(seconds / 3600);
22825   var gm = Math.floor(guide / 60 % 60);
22826   var gh = Math.floor(guide / 3600);
22827
22828   // handle invalid times
22829   if (isNaN(seconds) || seconds === Infinity) {
22830     // '-' is false for all relational operators (e.g. <, >=) so this setting
22831     // will add the minimum number of fields specified by the guide
22832     h = m = s = '-';
22833   }
22834
22835   // Check if we need to show hours
22836   h = h > 0 || gh > 0 ? h + ':' : '';
22837
22838   // If hours are showing, we may need to add a leading zero.
22839   // Always show at least one digit of minutes.
22840   m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
22841
22842   // Check if leading zero is need for seconds
22843   s = s < 10 ? '0' + s : s;
22844
22845   return h + m + s;
22846 }
22847
22848 exports['default'] = formatTime;
22849
22850 },{}],85:[function(_dereq_,module,exports){
22851 "use strict";
22852
22853 exports.__esModule = true;
22854 exports.newGUID = newGUID;
22855 /**
22856  * @file guid.js
22857  * @module guid
22858  */
22859
22860 /**
22861  * Unique ID for an element or function
22862  * @type {Number}
22863  */
22864 var _guid = 1;
22865
22866 /**
22867  * Get a unique auto-incrementing ID by number that has not been returned before.
22868  *
22869  * @return {number}
22870  *         A new unique ID.
22871  */
22872 function newGUID() {
22873   return _guid++;
22874 }
22875
22876 },{}],86:[function(_dereq_,module,exports){
22877 'use strict';
22878
22879 exports.__esModule = true;
22880 exports.logByType = undefined;
22881
22882 var _window = _dereq_(95);
22883
22884 var _window2 = _interopRequireDefault(_window);
22885
22886 var _browser = _dereq_(78);
22887
22888 var _obj = _dereq_(88);
22889
22890 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22891
22892 var log = void 0;
22893
22894 /**
22895  * Log messages to the console and history based on the type of message
22896  *
22897  * @param  {string} type
22898  *         The name of the console method to use.
22899  *
22900  * @param  {Array} args
22901  *         The arguments to be passed to the matching console method.
22902  *
22903  * @param  {boolean} [stringify]
22904  *         By default, only old IEs should get console argument stringification,
22905  *         but this is exposed as a parameter to facilitate testing.
22906  */
22907 /**
22908  * @file log.js
22909  * @module log
22910  */
22911 var logByType = exports.logByType = function logByType(type, args) {
22912   var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
22913
22914
22915   if (type !== 'log') {
22916
22917     // add the type to the front of the message when it's not "log"
22918     args.unshift(type.toUpperCase() + ':');
22919   }
22920
22921   // add to history
22922   log.history.push(args);
22923
22924   // add console prefix after adding to history
22925   args.unshift('VIDEOJS:');
22926
22927   // If there's no console then don't try to output messages, but they will
22928   // still be stored in `log.history`.
22929   //
22930   // Was setting these once outside of this function, but containing them
22931   // in the function makes it easier to test cases where console doesn't exist
22932   // when the module is executed.
22933   var fn = _window2['default'].console && _window2['default'].console[type];
22934
22935   // Bail out if there's no console.
22936   if (!fn) {
22937     return;
22938   }
22939
22940   // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
22941   // objects and arrays for those less-capable browsers.
22942   if (stringify) {
22943     args = args.map(function (a) {
22944       if ((0, _obj.isObject)(a) || Array.isArray(a)) {
22945         try {
22946           return JSON.stringify(a);
22947         } catch (x) {
22948           return String(a);
22949         }
22950       }
22951
22952       // Cast to string before joining, so we get null and undefined explicitly
22953       // included in output (as we would in a modern console).
22954       return String(a);
22955     }).join(' ');
22956   }
22957
22958   // Old IE versions do not allow .apply() for console methods (they are
22959   // reported as objects rather than functions).
22960   if (!fn.apply) {
22961     fn(args);
22962   } else {
22963     fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
22964   }
22965 };
22966
22967 /**
22968  * Log plain debug messages
22969  *
22970  * @param {Mixed[]} args
22971  *        One or more messages or objects that should be logged.
22972  */
22973 log = function log() {
22974   for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
22975     args[_key] = arguments[_key];
22976   }
22977
22978   logByType('log', args);
22979 };
22980
22981 /**
22982  * Keep a history of log messages
22983  *
22984  * @type {Array}
22985  */
22986 log.history = [];
22987
22988 /**
22989  * Log error messages
22990  *
22991  * @param {Mixed[]} args
22992  *        One or more messages or objects that should be logged as an error
22993  */
22994 log.error = function () {
22995   for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22996     args[_key2] = arguments[_key2];
22997   }
22998
22999   return logByType('error', args);
23000 };
23001
23002 /**
23003  * Log warning messages
23004  *
23005  * @param {Mixed[]} args
23006  *        One or more messages or objects that should be logged as a warning.
23007  */
23008 log.warn = function () {
23009   for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
23010     args[_key3] = arguments[_key3];
23011   }
23012
23013   return logByType('warn', args);
23014 };
23015
23016 exports['default'] = log;
23017
23018 },{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){
23019 'use strict';
23020
23021 exports.__esModule = true;
23022 exports['default'] = mergeOptions;
23023
23024 var _obj = _dereq_(88);
23025
23026 /**
23027  * Deep-merge one or more options objects, recursively merging **only** plain
23028  * object properties.
23029  *
23030  * @param   {Object[]} sources
23031  *          One or more objects to merge into a new object.
23032  *
23033  * @returns {Object}
23034  *          A new object that is the merged result of all sources.
23035  */
23036 function mergeOptions() {
23037   var result = {};
23038
23039   for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
23040     sources[_key] = arguments[_key];
23041   }
23042
23043   sources.forEach(function (source) {
23044     if (!source) {
23045       return;
23046     }
23047
23048     (0, _obj.each)(source, function (value, key) {
23049       if (!(0, _obj.isPlain)(value)) {
23050         result[key] = value;
23051         return;
23052       }
23053
23054       if (!(0, _obj.isPlain)(result[key])) {
23055         result[key] = {};
23056       }
23057
23058       result[key] = mergeOptions(result[key], value);
23059     });
23060   });
23061
23062   return result;
23063 } /**
23064    * @file merge-options.js
23065    * @module merge-options
23066    */
23067
23068 },{"88":88}],88:[function(_dereq_,module,exports){
23069 'use strict';
23070
23071 exports.__esModule = true;
23072
23073 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; };
23074
23075 exports.each = each;
23076 exports.reduce = reduce;
23077 exports.assign = assign;
23078 exports.isObject = isObject;
23079 exports.isPlain = isPlain;
23080 /**
23081  * @file obj.js
23082  * @module obj
23083  */
23084
23085 /**
23086  * @callback obj:EachCallback
23087  *
23088  * @param {Mixed} value
23089  *        The current key for the object that is being iterated over.
23090  *
23091  * @param {string} key
23092  *        The current key-value for object that is being iterated over
23093  */
23094
23095 /**
23096  * @callback obj:ReduceCallback
23097  *
23098  * @param {Mixed} accum
23099  *        The value that is accumulating over the reduce loop.
23100  *
23101  * @param {Mixed} value
23102  *        The current key for the object that is being iterated over.
23103  *
23104  * @param {string} key
23105  *        The current key-value for object that is being iterated over
23106  *
23107  * @return {Mixed}
23108  *         The new accumulated value.
23109  */
23110 var toString = Object.prototype.toString;
23111
23112 /**
23113  * Get the keys of an Object
23114  *
23115  * @param {Object}
23116  *        The Object to get the keys from
23117  *
23118  * @return {string[]}
23119  *         An array of the keys from the object. Returns an empty array if the
23120  *         object passed in was invalid or had no keys.
23121  *
23122  * @private
23123  */
23124 var keys = function keys(object) {
23125   return isObject(object) ? Object.keys(object) : [];
23126 };
23127
23128 /**
23129  * Array-like iteration for objects.
23130  *
23131  * @param {Object} object
23132  *        The object to iterate over
23133  *
23134  * @param {obj:EachCallback} fn
23135  *        The callback function which is called for each key in the object.
23136  */
23137 function each(object, fn) {
23138   keys(object).forEach(function (key) {
23139     return fn(object[key], key);
23140   });
23141 }
23142
23143 /**
23144  * Array-like reduce for objects.
23145  *
23146  * @param {Object} object
23147  *        The Object that you want to reduce.
23148  *
23149  * @param {Function} fn
23150  *         A callback function which is called for each key in the object. It
23151  *         receives the accumulated value and the per-iteration value and key
23152  *         as arguments.
23153  *
23154  * @param {Mixed} [initial = 0]
23155  *        Starting value
23156  *
23157  * @return {Mixed}
23158  *         The final accumulated value.
23159  */
23160 function reduce(object, fn) {
23161   var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
23162
23163   return keys(object).reduce(function (accum, key) {
23164     return fn(accum, object[key], key);
23165   }, initial);
23166 }
23167
23168 /**
23169  * Object.assign-style object shallow merge/extend.
23170  *
23171  * @param  {Object} target
23172  * @param  {Object} ...sources
23173  * @return {Object}
23174  */
23175 function assign(target) {
23176   for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
23177     sources[_key - 1] = arguments[_key];
23178   }
23179
23180   if (Object.assign) {
23181     return Object.assign.apply(Object, [target].concat(sources));
23182   }
23183
23184   sources.forEach(function (source) {
23185     if (!source) {
23186       return;
23187     }
23188
23189     each(source, function (value, key) {
23190       target[key] = value;
23191     });
23192   });
23193
23194   return target;
23195 }
23196
23197 /**
23198  * Returns whether a value is an object of any kind - including DOM nodes,
23199  * arrays, regular expressions, etc. Not functions, though.
23200  *
23201  * This avoids the gotcha where using `typeof` on a `null` value
23202  * results in `'object'`.
23203  *
23204  * @param  {Object} value
23205  * @return {Boolean}
23206  */
23207 function isObject(value) {
23208   return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
23209 }
23210
23211 /**
23212  * Returns whether an object appears to be a "plain" object - that is, a
23213  * direct instance of `Object`.
23214  *
23215  * @param  {Object} value
23216  * @return {Boolean}
23217  */
23218 function isPlain(value) {
23219   return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
23220 }
23221
23222 },{}],89:[function(_dereq_,module,exports){
23223 'use strict';
23224
23225 exports.__esModule = true;
23226 exports.setTextContent = exports.createStyleElement = undefined;
23227
23228 var _document = _dereq_(94);
23229
23230 var _document2 = _interopRequireDefault(_document);
23231
23232 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23233
23234 /**
23235  * Create a DOM syle element given a className for it.
23236  *
23237  * @param {string} className
23238  *        The className to add to the created style element.
23239  *
23240  * @return {Element}
23241  *         The element that was created.
23242  */
23243 var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
23244   var style = _document2['default'].createElement('style');
23245
23246   style.className = className;
23247
23248   return style;
23249 };
23250
23251 /**
23252  * Add text to a DOM element.
23253  *
23254  * @param {Element} el
23255  *        The Element to add text content to.
23256  *
23257  * @param {string} content
23258  *        The text to add to the element.
23259  */
23260 /**
23261  * @file stylesheet.js
23262  * @module stylesheet
23263  */
23264 var setTextContent = exports.setTextContent = function setTextContent(el, content) {
23265   if (el.styleSheet) {
23266     el.styleSheet.cssText = content;
23267   } else {
23268     el.textContent = content;
23269   }
23270 };
23271
23272 },{"94":94}],90:[function(_dereq_,module,exports){
23273 'use strict';
23274
23275 exports.__esModule = true;
23276 exports.createTimeRange = undefined;
23277 exports.createTimeRanges = createTimeRanges;
23278
23279 var _log = _dereq_(86);
23280
23281 var _log2 = _interopRequireDefault(_log);
23282
23283 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23284
23285 /**
23286  * Returns the time for the specified index at the start or end
23287  * of a TimeRange object.
23288  *
23289  * @function time-ranges:indexFunction
23290  *
23291  * @param {number} [index=0]
23292  *        The range number to return the time for.
23293  *
23294  * @return {number}
23295  *         The time that offset at the specified index.
23296  *
23297  * @depricated index must be set to a value, in the future this will throw an error.
23298  */
23299
23300 /**
23301  * An object that contains ranges of time for various reasons.
23302  *
23303  * @typedef {Object} TimeRange
23304  *
23305  * @property {number} length
23306  *           The number of time ranges represented by this Object
23307  *
23308  * @property {time-ranges:indexFunction} start
23309  *           Returns the time offset at which a specified time range begins.
23310  *
23311  * @property {time-ranges:indexFunction} end
23312  *           Returns the time offset at which a specified time range begins.
23313  *
23314  * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
23315  */
23316
23317 /**
23318  * Check if any of the time ranges are over the maximum index.
23319  *
23320  * @param {string} fnName
23321  *        The function name to use for logging
23322  *
23323  * @param {number} index
23324  *        The index to check
23325  *
23326  * @param {number} maxIndex
23327  *        The maximum possible index
23328  *
23329  * @throws {Error} if the timeRanges provided are over the maxIndex
23330  */
23331 function rangeCheck(fnName, index, maxIndex) {
23332   if (index < 0 || index > maxIndex) {
23333     throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
23334   }
23335 }
23336
23337 /**
23338  * Check if any of the time ranges are over the maximum index.
23339  *
23340  * @param {string} fnName
23341  *        The function name to use for logging
23342  *
23343  * @param {string} valueIndex
23344  *        The proprety that should be used to get the time. should be 'start' or 'end'
23345  *
23346  * @param {Array} ranges
23347  *        An array of time ranges
23348  *
23349  * @param {Array} [rangeIndex=0]
23350  *        The index to start the search at
23351  *
23352  * @return {number}
23353  *         The time that offset at the specified index.
23354  *
23355  *
23356  * @depricated rangeIndex must be set to a value, in the future this will throw an error.
23357  * @throws {Error} if rangeIndex is more than the length of ranges
23358  */
23359 /**
23360  * @file time-ranges.js
23361  * @module time-ranges
23362  */
23363 function getRange(fnName, valueIndex, ranges, rangeIndex) {
23364   if (rangeIndex === undefined) {
23365     _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
23366     rangeIndex = 0;
23367   }
23368   rangeCheck(fnName, rangeIndex, ranges.length - 1);
23369   return ranges[rangeIndex][valueIndex];
23370 }
23371
23372 /**
23373  * Create a time range object givent ranges of time.
23374  *
23375  * @param {Array} [ranges]
23376  *        An array of time ranges.
23377  */
23378 function createTimeRangesObj(ranges) {
23379   if (ranges === undefined || ranges.length === 0) {
23380     return {
23381       length: 0,
23382       start: function start() {
23383         throw new Error('This TimeRanges object is empty');
23384       },
23385       end: function end() {
23386         throw new Error('This TimeRanges object is empty');
23387       }
23388     };
23389   }
23390   return {
23391     length: ranges.length,
23392     start: getRange.bind(null, 'start', 0, ranges),
23393     end: getRange.bind(null, 'end', 1, ranges)
23394   };
23395 }
23396
23397 /**
23398  * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
23399  *
23400  * @param {number|Array} start
23401  *        The start of a single range or an array of ranges
23402  *
23403  * @param {number} end
23404  *        The end of a single range.
23405  *
23406  * @private
23407  */
23408 function createTimeRanges(start, end) {
23409   if (Array.isArray(start)) {
23410     return createTimeRangesObj(start);
23411   } else if (start === undefined || end === undefined) {
23412     return createTimeRangesObj();
23413   }
23414   return createTimeRangesObj([[start, end]]);
23415 }
23416
23417 exports.createTimeRange = createTimeRanges;
23418
23419 },{"86":86}],91:[function(_dereq_,module,exports){
23420 'use strict';
23421
23422 exports.__esModule = true;
23423 /**
23424  * @file to-title-case.js
23425  * @module to-title-case
23426  */
23427
23428 /**
23429  * Uppercase the first letter of a string.
23430  *
23431  * @param {string} string
23432  *        String to be uppercased
23433  *
23434  * @return {string}
23435  *         The string with an uppercased first letter
23436  */
23437 function toTitleCase(string) {
23438   if (typeof string !== 'string') {
23439     return string;
23440   }
23441
23442   return string.charAt(0).toUpperCase() + string.slice(1);
23443 }
23444
23445 exports['default'] = toTitleCase;
23446
23447 },{}],92:[function(_dereq_,module,exports){
23448 'use strict';
23449
23450 exports.__esModule = true;
23451 exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
23452
23453 var _document = _dereq_(94);
23454
23455 var _document2 = _interopRequireDefault(_document);
23456
23457 var _window = _dereq_(95);
23458
23459 var _window2 = _interopRequireDefault(_window);
23460
23461 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23462
23463 /**
23464  * @typedef {Object} url:URLObject
23465  *
23466  * @property {string} protocol
23467  *           The protocol of the url that was parsed.
23468  *
23469  * @property {string} hostname
23470  *           The hostname of the url that was parsed.
23471  *
23472  * @property {string} port
23473  *           The port of the url that was parsed.
23474  *
23475  * @property {string} pathname
23476  *           The pathname of the url that was parsed.
23477  *
23478  * @property {string} search
23479  *           The search query of the url that was parsed.
23480  *
23481  * @property {string} hash
23482  *           The hash of the url that was parsed.
23483  *
23484  * @property {string} host
23485  *           The host of the url that was parsed.
23486  */
23487
23488 /**
23489  * Resolve and parse the elements of a URL.
23490  *
23491  * @param  {String} url
23492  *         The url to parse
23493  *
23494  * @return {url:URLObject}
23495  *         An object of url details
23496  */
23497 /**
23498  * @file url.js
23499  * @module url
23500  */
23501 var parseUrl = exports.parseUrl = function parseUrl(url) {
23502   var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
23503
23504   // add the url to an anchor and let the browser parse the URL
23505   var a = _document2['default'].createElement('a');
23506
23507   a.href = url;
23508
23509   // IE8 (and 9?) Fix
23510   // ie8 doesn't parse the URL correctly until the anchor is actually
23511   // added to the body, and an innerHTML is needed to trigger the parsing
23512   var addToBody = a.host === '' && a.protocol !== 'file:';
23513   var div = void 0;
23514
23515   if (addToBody) {
23516     div = _document2['default'].createElement('div');
23517     div.innerHTML = '<a href="' + url + '"></a>';
23518     a = div.firstChild;
23519     // prevent the div from affecting layout
23520     div.setAttribute('style', 'display:none; position:absolute;');
23521     _document2['default'].body.appendChild(div);
23522   }
23523
23524   // Copy the specific URL properties to a new object
23525   // This is also needed for IE8 because the anchor loses its
23526   // properties when it's removed from the dom
23527   var details = {};
23528
23529   for (var i = 0; i < props.length; i++) {
23530     details[props[i]] = a[props[i]];
23531   }
23532
23533   // IE9 adds the port to the host property unlike everyone else. If
23534   // a port identifier is added for standard ports, strip it.
23535   if (details.protocol === 'http:') {
23536     details.host = details.host.replace(/:80$/, '');
23537   }
23538
23539   if (details.protocol === 'https:') {
23540     details.host = details.host.replace(/:443$/, '');
23541   }
23542
23543   if (addToBody) {
23544     _document2['default'].body.removeChild(div);
23545   }
23546
23547   return details;
23548 };
23549
23550 /**
23551  * Get absolute version of relative URL. Used to tell flash correct URL.
23552  *
23553  *
23554  * @param  {string} url
23555  *         URL to make absolute
23556  *
23557  * @return {string}
23558  *         Absolute URL
23559  *
23560  * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
23561  */
23562 var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
23563   // Check if absolute URL
23564   if (!url.match(/^https?:\/\//)) {
23565     // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
23566     var div = _document2['default'].createElement('div');
23567
23568     div.innerHTML = '<a href="' + url + '">x</a>';
23569     url = div.firstChild.href;
23570   }
23571
23572   return url;
23573 };
23574
23575 /**
23576  * Returns the extension of the passed file name. It will return an empty string
23577  * if passed an invalid path.
23578  *
23579  * @param {string} path
23580  *        The fileName path like '/path/to/file.mp4'
23581  *
23582  * @returns {string}
23583  *          The extension in lower case or an empty string if no
23584  *          extension could be found.
23585  */
23586 var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
23587   if (typeof path === 'string') {
23588     var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
23589     var pathParts = splitPathRe.exec(path);
23590
23591     if (pathParts) {
23592       return pathParts.pop().toLowerCase();
23593     }
23594   }
23595
23596   return '';
23597 };
23598
23599 /**
23600  * Returns whether the url passed is a cross domain request or not.
23601  *
23602  * @param {string} url
23603  *        The url to check.
23604  *
23605  * @return {boolean}
23606  *         Whether it is a cross domain request or not.
23607  */
23608 var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
23609   var winLoc = _window2['default'].location;
23610   var urlInfo = parseUrl(url);
23611
23612   // IE8 protocol relative urls will return ':' for protocol
23613   var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
23614
23615   // Check if url is for another domain/origin
23616   // IE8 doesn't know location.origin, so we won't rely on it here
23617   var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
23618
23619   return crossOrigin;
23620 };
23621
23622 },{"94":94,"95":95}],93:[function(_dereq_,module,exports){
23623 'use strict';
23624
23625 exports.__esModule = true;
23626
23627 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; }; /**
23628                                                                                                                                                                                                                                                                                * @file video.js
23629                                                                                                                                                                                                                                                                                * @module videojs
23630                                                                                                                                                                                                                                                                                */
23631
23632 /* global define */
23633
23634 // Include the built-in techs
23635
23636
23637 var _window = _dereq_(95);
23638
23639 var _window2 = _interopRequireDefault(_window);
23640
23641 var _document = _dereq_(94);
23642
23643 var _document2 = _interopRequireDefault(_document);
23644
23645 var _setup = _dereq_(56);
23646
23647 var setup = _interopRequireWildcard(_setup);
23648
23649 var _stylesheet = _dereq_(89);
23650
23651 var stylesheet = _interopRequireWildcard(_stylesheet);
23652
23653 var _component = _dereq_(5);
23654
23655 var _component2 = _interopRequireDefault(_component);
23656
23657 var _eventTarget = _dereq_(42);
23658
23659 var _eventTarget2 = _interopRequireDefault(_eventTarget);
23660
23661 var _events = _dereq_(82);
23662
23663 var Events = _interopRequireWildcard(_events);
23664
23665 var _player = _dereq_(51);
23666
23667 var _player2 = _interopRequireDefault(_player);
23668
23669 var _plugins = _dereq_(52);
23670
23671 var _plugins2 = _interopRequireDefault(_plugins);
23672
23673 var _mergeOptions2 = _dereq_(87);
23674
23675 var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
23676
23677 var _fn = _dereq_(83);
23678
23679 var Fn = _interopRequireWildcard(_fn);
23680
23681 var _textTrack = _dereq_(72);
23682
23683 var _textTrack2 = _interopRequireDefault(_textTrack);
23684
23685 var _audioTrack = _dereq_(64);
23686
23687 var _audioTrack2 = _interopRequireDefault(_audioTrack);
23688
23689 var _videoTrack = _dereq_(77);
23690
23691 var _videoTrack2 = _interopRequireDefault(_videoTrack);
23692
23693 var _timeRanges = _dereq_(90);
23694
23695 var _formatTime = _dereq_(84);
23696
23697 var _formatTime2 = _interopRequireDefault(_formatTime);
23698
23699 var _log = _dereq_(86);
23700
23701 var _log2 = _interopRequireDefault(_log);
23702
23703 var _dom = _dereq_(81);
23704
23705 var Dom = _interopRequireWildcard(_dom);
23706
23707 var _browser = _dereq_(78);
23708
23709 var browser = _interopRequireWildcard(_browser);
23710
23711 var _url = _dereq_(92);
23712
23713 var Url = _interopRequireWildcard(_url);
23714
23715 var _obj = _dereq_(88);
23716
23717 var _computedStyle = _dereq_(80);
23718
23719 var _computedStyle2 = _interopRequireDefault(_computedStyle);
23720
23721 var _extend = _dereq_(43);
23722
23723 var _extend2 = _interopRequireDefault(_extend);
23724
23725 var _xhr = _dereq_(99);
23726
23727 var _xhr2 = _interopRequireDefault(_xhr);
23728
23729 var _tech = _dereq_(62);
23730
23731 var _tech2 = _interopRequireDefault(_tech);
23732
23733 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; } }
23734
23735 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23736
23737 // HTML5 Element Shim for IE8
23738 if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
23739   _document2['default'].createElement('video');
23740   _document2['default'].createElement('audio');
23741   _document2['default'].createElement('track');
23742 }
23743
23744 /**
23745  * Doubles as the main function for users to create a player instance and also
23746  * the main library object.
23747  * The `videojs` function can be used to initialize or retrieve a player.
23748   *
23749  * @param {string|Element} id
23750  *        Video element or video element ID
23751  *
23752  * @param {Object} [options]
23753  *        Optional options object for config/settings
23754  *
23755  * @param {Component~ReadyCallback} [ready]
23756  *        Optional ready callback
23757  *
23758  * @return {Player}
23759  *         A player instance
23760  *
23761  * @mixes videojs
23762  */
23763 function videojs(id, options, ready) {
23764   var tag = void 0;
23765
23766   // Allow for element or ID to be passed in
23767   // String ID
23768   if (typeof id === 'string') {
23769
23770     // Adjust for jQuery ID syntax
23771     if (id.indexOf('#') === 0) {
23772       id = id.slice(1);
23773     }
23774
23775     // If a player instance has already been created for this ID return it.
23776     if (videojs.getPlayers()[id]) {
23777
23778       // If options or ready funtion are passed, warn
23779       if (options) {
23780         _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
23781       }
23782
23783       if (ready) {
23784         videojs.getPlayers()[id].ready(ready);
23785       }
23786
23787       return videojs.getPlayers()[id];
23788     }
23789
23790     // Otherwise get element for ID
23791     tag = Dom.getEl(id);
23792
23793     // ID is a media element
23794   } else {
23795     tag = id;
23796   }
23797
23798   // Check for a useable element
23799   // re: nodeName, could be a box div also
23800   if (!tag || !tag.nodeName) {
23801     throw new TypeError('The element or ID supplied is not valid. (videojs)');
23802   }
23803
23804   // Element may have a player attr referring to an already created player instance.
23805   // If so return that otherwise set up a new player below
23806   if (tag.player || _player2['default'].players[tag.playerId]) {
23807     return tag.player || _player2['default'].players[tag.playerId];
23808   }
23809
23810   options = options || {};
23811
23812   videojs.hooks('beforesetup').forEach(function (hookFunction) {
23813     var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
23814
23815     if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
23816       _log2['default'].error('please return an object in beforesetup hooks');
23817       return;
23818     }
23819
23820     options = (0, _mergeOptions3['default'])(options, opts);
23821   });
23822
23823   var PlayerComponent = _component2['default'].getComponent('Player');
23824   // If not, set up a new player
23825   var player = new PlayerComponent(tag, options, ready);
23826
23827   videojs.hooks('setup').forEach(function (hookFunction) {
23828     return hookFunction(player);
23829   });
23830
23831   return player;
23832 }
23833
23834 /**
23835  * An Object that contains lifecycle hooks as keys which point to an array
23836  * of functions that are run when a lifecycle is triggered
23837  */
23838 videojs.hooks_ = {};
23839
23840 /**
23841  * Get a list of hooks for a specific lifecycle
23842  *
23843  * @param {string} type
23844  *        the lifecyle to get hooks from
23845  *
23846  * @param {Function} [fn]
23847  *        Optionally add a hook to the lifecycle that your are getting.
23848  *
23849  * @return {Array}
23850  *         an array of hooks, or an empty array if there are none.
23851  */
23852 videojs.hooks = function (type, fn) {
23853   videojs.hooks_[type] = videojs.hooks_[type] || [];
23854   if (fn) {
23855     videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
23856   }
23857   return videojs.hooks_[type];
23858 };
23859
23860 /**
23861  * Add a function hook to a specific videojs lifecycle.
23862  *
23863  * @param {string} type
23864  *        the lifecycle to hook the function to.
23865  *
23866  * @param {Function|Function[]}
23867  *        The function or array of functions to attach.
23868  */
23869 videojs.hook = function (type, fn) {
23870   videojs.hooks(type, fn);
23871 };
23872
23873 /**
23874  * Remove a hook from a specific videojs lifecycle.
23875  *
23876  * @param {string} type
23877  *        the lifecycle that the function hooked to
23878  *
23879  * @param {Function} fn
23880  *        The hooked function to remove
23881  *
23882  * @return {boolean}
23883  *         The function that was removed or undef
23884  */
23885 videojs.removeHook = function (type, fn) {
23886   var index = videojs.hooks(type).indexOf(fn);
23887
23888   if (index <= -1) {
23889     return false;
23890   }
23891
23892   videojs.hooks_[type] = videojs.hooks_[type].slice();
23893   videojs.hooks_[type].splice(index, 1);
23894
23895   return true;
23896 };
23897
23898 // Add default styles
23899 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
23900   var style = Dom.$('.vjs-styles-defaults');
23901
23902   if (!style) {
23903     style = stylesheet.createStyleElement('vjs-styles-defaults');
23904     var head = Dom.$('head');
23905
23906     if (head) {
23907       head.insertBefore(style, head.firstChild);
23908     }
23909     stylesheet.setTextContent(style, '\n      .video-js {\n        width: 300px;\n        height: 150px;\n      }\n\n      .vjs-fluid {\n        padding-top: 56.25%\n      }\n    ');
23910   }
23911 }
23912
23913 // Run Auto-load players
23914 // You have to wait at least once in case this script is loaded after your
23915 // video in the DOM (weird behavior only with minified version)
23916 setup.autoSetupTimeout(1, videojs);
23917
23918 /**
23919  * Current software version. Follows semver.
23920  *
23921  * @type {string}
23922  */
23923 videojs.VERSION = '5.19.2';
23924
23925 /**
23926  * The global options object. These are the settings that take effect
23927  * if no overrides are specified when the player is created.
23928  *
23929  * @type {Object}
23930  */
23931 videojs.options = _player2['default'].prototype.options_;
23932
23933 /**
23934  * Get an object with the currently created players, keyed by player ID
23935  *
23936  * @return {Object}
23937  *         The created players
23938  */
23939 videojs.getPlayers = function () {
23940   return _player2['default'].players;
23941 };
23942
23943 /**
23944  * Expose players object.
23945  *
23946  * @memberOf videojs
23947  * @property {Object} players
23948  */
23949 videojs.players = _player2['default'].players;
23950
23951 /**
23952  * Get a component class object by name
23953  *
23954  * @borrows Component.getComponent as videojs.getComponent
23955  */
23956 videojs.getComponent = _component2['default'].getComponent;
23957
23958 /**
23959  * Register a component so it can referred to by name. Used when adding to other
23960  * components, either through addChild `component.addChild('myComponent')` or through
23961  * default children options  `{ children: ['myComponent'] }`.
23962  *
23963  * > NOTE: You could also just initialize the component before adding.
23964  * `component.addChild(new MyComponent());`
23965  *
23966  * @param {string} name
23967  *        The class name of the component
23968  *
23969  * @param {Component} comp
23970  *        The component class
23971  *
23972  * @return {Component}
23973  *         The newly registered component
23974  */
23975 videojs.registerComponent = function (name, comp) {
23976   if (_tech2['default'].isTech(comp)) {
23977     _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
23978   }
23979
23980   _component2['default'].registerComponent.call(_component2['default'], name, comp);
23981 };
23982
23983 /**
23984  * Get a Tech class object by name
23985  *
23986  * @borrows Tech.getTech as videojs.getTech
23987  */
23988 videojs.getTech = _tech2['default'].getTech;
23989
23990 /**
23991  * Register a Tech so it can referred to by name.
23992  * This is used in the tech order for the player.
23993  *
23994  * @borrows Tech.registerTech as videojs.registerTech
23995  */
23996 videojs.registerTech = _tech2['default'].registerTech;
23997
23998 /**
23999  * A suite of browser and device tests from {@link browser}.
24000  *
24001  * @type {Object}
24002  * @private
24003  */
24004 videojs.browser = browser;
24005
24006 /**
24007  * Whether or not the browser supports touch events. Included for backward
24008  * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
24009  * instead going forward.
24010  *
24011  * @deprecated since version 5.0
24012  * @type {boolean}
24013  */
24014 videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
24015
24016 /**
24017  * Subclass an existing class
24018  * Mimics ES6 subclassing with the `extend` keyword
24019  *
24020  * @borrows extend:extendFn as videojs.extend
24021  */
24022 videojs.extend = _extend2['default'];
24023
24024 /**
24025  * Merge two options objects recursively
24026  * Performs a deep merge like lodash.merge but **only merges plain objects**
24027  * (not arrays, elements, anything else)
24028  * Other values will be copied directly from the second object.
24029  *
24030  * @borrows merge-options:mergeOptions as videojs.mergeOptions
24031  */
24032 videojs.mergeOptions = _mergeOptions3['default'];
24033
24034 /**
24035  * Change the context (this) of a function
24036  *
24037  * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
24038  * `function() {}.bind(newContext);` instead of this.
24039  *
24040  * @borrows fn:bind as videojs.bind
24041  */
24042 videojs.bind = Fn.bind;
24043
24044 /**
24045  * Create a Video.js player plugin.
24046  * Plugins are only initialized when options for the plugin are included
24047  * in the player options, or the plugin function on the player instance is
24048  * called.
24049  *
24050  * @borrows plugin:plugin as videojs.plugin
24051  */
24052 videojs.plugin = _plugins2['default'];
24053
24054 /**
24055  * Adding languages so that they're available to all players.
24056  * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
24057  *
24058  * @param {string} code
24059  *        The language code or dictionary property
24060  *
24061  * @param {Object} data
24062  *        The data values to be translated
24063  *
24064  * @return {Object}
24065  *         The resulting language dictionary object
24066  */
24067 videojs.addLanguage = function (code, data) {
24068   var _mergeOptions;
24069
24070   code = ('' + code).toLowerCase();
24071
24072   videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
24073
24074   return videojs.options.languages[code];
24075 };
24076
24077 /**
24078  * Log messages
24079  *
24080  * @borrows log:log as videojs.log
24081  */
24082 videojs.log = _log2['default'];
24083
24084 /**
24085  * Creates an emulated TimeRange object.
24086  *
24087  * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
24088  */
24089 /**
24090  * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
24091  */
24092 videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
24093
24094 /**
24095  * Format seconds as a time string, H:MM:SS or M:SS
24096  * Supplying a guide (in seconds) will force a number of leading zeros
24097  * to cover the length of the guide
24098  *
24099  * @borrows format-time:formatTime as videojs.formatTime
24100  */
24101 videojs.formatTime = _formatTime2['default'];
24102
24103 /**
24104  * Resolve and parse the elements of a URL
24105  *
24106  * @borrows url:parseUrl as videojs.parseUrl
24107  */
24108 videojs.parseUrl = Url.parseUrl;
24109
24110 /**
24111  * Returns whether the url passed is a cross domain request or not.
24112  *
24113  * @borrows url:isCrossOrigin as videojs.isCrossOrigin
24114  */
24115 videojs.isCrossOrigin = Url.isCrossOrigin;
24116
24117 /**
24118  * Event target class.
24119  *
24120  * @borrows EventTarget as videojs.EventTarget
24121  */
24122 videojs.EventTarget = _eventTarget2['default'];
24123
24124 /**
24125  * Add an event listener to element
24126  * It stores the handler function in a separate cache object
24127  * and adds a generic handler to the element's event,
24128  * along with a unique id (guid) to the element.
24129  *
24130  * @borrows events:on as videojs.on
24131  */
24132 videojs.on = Events.on;
24133
24134 /**
24135  * Trigger a listener only once for an event
24136  *
24137  * @borrows events:one as videojs.one
24138  */
24139 videojs.one = Events.one;
24140
24141 /**
24142  * Removes event listeners from an element
24143  *
24144  * @borrows events:off as videojs.off
24145  */
24146 videojs.off = Events.off;
24147
24148 /**
24149  * Trigger an event for an element
24150  *
24151  * @borrows events:trigger as videojs.trigger
24152  */
24153 videojs.trigger = Events.trigger;
24154
24155 /**
24156  * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
24157  *
24158  * @param {Object} options
24159  *        settings for the request.
24160  *
24161  * @return {XMLHttpRequest|XDomainRequest}
24162  *         The request object.
24163  *
24164  * @see https://github.com/Raynos/xhr
24165  */
24166 videojs.xhr = _xhr2['default'];
24167
24168 /**
24169  * TextTrack class
24170  *
24171  * @borrows TextTrack as videojs.TextTrack
24172  */
24173 videojs.TextTrack = _textTrack2['default'];
24174
24175 /**
24176  * export the AudioTrack class so that source handlers can create
24177  * AudioTracks and then add them to the players AudioTrackList
24178  *
24179  * @borrows AudioTrack as videojs.AudioTrack
24180  */
24181 videojs.AudioTrack = _audioTrack2['default'];
24182
24183 /**
24184  * export the VideoTrack class so that source handlers can create
24185  * VideoTracks and then add them to the players VideoTrackList
24186  *
24187  * @borrows VideoTrack as videojs.VideoTrack
24188  */
24189 videojs.VideoTrack = _videoTrack2['default'];
24190
24191 /**
24192  * Determines, via duck typing, whether or not a value is a DOM element.
24193  *
24194  * @borrows dom:isEl as videojs.isEl
24195  */
24196 videojs.isEl = Dom.isEl;
24197
24198 /**
24199  * Determines, via duck typing, whether or not a value is a text node.
24200  *
24201  * @borrows dom:isTextNode as videojs.isTextNode
24202  */
24203 videojs.isTextNode = Dom.isTextNode;
24204
24205 /**
24206  * Creates an element and applies properties.
24207  *
24208  * @borrows dom:createEl as videojs.createEl
24209  */
24210 videojs.createEl = Dom.createEl;
24211
24212 /**
24213  * Check if an element has a CSS class
24214  *
24215  * @borrows dom:hasElClass as videojs.hasClass
24216  */
24217 videojs.hasClass = Dom.hasElClass;
24218
24219 /**
24220  * Add a CSS class name to an element
24221  *
24222  * @borrows dom:addElClass as videojs.addClass
24223  */
24224 videojs.addClass = Dom.addElClass;
24225
24226 /**
24227  * Remove a CSS class name from an element
24228  *
24229  * @borrows dom:removeElClass as videojs.removeClass
24230  */
24231 videojs.removeClass = Dom.removeElClass;
24232
24233 /**
24234  * Adds or removes a CSS class name on an element depending on an optional
24235  * condition or the presence/absence of the class name.
24236  *
24237  * @borrows dom:toggleElClass as videojs.toggleClass
24238  */
24239 videojs.toggleClass = Dom.toggleElClass;
24240
24241 /**
24242  * Apply attributes to an HTML element.
24243  *
24244  * @borrows dom:setElAttributes as videojs.setAttribute
24245  */
24246 videojs.setAttributes = Dom.setElAttributes;
24247
24248 /**
24249  * Get an element's attribute values, as defined on the HTML tag
24250  * Attributes are not the same as properties. They're defined on the tag
24251  * or with setAttribute (which shouldn't be used with HTML)
24252  * This will return true or false for boolean attributes.
24253  *
24254  * @borrows dom:getElAttributes as videojs.getAttributes
24255  */
24256 videojs.getAttributes = Dom.getElAttributes;
24257
24258 /**
24259  * Empties the contents of an element.
24260  *
24261  * @borrows dom:emptyEl as videojs.emptyEl
24262  */
24263 videojs.emptyEl = Dom.emptyEl;
24264
24265 /**
24266  * Normalizes and appends content to an element.
24267  *
24268  * The content for an element can be passed in multiple types and
24269  * combinations, whose behavior is as follows:
24270  *
24271  * - String
24272  *   Normalized into a text node.
24273  *
24274  * - Element, TextNode
24275  *   Passed through.
24276  *
24277  * - Array
24278  *   A one-dimensional array of strings, elements, nodes, or functions (which
24279  *   return single strings, elements, or nodes).
24280  *
24281  * - Function
24282  *   If the sole argument, is expected to produce a string, element,
24283  *   node, or array.
24284  *
24285  * @borrows dom:appendContents as videojs.appendContet
24286  */
24287 videojs.appendContent = Dom.appendContent;
24288
24289 /**
24290  * Normalizes and inserts content into an element; this is identical to
24291  * `appendContent()`, except it empties the element first.
24292  *
24293  * The content for an element can be passed in multiple types and
24294  * combinations, whose behavior is as follows:
24295  *
24296  * - String
24297  *   Normalized into a text node.
24298  *
24299  * - Element, TextNode
24300  *   Passed through.
24301  *
24302  * - Array
24303  *   A one-dimensional array of strings, elements, nodes, or functions (which
24304  *   return single strings, elements, or nodes).
24305  *
24306  * - Function
24307  *   If the sole argument, is expected to produce a string, element,
24308  *   node, or array.
24309  *
24310  * @borrows dom:insertContent as videojs.insertContent
24311  */
24312 videojs.insertContent = Dom.insertContent;
24313
24314 /**
24315  * A safe getComputedStyle with an IE8 fallback.
24316  *
24317  * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
24318  * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
24319  * that the player doesn't break in these cases.
24320  * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
24321  *
24322  * @borrows computed-style:computedStyle as videojs.computedStyle
24323  */
24324 videojs.computedStyle = _computedStyle2['default'];
24325
24326 /*
24327  * Custom Universal Module Definition (UMD)
24328  *
24329  * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
24330  * still support requirejs and browserify. This also needs to be closure
24331  * compiler compatible, so string keys are used.
24332  */
24333 if (typeof define === 'function' && define.amd) {
24334   define('videojs', [], function () {
24335     return videojs;
24336   });
24337
24338   // checking that module is an object too because of umdjs/umd#35
24339 } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
24340   module.exports = videojs;
24341 }
24342
24343 exports['default'] = videojs;
24344
24345 },{"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){
24346 (function (global){
24347 var topLevel = typeof global !== 'undefined' ? global :
24348     typeof window !== 'undefined' ? window : {}
24349 var minDoc = _dereq_(96);
24350
24351 if (typeof document !== 'undefined') {
24352     module.exports = document;
24353 } else {
24354     var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
24355
24356     if (!doccy) {
24357         doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
24358     }
24359
24360     module.exports = doccy;
24361 }
24362
24363 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24364 },{"96":96}],95:[function(_dereq_,module,exports){
24365 (function (global){
24366 if (typeof window !== "undefined") {
24367     module.exports = window;
24368 } else if (typeof global !== "undefined") {
24369     module.exports = global;
24370 } else if (typeof self !== "undefined"){
24371     module.exports = self;
24372 } else {
24373     module.exports = {};
24374 }
24375
24376 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24377 },{}],96:[function(_dereq_,module,exports){
24378
24379 },{}],97:[function(_dereq_,module,exports){
24380 module.exports = SafeParseTuple
24381
24382 function SafeParseTuple(obj, reviver) {
24383     var json
24384     var error = null
24385
24386     try {
24387         json = JSON.parse(obj, reviver)
24388     } catch (err) {
24389         error = err
24390     }
24391
24392     return [error, json]
24393 }
24394
24395 },{}],98:[function(_dereq_,module,exports){
24396 function clean (s) {
24397   return s.replace(/\n\r?\s*/g, '')
24398 }
24399
24400
24401 module.exports = function tsml (sa) {
24402   var s = ''
24403     , i = 0
24404
24405   for (; i < arguments.length; i++)
24406     s += clean(sa[i]) + (arguments[i + 1] || '')
24407
24408   return s
24409 }
24410 },{}],99:[function(_dereq_,module,exports){
24411 "use strict";
24412 var window = _dereq_(95)
24413 var isFunction = _dereq_(100)
24414 var parseHeaders = _dereq_(103)
24415 var xtend = _dereq_(104)
24416
24417 module.exports = createXHR
24418 createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
24419 createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
24420
24421 forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
24422     createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
24423         options = initParams(uri, options, callback)
24424         options.method = method.toUpperCase()
24425         return _createXHR(options)
24426     }
24427 })
24428
24429 function forEachArray(array, iterator) {
24430     for (var i = 0; i < array.length; i++) {
24431         iterator(array[i])
24432     }
24433 }
24434
24435 function isEmpty(obj){
24436     for(var i in obj){
24437         if(obj.hasOwnProperty(i)) return false
24438     }
24439     return true
24440 }
24441
24442 function initParams(uri, options, callback) {
24443     var params = uri
24444
24445     if (isFunction(options)) {
24446         callback = options
24447         if (typeof uri === "string") {
24448             params = {uri:uri}
24449         }
24450     } else {
24451         params = xtend(options, {uri: uri})
24452     }
24453
24454     params.callback = callback
24455     return params
24456 }
24457
24458 function createXHR(uri, options, callback) {
24459     options = initParams(uri, options, callback)
24460     return _createXHR(options)
24461 }
24462
24463 function _createXHR(options) {
24464     if(typeof options.callback === "undefined"){
24465         throw new Error("callback argument missing")
24466     }
24467
24468     var called = false
24469     var callback = function cbOnce(err, response, body){
24470         if(!called){
24471             called = true
24472             options.callback(err, response, body)
24473         }
24474     }
24475
24476     function readystatechange() {
24477         if (xhr.readyState === 4) {
24478             setTimeout(loadFunc, 0)
24479         }
24480     }
24481
24482     function getBody() {
24483         // Chrome with requestType=blob throws errors arround when even testing access to responseText
24484         var body = undefined
24485
24486         if (xhr.response) {
24487             body = xhr.response
24488         } else {
24489             body = xhr.responseText || getXml(xhr)
24490         }
24491
24492         if (isJson) {
24493             try {
24494                 body = JSON.parse(body)
24495             } catch (e) {}
24496         }
24497
24498         return body
24499     }
24500
24501     function errorFunc(evt) {
24502         clearTimeout(timeoutTimer)
24503         if(!(evt instanceof Error)){
24504             evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
24505         }
24506         evt.statusCode = 0
24507         return callback(evt, failureResponse)
24508     }
24509
24510     // will load the data & process the response in a special response object
24511     function loadFunc() {
24512         if (aborted) return
24513         var status
24514         clearTimeout(timeoutTimer)
24515         if(options.useXDR && xhr.status===undefined) {
24516             //IE8 CORS GET successful response doesn't have a status field, but body is fine
24517             status = 200
24518         } else {
24519             status = (xhr.status === 1223 ? 204 : xhr.status)
24520         }
24521         var response = failureResponse
24522         var err = null
24523
24524         if (status !== 0){
24525             response = {
24526                 body: getBody(),
24527                 statusCode: status,
24528                 method: method,
24529                 headers: {},
24530                 url: uri,
24531                 rawRequest: xhr
24532             }
24533             if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
24534                 response.headers = parseHeaders(xhr.getAllResponseHeaders())
24535             }
24536         } else {
24537             err = new Error("Internal XMLHttpRequest Error")
24538         }
24539         return callback(err, response, response.body)
24540     }
24541
24542     var xhr = options.xhr || null
24543
24544     if (!xhr) {
24545         if (options.cors || options.useXDR) {
24546             xhr = new createXHR.XDomainRequest()
24547         }else{
24548             xhr = new createXHR.XMLHttpRequest()
24549         }
24550     }
24551
24552     var key
24553     var aborted
24554     var uri = xhr.url = options.uri || options.url
24555     var method = xhr.method = options.method || "GET"
24556     var body = options.body || options.data
24557     var headers = xhr.headers = options.headers || {}
24558     var sync = !!options.sync
24559     var isJson = false
24560     var timeoutTimer
24561     var failureResponse = {
24562         body: undefined,
24563         headers: {},
24564         statusCode: 0,
24565         method: method,
24566         url: uri,
24567         rawRequest: xhr
24568     }
24569
24570     if ("json" in options && options.json !== false) {
24571         isJson = true
24572         headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
24573         if (method !== "GET" && method !== "HEAD") {
24574             headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
24575             body = JSON.stringify(options.json === true ? body : options.json)
24576         }
24577     }
24578
24579     xhr.onreadystatechange = readystatechange
24580     xhr.onload = loadFunc
24581     xhr.onerror = errorFunc
24582     // IE9 must have onprogress be set to a unique function.
24583     xhr.onprogress = function () {
24584         // IE must die
24585     }
24586     xhr.onabort = function(){
24587         aborted = true;
24588     }
24589     xhr.ontimeout = errorFunc
24590     xhr.open(method, uri, !sync, options.username, options.password)
24591     //has to be after open
24592     if(!sync) {
24593         xhr.withCredentials = !!options.withCredentials
24594     }
24595     // Cannot set timeout with sync request
24596     // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
24597     // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
24598     if (!sync && options.timeout > 0 ) {
24599         timeoutTimer = setTimeout(function(){
24600             if (aborted) return
24601             aborted = true//IE9 may still call readystatechange
24602             xhr.abort("timeout")
24603             var e = new Error("XMLHttpRequest timeout")
24604             e.code = "ETIMEDOUT"
24605             errorFunc(e)
24606         }, options.timeout )
24607     }
24608
24609     if (xhr.setRequestHeader) {
24610         for(key in headers){
24611             if(headers.hasOwnProperty(key)){
24612                 xhr.setRequestHeader(key, headers[key])
24613             }
24614         }
24615     } else if (options.headers && !isEmpty(options.headers)) {
24616         throw new Error("Headers cannot be set on an XDomainRequest object")
24617     }
24618
24619     if ("responseType" in options) {
24620         xhr.responseType = options.responseType
24621     }
24622
24623     if ("beforeSend" in options &&
24624         typeof options.beforeSend === "function"
24625     ) {
24626         options.beforeSend(xhr)
24627     }
24628
24629     // Microsoft Edge browser sends "undefined" when send is called with undefined value.
24630     // XMLHttpRequest spec says to pass null as body to indicate no body
24631     // See https://github.com/naugtur/xhr/issues/100.
24632     xhr.send(body || null)
24633
24634     return xhr
24635
24636
24637 }
24638
24639 function getXml(xhr) {
24640     if (xhr.responseType === "document") {
24641         return xhr.responseXML
24642     }
24643     var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
24644     if (xhr.responseType === "" && !firefoxBugTakenEffect) {
24645         return xhr.responseXML
24646     }
24647
24648     return null
24649 }
24650
24651 function noop() {}
24652
24653 },{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){
24654 module.exports = isFunction
24655
24656 var toString = Object.prototype.toString
24657
24658 function isFunction (fn) {
24659   var string = toString.call(fn)
24660   return string === '[object Function]' ||
24661     (typeof fn === 'function' && string !== '[object RegExp]') ||
24662     (typeof window !== 'undefined' &&
24663      // IE8 and below
24664      (fn === window.setTimeout ||
24665       fn === window.alert ||
24666       fn === window.confirm ||
24667       fn === window.prompt))
24668 };
24669
24670 },{}],101:[function(_dereq_,module,exports){
24671 var isFunction = _dereq_(100)
24672
24673 module.exports = forEach
24674
24675 var toString = Object.prototype.toString
24676 var hasOwnProperty = Object.prototype.hasOwnProperty
24677
24678 function forEach(list, iterator, context) {
24679     if (!isFunction(iterator)) {
24680         throw new TypeError('iterator must be a function')
24681     }
24682
24683     if (arguments.length < 3) {
24684         context = this
24685     }
24686     
24687     if (toString.call(list) === '[object Array]')
24688         forEachArray(list, iterator, context)
24689     else if (typeof list === 'string')
24690         forEachString(list, iterator, context)
24691     else
24692         forEachObject(list, iterator, context)
24693 }
24694
24695 function forEachArray(array, iterator, context) {
24696     for (var i = 0, len = array.length; i < len; i++) {
24697         if (hasOwnProperty.call(array, i)) {
24698             iterator.call(context, array[i], i, array)
24699         }
24700     }
24701 }
24702
24703 function forEachString(string, iterator, context) {
24704     for (var i = 0, len = string.length; i < len; i++) {
24705         // no such thing as a sparse string.
24706         iterator.call(context, string.charAt(i), i, string)
24707     }
24708 }
24709
24710 function forEachObject(object, iterator, context) {
24711     for (var k in object) {
24712         if (hasOwnProperty.call(object, k)) {
24713             iterator.call(context, object[k], k, object)
24714         }
24715     }
24716 }
24717
24718 },{"100":100}],102:[function(_dereq_,module,exports){
24719
24720 exports = module.exports = trim;
24721
24722 function trim(str){
24723   return str.replace(/^\s*|\s*$/g, '');
24724 }
24725
24726 exports.left = function(str){
24727   return str.replace(/^\s*/, '');
24728 };
24729
24730 exports.right = function(str){
24731   return str.replace(/\s*$/, '');
24732 };
24733
24734 },{}],103:[function(_dereq_,module,exports){
24735 var trim = _dereq_(102)
24736   , forEach = _dereq_(101)
24737   , isArray = function(arg) {
24738       return Object.prototype.toString.call(arg) === '[object Array]';
24739     }
24740
24741 module.exports = function (headers) {
24742   if (!headers)
24743     return {}
24744
24745   var result = {}
24746
24747   forEach(
24748       trim(headers).split('\n')
24749     , function (row) {
24750         var index = row.indexOf(':')
24751           , key = trim(row.slice(0, index)).toLowerCase()
24752           , value = trim(row.slice(index + 1))
24753
24754         if (typeof(result[key]) === 'undefined') {
24755           result[key] = value
24756         } else if (isArray(result[key])) {
24757           result[key].push(value)
24758         } else {
24759           result[key] = [ result[key], value ]
24760         }
24761       }
24762   )
24763
24764   return result
24765 }
24766 },{"101":101,"102":102}],104:[function(_dereq_,module,exports){
24767 module.exports = extend
24768
24769 var hasOwnProperty = Object.prototype.hasOwnProperty;
24770
24771 function extend() {
24772     var target = {}
24773
24774     for (var i = 0; i < arguments.length; i++) {
24775         var source = arguments[i]
24776
24777         for (var key in source) {
24778             if (hasOwnProperty.call(source, key)) {
24779                 target[key] = source[key]
24780             }
24781         }
24782     }
24783
24784     return target
24785 }
24786
24787 },{}],105:[function(_dereq_,module,exports){
24788 /**
24789  * Copyright 2013 vtt.js Contributors
24790  *
24791  * Licensed under the Apache License, Version 2.0 (the "License");
24792  * you may not use this file except in compliance with the License.
24793  * You may obtain a copy of the License at
24794  *
24795  *   http://www.apache.org/licenses/LICENSE-2.0
24796  *
24797  * Unless required by applicable law or agreed to in writing, software
24798  * distributed under the License is distributed on an "AS IS" BASIS,
24799  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24800  * See the License for the specific language governing permissions and
24801  * limitations under the License.
24802  */
24803
24804 // Default exports for Node. Export the extended versions of VTTCue and
24805 // VTTRegion in Node since we likely want the capability to convert back and
24806 // forth between JSON. If we don't then it's not that big of a deal since we're
24807 // off browser.
24808
24809 var window = _dereq_(109);
24810
24811 var vttjs = module.exports = {
24812   WebVTT: _dereq_(106).WebVTT,
24813   VTTCue: _dereq_(107).VTTCue,
24814   VTTRegion: _dereq_(108).VTTRegion
24815 };
24816
24817 window.vttjs = vttjs;
24818 window.WebVTT = vttjs.WebVTT;
24819
24820 var cueShim = vttjs.VTTCue;
24821 var regionShim = vttjs.VTTRegion;
24822 var nativeVTTCue = window.VTTCue;
24823 var nativeVTTRegion = window.VTTRegion;
24824
24825 vttjs.shim = function() {
24826   window.VTTCue = cueShim;
24827   window.VTTRegion = regionShim;
24828 };
24829
24830 vttjs.restore = function() {
24831   window.VTTCue = nativeVTTCue;
24832   window.VTTRegion = nativeVTTRegion;
24833 };
24834
24835 if (!window.VTTCue) {
24836   vttjs.shim();
24837 }
24838
24839 },{"106":106,"107":107,"108":108,"109":109}],106:[function(_dereq_,module,exports){
24840 /**
24841  * Copyright 2013 vtt.js Contributors
24842  *
24843  * Licensed under the Apache License, Version 2.0 (the "License");
24844  * you may not use this file except in compliance with the License.
24845  * You may obtain a copy of the License at
24846  *
24847  *   http://www.apache.org/licenses/LICENSE-2.0
24848  *
24849  * Unless required by applicable law or agreed to in writing, software
24850  * distributed under the License is distributed on an "AS IS" BASIS,
24851  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24852  * See the License for the specific language governing permissions and
24853  * limitations under the License.
24854  */
24855
24856 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
24857 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
24858
24859 (function(global) {
24860
24861   var _objCreate = Object.create || (function() {
24862     function F() {}
24863     return function(o) {
24864       if (arguments.length !== 1) {
24865         throw new Error('Object.create shim only accepts one parameter.');
24866       }
24867       F.prototype = o;
24868       return new F();
24869     };
24870   })();
24871
24872   // Creates a new ParserError object from an errorData object. The errorData
24873   // object should have default code and message properties. The default message
24874   // property can be overriden by passing in a message parameter.
24875   // See ParsingError.Errors below for acceptable errors.
24876   function ParsingError(errorData, message) {
24877     this.name = "ParsingError";
24878     this.code = errorData.code;
24879     this.message = message || errorData.message;
24880   }
24881   ParsingError.prototype = _objCreate(Error.prototype);
24882   ParsingError.prototype.constructor = ParsingError;
24883
24884   // ParsingError metadata for acceptable ParsingErrors.
24885   ParsingError.Errors = {
24886     BadSignature: {
24887       code: 0,
24888       message: "Malformed WebVTT signature."
24889     },
24890     BadTimeStamp: {
24891       code: 1,
24892       message: "Malformed time stamp."
24893     }
24894   };
24895
24896   // Try to parse input as a time stamp.
24897   function parseTimeStamp(input) {
24898
24899     function computeSeconds(h, m, s, f) {
24900       return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
24901     }
24902
24903     var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
24904     if (!m) {
24905       return null;
24906     }
24907
24908     if (m[3]) {
24909       // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
24910       return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
24911     } else if (m[1] > 59) {
24912       // Timestamp takes the form of [hours]:[minutes].[milliseconds]
24913       // First position is hours as it's over 59.
24914       return computeSeconds(m[1], m[2], 0,  m[4]);
24915     } else {
24916       // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
24917       return computeSeconds(0, m[1], m[2], m[4]);
24918     }
24919   }
24920
24921   // A settings object holds key/value pairs and will ignore anything but the first
24922   // assignment to a specific key.
24923   function Settings() {
24924     this.values = _objCreate(null);
24925   }
24926
24927   Settings.prototype = {
24928     // Only accept the first assignment to any key.
24929     set: function(k, v) {
24930       if (!this.get(k) && v !== "") {
24931         this.values[k] = v;
24932       }
24933     },
24934     // Return the value for a key, or a default value.
24935     // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
24936     // a number of possible default values as properties where 'defaultKey' is
24937     // the key of the property that will be chosen; otherwise it's assumed to be
24938     // a single value.
24939     get: function(k, dflt, defaultKey) {
24940       if (defaultKey) {
24941         return this.has(k) ? this.values[k] : dflt[defaultKey];
24942       }
24943       return this.has(k) ? this.values[k] : dflt;
24944     },
24945     // Check whether we have a value for a key.
24946     has: function(k) {
24947       return k in this.values;
24948     },
24949     // Accept a setting if its one of the given alternatives.
24950     alt: function(k, v, a) {
24951       for (var n = 0; n < a.length; ++n) {
24952         if (v === a[n]) {
24953           this.set(k, v);
24954           break;
24955         }
24956       }
24957     },
24958     // Accept a setting if its a valid (signed) integer.
24959     integer: function(k, v) {
24960       if (/^-?\d+$/.test(v)) { // integer
24961         this.set(k, parseInt(v, 10));
24962       }
24963     },
24964     // Accept a setting if its a valid percentage.
24965     percent: function(k, v) {
24966       var m;
24967       if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
24968         v = parseFloat(v);
24969         if (v >= 0 && v <= 100) {
24970           this.set(k, v);
24971           return true;
24972         }
24973       }
24974       return false;
24975     }
24976   };
24977
24978   // Helper function to parse input into groups separated by 'groupDelim', and
24979   // interprete each group as a key/value pair separated by 'keyValueDelim'.
24980   function parseOptions(input, callback, keyValueDelim, groupDelim) {
24981     var groups = groupDelim ? input.split(groupDelim) : [input];
24982     for (var i in groups) {
24983       if (typeof groups[i] !== "string") {
24984         continue;
24985       }
24986       var kv = groups[i].split(keyValueDelim);
24987       if (kv.length !== 2) {
24988         continue;
24989       }
24990       var k = kv[0];
24991       var v = kv[1];
24992       callback(k, v);
24993     }
24994   }
24995
24996   function parseCue(input, cue, regionList) {
24997     // Remember the original input if we need to throw an error.
24998     var oInput = input;
24999     // 4.1 WebVTT timestamp
25000     function consumeTimeStamp() {
25001       var ts = parseTimeStamp(input);
25002       if (ts === null) {
25003         throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25004                               "Malformed timestamp: " + oInput);
25005       }
25006       // Remove time stamp from input.
25007       input = input.replace(/^[^\sa-zA-Z-]+/, "");
25008       return ts;
25009     }
25010
25011     // 4.4.2 WebVTT cue settings
25012     function consumeCueSettings(input, cue) {
25013       var settings = new Settings();
25014
25015       parseOptions(input, function (k, v) {
25016         switch (k) {
25017         case "region":
25018           // Find the last region we parsed with the same region id.
25019           for (var i = regionList.length - 1; i >= 0; i--) {
25020             if (regionList[i].id === v) {
25021               settings.set(k, regionList[i].region);
25022               break;
25023             }
25024           }
25025           break;
25026         case "vertical":
25027           settings.alt(k, v, ["rl", "lr"]);
25028           break;
25029         case "line":
25030           var vals = v.split(","),
25031               vals0 = vals[0];
25032           settings.integer(k, vals0);
25033           settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
25034           settings.alt(k, vals0, ["auto"]);
25035           if (vals.length === 2) {
25036             settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
25037           }
25038           break;
25039         case "position":
25040           vals = v.split(",");
25041           settings.percent(k, vals[0]);
25042           if (vals.length === 2) {
25043             settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
25044           }
25045           break;
25046         case "size":
25047           settings.percent(k, v);
25048           break;
25049         case "align":
25050           settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
25051           break;
25052         }
25053       }, /:/, /\s/);
25054
25055       // Apply default values for any missing fields.
25056       cue.region = settings.get("region", null);
25057       cue.vertical = settings.get("vertical", "");
25058       cue.line = settings.get("line", "auto");
25059       cue.lineAlign = settings.get("lineAlign", "start");
25060       cue.snapToLines = settings.get("snapToLines", true);
25061       cue.size = settings.get("size", 100);
25062       cue.align = settings.get("align", "middle");
25063       cue.position = settings.get("position", {
25064         start: 0,
25065         left: 0,
25066         middle: 50,
25067         end: 100,
25068         right: 100
25069       }, cue.align);
25070       cue.positionAlign = settings.get("positionAlign", {
25071         start: "start",
25072         left: "start",
25073         middle: "middle",
25074         end: "end",
25075         right: "end"
25076       }, cue.align);
25077     }
25078
25079     function skipWhitespace() {
25080       input = input.replace(/^\s+/, "");
25081     }
25082
25083     // 4.1 WebVTT cue timings.
25084     skipWhitespace();
25085     cue.startTime = consumeTimeStamp();   // (1) collect cue start time
25086     skipWhitespace();
25087     if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
25088       throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25089                              "Malformed time stamp (time stamps must be separated by '-->'): " +
25090                              oInput);
25091     }
25092     input = input.substr(3);
25093     skipWhitespace();
25094     cue.endTime = consumeTimeStamp();     // (5) collect cue end time
25095
25096     // 4.1 WebVTT cue settings list.
25097     skipWhitespace();
25098     consumeCueSettings(input, cue);
25099   }
25100
25101   var ESCAPE = {
25102     "&amp;": "&",
25103     "&lt;": "<",
25104     "&gt;": ">",
25105     "&lrm;": "\u200e",
25106     "&rlm;": "\u200f",
25107     "&nbsp;": "\u00a0"
25108   };
25109
25110   var TAG_NAME = {
25111     c: "span",
25112     i: "i",
25113     b: "b",
25114     u: "u",
25115     ruby: "ruby",
25116     rt: "rt",
25117     v: "span",
25118     lang: "span"
25119   };
25120
25121   var TAG_ANNOTATION = {
25122     v: "title",
25123     lang: "lang"
25124   };
25125
25126   var NEEDS_PARENT = {
25127     rt: "ruby"
25128   };
25129
25130   // Parse content into a document fragment.
25131   function parseContent(window, input) {
25132     function nextToken() {
25133       // Check for end-of-string.
25134       if (!input) {
25135         return null;
25136       }
25137
25138       // Consume 'n' characters from the input.
25139       function consume(result) {
25140         input = input.substr(result.length);
25141         return result;
25142       }
25143
25144       var m = input.match(/^([^<]*)(<[^>]+>?)?/);
25145       // If there is some text before the next tag, return it, otherwise return
25146       // the tag.
25147       return consume(m[1] ? m[1] : m[2]);
25148     }
25149
25150     // Unescape a string 's'.
25151     function unescape1(e) {
25152       return ESCAPE[e];
25153     }
25154     function unescape(s) {
25155       while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
25156         s = s.replace(m[0], unescape1);
25157       }
25158       return s;
25159     }
25160
25161     function shouldAdd(current, element) {
25162       return !NEEDS_PARENT[element.localName] ||
25163              NEEDS_PARENT[element.localName] === current.localName;
25164     }
25165
25166     // Create an element for this tag.
25167     function createElement(type, annotation) {
25168       var tagName = TAG_NAME[type];
25169       if (!tagName) {
25170         return null;
25171       }
25172       var element = window.document.createElement(tagName);
25173       element.localName = tagName;
25174       var name = TAG_ANNOTATION[type];
25175       if (name && annotation) {
25176         element[name] = annotation.trim();
25177       }
25178       return element;
25179     }
25180
25181     var rootDiv = window.document.createElement("div"),
25182         current = rootDiv,
25183         t,
25184         tagStack = [];
25185
25186     while ((t = nextToken()) !== null) {
25187       if (t[0] === '<') {
25188         if (t[1] === "/") {
25189           // If the closing tag matches, move back up to the parent node.
25190           if (tagStack.length &&
25191               tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
25192             tagStack.pop();
25193             current = current.parentNode;
25194           }
25195           // Otherwise just ignore the end tag.
25196           continue;
25197         }
25198         var ts = parseTimeStamp(t.substr(1, t.length - 2));
25199         var node;
25200         if (ts) {
25201           // Timestamps are lead nodes as well.
25202           node = window.document.createProcessingInstruction("timestamp", ts);
25203           current.appendChild(node);
25204           continue;
25205         }
25206         var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
25207         // If we can't parse the tag, skip to the next tag.
25208         if (!m) {
25209           continue;
25210         }
25211         // Try to construct an element, and ignore the tag if we couldn't.
25212         node = createElement(m[1], m[3]);
25213         if (!node) {
25214           continue;
25215         }
25216         // Determine if the tag should be added based on the context of where it
25217         // is placed in the cuetext.
25218         if (!shouldAdd(current, node)) {
25219           continue;
25220         }
25221         // Set the class list (as a list of classes, separated by space).
25222         if (m[2]) {
25223           node.className = m[2].substr(1).replace('.', ' ');
25224         }
25225         // Append the node to the current node, and enter the scope of the new
25226         // node.
25227         tagStack.push(m[1]);
25228         current.appendChild(node);
25229         current = node;
25230         continue;
25231       }
25232
25233       // Text nodes are leaf nodes.
25234       current.appendChild(window.document.createTextNode(unescape(t)));
25235     }
25236
25237     return rootDiv;
25238   }
25239
25240   // This is a list of all the Unicode characters that have a strong
25241   // right-to-left category. What this means is that these characters are
25242   // written right-to-left for sure. It was generated by pulling all the strong
25243   // right-to-left characters out of the Unicode data table. That table can
25244   // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
25245   var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],
25246    [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],
25247    [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],
25248    [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],
25249    [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],
25250    [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],
25251    [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],
25252    [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],
25253    [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],
25254    [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],
25255    [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],
25256    [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],
25257    [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],
25258    [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],
25259    [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],
25260    [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],
25261    [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],
25262    [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],
25263    [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],
25264    [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],
25265    [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],
25266    [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],
25267    [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],
25268    [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],
25269    [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];
25270
25271   function isStrongRTLChar(charCode) {
25272     for (var i = 0; i < strongRTLRanges.length; i++) {
25273       var currentRange = strongRTLRanges[i];
25274       if (charCode >= currentRange[0] && charCode <= currentRange[1]) {
25275         return true;
25276       }
25277     }
25278
25279     return false;
25280   }
25281
25282   function determineBidi(cueDiv) {
25283     var nodeStack = [],
25284         text = "",
25285         charCode;
25286
25287     if (!cueDiv || !cueDiv.childNodes) {
25288       return "ltr";
25289     }
25290
25291     function pushNodes(nodeStack, node) {
25292       for (var i = node.childNodes.length - 1; i >= 0; i--) {
25293         nodeStack.push(node.childNodes[i]);
25294       }
25295     }
25296
25297     function nextTextNode(nodeStack) {
25298       if (!nodeStack || !nodeStack.length) {
25299         return null;
25300       }
25301
25302       var node = nodeStack.pop(),
25303           text = node.textContent || node.innerText;
25304       if (text) {
25305         // TODO: This should match all unicode type B characters (paragraph
25306         // separator characters). See issue #115.
25307         var m = text.match(/^.*(\n|\r)/);
25308         if (m) {
25309           nodeStack.length = 0;
25310           return m[0];
25311         }
25312         return text;
25313       }
25314       if (node.tagName === "ruby") {
25315         return nextTextNode(nodeStack);
25316       }
25317       if (node.childNodes) {
25318         pushNodes(nodeStack, node);
25319         return nextTextNode(nodeStack);
25320       }
25321     }
25322
25323     pushNodes(nodeStack, cueDiv);
25324     while ((text = nextTextNode(nodeStack))) {
25325       for (var i = 0; i < text.length; i++) {
25326         charCode = text.charCodeAt(i);
25327         if (isStrongRTLChar(charCode)) {
25328           return "rtl";
25329         }
25330       }
25331     }
25332     return "ltr";
25333   }
25334
25335   function computeLinePos(cue) {
25336     if (typeof cue.line === "number" &&
25337         (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
25338       return cue.line;
25339     }
25340     if (!cue.track || !cue.track.textTrackList ||
25341         !cue.track.textTrackList.mediaElement) {
25342       return -1;
25343     }
25344     var track = cue.track,
25345         trackList = track.textTrackList,
25346         count = 0;
25347     for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
25348       if (trackList[i].mode === "showing") {
25349         count++;
25350       }
25351     }
25352     return ++count * -1;
25353   }
25354
25355   function StyleBox() {
25356   }
25357
25358   // Apply styles to a div. If there is no div passed then it defaults to the
25359   // div on 'this'.
25360   StyleBox.prototype.applyStyles = function(styles, div) {
25361     div = div || this.div;
25362     for (var prop in styles) {
25363       if (styles.hasOwnProperty(prop)) {
25364         div.style[prop] = styles[prop];
25365       }
25366     }
25367   };
25368
25369   StyleBox.prototype.formatStyle = function(val, unit) {
25370     return val === 0 ? 0 : val + unit;
25371   };
25372
25373   // Constructs the computed display state of the cue (a div). Places the div
25374   // into the overlay which should be a block level element (usually a div).
25375   function CueStyleBox(window, cue, styleOptions) {
25376     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
25377     var color = "rgba(255, 255, 255, 1)";
25378     var backgroundColor = "rgba(0, 0, 0, 0.8)";
25379
25380     if (isIE8) {
25381       color = "rgb(255, 255, 255)";
25382       backgroundColor = "rgb(0, 0, 0)";
25383     }
25384
25385     StyleBox.call(this);
25386     this.cue = cue;
25387
25388     // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
25389     // have inline positioning and will function as the cue background box.
25390     this.cueDiv = parseContent(window, cue.text);
25391     var styles = {
25392       color: color,
25393       backgroundColor: backgroundColor,
25394       position: "relative",
25395       left: 0,
25396       right: 0,
25397       top: 0,
25398       bottom: 0,
25399       display: "inline"
25400     };
25401
25402     if (!isIE8) {
25403       styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25404                                                : cue.vertical === "lr" ? "vertical-lr"
25405                                                                        : "vertical-rl";
25406       styles.unicodeBidi = "plaintext";
25407     }
25408     this.applyStyles(styles, this.cueDiv);
25409
25410     // Create an absolutely positioned div that will be used to position the cue
25411     // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
25412     // mirrors of them except "middle" which is "center" in CSS.
25413     this.div = window.document.createElement("div");
25414     styles = {
25415       textAlign: cue.align === "middle" ? "center" : cue.align,
25416       font: styleOptions.font,
25417       whiteSpace: "pre-line",
25418       position: "absolute"
25419     };
25420
25421     if (!isIE8) {
25422       styles.direction = determineBidi(this.cueDiv);
25423       styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25424                                                : cue.vertical === "lr" ? "vertical-lr"
25425                                                                        : "vertical-rl".
25426       stylesunicodeBidi =  "plaintext";
25427     }
25428
25429     this.applyStyles(styles);
25430
25431     this.div.appendChild(this.cueDiv);
25432
25433     // Calculate the distance from the reference edge of the viewport to the text
25434     // position of the cue box. The reference edge will be resolved later when
25435     // the box orientation styles are applied.
25436     var textPos = 0;
25437     switch (cue.positionAlign) {
25438     case "start":
25439       textPos = cue.position;
25440       break;
25441     case "middle":
25442       textPos = cue.position - (cue.size / 2);
25443       break;
25444     case "end":
25445       textPos = cue.position - cue.size;
25446       break;
25447     }
25448
25449     // Horizontal box orientation; textPos is the distance from the left edge of the
25450     // area to the left edge of the box and cue.size is the distance extending to
25451     // the right from there.
25452     if (cue.vertical === "") {
25453       this.applyStyles({
25454         left:  this.formatStyle(textPos, "%"),
25455         width: this.formatStyle(cue.size, "%")
25456       });
25457     // Vertical box orientation; textPos is the distance from the top edge of the
25458     // area to the top edge of the box and cue.size is the height extending
25459     // downwards from there.
25460     } else {
25461       this.applyStyles({
25462         top: this.formatStyle(textPos, "%"),
25463         height: this.formatStyle(cue.size, "%")
25464       });
25465     }
25466
25467     this.move = function(box) {
25468       this.applyStyles({
25469         top: this.formatStyle(box.top, "px"),
25470         bottom: this.formatStyle(box.bottom, "px"),
25471         left: this.formatStyle(box.left, "px"),
25472         right: this.formatStyle(box.right, "px"),
25473         height: this.formatStyle(box.height, "px"),
25474         width: this.formatStyle(box.width, "px")
25475       });
25476     };
25477   }
25478   CueStyleBox.prototype = _objCreate(StyleBox.prototype);
25479   CueStyleBox.prototype.constructor = CueStyleBox;
25480
25481   // Represents the co-ordinates of an Element in a way that we can easily
25482   // compute things with such as if it overlaps or intersects with another Element.
25483   // Can initialize it with either a StyleBox or another BoxPosition.
25484   function BoxPosition(obj) {
25485     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
25486
25487     // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
25488     // was passed in and we need to copy the results of 'getBoundingClientRect'
25489     // as the object returned is readonly. All co-ordinate values are in reference
25490     // to the viewport origin (top left).
25491     var lh, height, width, top;
25492     if (obj.div) {
25493       height = obj.div.offsetHeight;
25494       width = obj.div.offsetWidth;
25495       top = obj.div.offsetTop;
25496
25497       var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
25498                   rects.getClientRects && rects.getClientRects();
25499       obj = obj.div.getBoundingClientRect();
25500       // In certain cases the outter div will be slightly larger then the sum of
25501       // the inner div's lines. This could be due to bold text, etc, on some platforms.
25502       // In this case we should get the average line height and use that. This will
25503       // result in the desired behaviour.
25504       lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
25505                  : 0;
25506
25507     }
25508     this.left = obj.left;
25509     this.right = obj.right;
25510     this.top = obj.top || top;
25511     this.height = obj.height || height;
25512     this.bottom = obj.bottom || (top + (obj.height || height));
25513     this.width = obj.width || width;
25514     this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
25515
25516     if (isIE8 && !this.lineHeight) {
25517       this.lineHeight = 13;
25518     }
25519   }
25520
25521   // Move the box along a particular axis. Optionally pass in an amount to move
25522   // the box. If no amount is passed then the default is the line height of the
25523   // box.
25524   BoxPosition.prototype.move = function(axis, toMove) {
25525     toMove = toMove !== undefined ? toMove : this.lineHeight;
25526     switch (axis) {
25527     case "+x":
25528       this.left += toMove;
25529       this.right += toMove;
25530       break;
25531     case "-x":
25532       this.left -= toMove;
25533       this.right -= toMove;
25534       break;
25535     case "+y":
25536       this.top += toMove;
25537       this.bottom += toMove;
25538       break;
25539     case "-y":
25540       this.top -= toMove;
25541       this.bottom -= toMove;
25542       break;
25543     }
25544   };
25545
25546   // Check if this box overlaps another box, b2.
25547   BoxPosition.prototype.overlaps = function(b2) {
25548     return this.left < b2.right &&
25549            this.right > b2.left &&
25550            this.top < b2.bottom &&
25551            this.bottom > b2.top;
25552   };
25553
25554   // Check if this box overlaps any other boxes in boxes.
25555   BoxPosition.prototype.overlapsAny = function(boxes) {
25556     for (var i = 0; i < boxes.length; i++) {
25557       if (this.overlaps(boxes[i])) {
25558         return true;
25559       }
25560     }
25561     return false;
25562   };
25563
25564   // Check if this box is within another box.
25565   BoxPosition.prototype.within = function(container) {
25566     return this.top >= container.top &&
25567            this.bottom <= container.bottom &&
25568            this.left >= container.left &&
25569            this.right <= container.right;
25570   };
25571
25572   // Check if this box is entirely within the container or it is overlapping
25573   // on the edge opposite of the axis direction passed. For example, if "+x" is
25574   // passed and the box is overlapping on the left edge of the container, then
25575   // return true.
25576   BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
25577     switch (axis) {
25578     case "+x":
25579       return this.left < container.left;
25580     case "-x":
25581       return this.right > container.right;
25582     case "+y":
25583       return this.top < container.top;
25584     case "-y":
25585       return this.bottom > container.bottom;
25586     }
25587   };
25588
25589   // Find the percentage of the area that this box is overlapping with another
25590   // box.
25591   BoxPosition.prototype.intersectPercentage = function(b2) {
25592     var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
25593         y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
25594         intersectArea = x * y;
25595     return intersectArea / (this.height * this.width);
25596   };
25597
25598   // Convert the positions from this box to CSS compatible positions using
25599   // the reference container's positions. This has to be done because this
25600   // box's positions are in reference to the viewport origin, whereas, CSS
25601   // values are in referecne to their respective edges.
25602   BoxPosition.prototype.toCSSCompatValues = function(reference) {
25603     return {
25604       top: this.top - reference.top,
25605       bottom: reference.bottom - this.bottom,
25606       left: this.left - reference.left,
25607       right: reference.right - this.right,
25608       height: this.height,
25609       width: this.width
25610     };
25611   };
25612
25613   // Get an object that represents the box's position without anything extra.
25614   // Can pass a StyleBox, HTMLElement, or another BoxPositon.
25615   BoxPosition.getSimpleBoxPosition = function(obj) {
25616     var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
25617     var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
25618     var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
25619
25620     obj = obj.div ? obj.div.getBoundingClientRect() :
25621                   obj.tagName ? obj.getBoundingClientRect() : obj;
25622     var ret = {
25623       left: obj.left,
25624       right: obj.right,
25625       top: obj.top || top,
25626       height: obj.height || height,
25627       bottom: obj.bottom || (top + (obj.height || height)),
25628       width: obj.width || width
25629     };
25630     return ret;
25631   };
25632
25633   // Move a StyleBox to its specified, or next best, position. The containerBox
25634   // is the box that contains the StyleBox, such as a div. boxPositions are
25635   // a list of other boxes that the styleBox can't overlap with.
25636   function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
25637
25638     // Find the best position for a cue box, b, on the video. The axis parameter
25639     // is a list of axis, the order of which, it will move the box along. For example:
25640     // Passing ["+x", "-x"] will move the box first along the x axis in the positive
25641     // direction. If it doesn't find a good position for it there it will then move
25642     // it along the x axis in the negative direction.
25643     function findBestPosition(b, axis) {
25644       var bestPosition,
25645           specifiedPosition = new BoxPosition(b),
25646           percentage = 1; // Highest possible so the first thing we get is better.
25647
25648       for (var i = 0; i < axis.length; i++) {
25649         while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
25650                (b.within(containerBox) && b.overlapsAny(boxPositions))) {
25651           b.move(axis[i]);
25652         }
25653         // We found a spot where we aren't overlapping anything. This is our
25654         // best position.
25655         if (b.within(containerBox)) {
25656           return b;
25657         }
25658         var p = b.intersectPercentage(containerBox);
25659         // If we're outside the container box less then we were on our last try
25660         // then remember this position as the best position.
25661         if (percentage > p) {
25662           bestPosition = new BoxPosition(b);
25663           percentage = p;
25664         }
25665         // Reset the box position to the specified position.
25666         b = new BoxPosition(specifiedPosition);
25667       }
25668       return bestPosition || specifiedPosition;
25669     }
25670
25671     var boxPosition = new BoxPosition(styleBox),
25672         cue = styleBox.cue,
25673         linePos = computeLinePos(cue),
25674         axis = [];
25675
25676     // If we have a line number to align the cue to.
25677     if (cue.snapToLines) {
25678       var size;
25679       switch (cue.vertical) {
25680       case "":
25681         axis = [ "+y", "-y" ];
25682         size = "height";
25683         break;
25684       case "rl":
25685         axis = [ "+x", "-x" ];
25686         size = "width";
25687         break;
25688       case "lr":
25689         axis = [ "-x", "+x" ];
25690         size = "width";
25691         break;
25692       }
25693
25694       var step = boxPosition.lineHeight,
25695           position = step * Math.round(linePos),
25696           maxPosition = containerBox[size] + step,
25697           initialAxis = axis[0];
25698
25699       // If the specified intial position is greater then the max position then
25700       // clamp the box to the amount of steps it would take for the box to
25701       // reach the max position.
25702       if (Math.abs(position) > maxPosition) {
25703         position = position < 0 ? -1 : 1;
25704         position *= Math.ceil(maxPosition / step) * step;
25705       }
25706
25707       // If computed line position returns negative then line numbers are
25708       // relative to the bottom of the video instead of the top. Therefore, we
25709       // need to increase our initial position by the length or width of the
25710       // video, depending on the writing direction, and reverse our axis directions.
25711       if (linePos < 0) {
25712         position += cue.vertical === "" ? containerBox.height : containerBox.width;
25713         axis = axis.reverse();
25714       }
25715
25716       // Move the box to the specified position. This may not be its best
25717       // position.
25718       boxPosition.move(initialAxis, position);
25719
25720     } else {
25721       // If we have a percentage line value for the cue.
25722       var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
25723
25724       switch (cue.lineAlign) {
25725       case "middle":
25726         linePos -= (calculatedPercentage / 2);
25727         break;
25728       case "end":
25729         linePos -= calculatedPercentage;
25730         break;
25731       }
25732
25733       // Apply initial line position to the cue box.
25734       switch (cue.vertical) {
25735       case "":
25736         styleBox.applyStyles({
25737           top: styleBox.formatStyle(linePos, "%")
25738         });
25739         break;
25740       case "rl":
25741         styleBox.applyStyles({
25742           left: styleBox.formatStyle(linePos, "%")
25743         });
25744         break;
25745       case "lr":
25746         styleBox.applyStyles({
25747           right: styleBox.formatStyle(linePos, "%")
25748         });
25749         break;
25750       }
25751
25752       axis = [ "+y", "-x", "+x", "-y" ];
25753
25754       // Get the box position again after we've applied the specified positioning
25755       // to it.
25756       boxPosition = new BoxPosition(styleBox);
25757     }
25758
25759     var bestPosition = findBestPosition(boxPosition, axis);
25760     styleBox.move(bestPosition.toCSSCompatValues(containerBox));
25761   }
25762
25763   function WebVTT() {
25764     // Nothing
25765   }
25766
25767   // Helper to allow strings to be decoded instead of the default binary utf8 data.
25768   WebVTT.StringDecoder = function() {
25769     return {
25770       decode: function(data) {
25771         if (!data) {
25772           return "";
25773         }
25774         if (typeof data !== "string") {
25775           throw new Error("Error - expected string data.");
25776         }
25777         return decodeURIComponent(encodeURIComponent(data));
25778       }
25779     };
25780   };
25781
25782   WebVTT.convertCueToDOMTree = function(window, cuetext) {
25783     if (!window || !cuetext) {
25784       return null;
25785     }
25786     return parseContent(window, cuetext);
25787   };
25788
25789   var FONT_SIZE_PERCENT = 0.05;
25790   var FONT_STYLE = "sans-serif";
25791   var CUE_BACKGROUND_PADDING = "1.5%";
25792
25793   // Runs the processing model over the cues and regions passed to it.
25794   // @param overlay A block level element (usually a div) that the computed cues
25795   //                and regions will be placed into.
25796   WebVTT.processCues = function(window, cues, overlay) {
25797     if (!window || !cues || !overlay) {
25798       return null;
25799     }
25800
25801     // Remove all previous children.
25802     while (overlay.firstChild) {
25803       overlay.removeChild(overlay.firstChild);
25804     }
25805
25806     var paddedOverlay = window.document.createElement("div");
25807     paddedOverlay.style.position = "absolute";
25808     paddedOverlay.style.left = "0";
25809     paddedOverlay.style.right = "0";
25810     paddedOverlay.style.top = "0";
25811     paddedOverlay.style.bottom = "0";
25812     paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
25813     overlay.appendChild(paddedOverlay);
25814
25815     // Determine if we need to compute the display states of the cues. This could
25816     // be the case if a cue's state has been changed since the last computation or
25817     // if it has not been computed yet.
25818     function shouldCompute(cues) {
25819       for (var i = 0; i < cues.length; i++) {
25820         if (cues[i].hasBeenReset || !cues[i].displayState) {
25821           return true;
25822         }
25823       }
25824       return false;
25825     }
25826
25827     // We don't need to recompute the cues' display states. Just reuse them.
25828     if (!shouldCompute(cues)) {
25829       for (var i = 0; i < cues.length; i++) {
25830         paddedOverlay.appendChild(cues[i].displayState);
25831       }
25832       return;
25833     }
25834
25835     var boxPositions = [],
25836         containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
25837         fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
25838     var styleOptions = {
25839       font: fontSize + "px " + FONT_STYLE
25840     };
25841
25842     (function() {
25843       var styleBox, cue;
25844
25845       for (var i = 0; i < cues.length; i++) {
25846         cue = cues[i];
25847
25848         // Compute the intial position and styles of the cue div.
25849         styleBox = new CueStyleBox(window, cue, styleOptions);
25850         paddedOverlay.appendChild(styleBox.div);
25851
25852         // Move the cue div to it's correct line position.
25853         moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
25854
25855         // Remember the computed div so that we don't have to recompute it later
25856         // if we don't have too.
25857         cue.displayState = styleBox.div;
25858
25859         boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
25860       }
25861     })();
25862   };
25863
25864   WebVTT.Parser = function(window, vttjs, decoder) {
25865     if (!decoder) {
25866       decoder = vttjs;
25867       vttjs = {};
25868     }
25869     if (!vttjs) {
25870       vttjs = {};
25871     }
25872
25873     this.window = window;
25874     this.vttjs = vttjs;
25875     this.state = "INITIAL";
25876     this.buffer = "";
25877     this.decoder = decoder || new TextDecoder("utf8");
25878     this.regionList = [];
25879   };
25880
25881   WebVTT.Parser.prototype = {
25882     // If the error is a ParsingError then report it to the consumer if
25883     // possible. If it's not a ParsingError then throw it like normal.
25884     reportOrThrowError: function(e) {
25885       if (e instanceof ParsingError) {
25886         this.onparsingerror && this.onparsingerror(e);
25887       } else {
25888         throw e;
25889       }
25890     },
25891     parse: function (data) {
25892       var self = this;
25893
25894       // If there is no data then we won't decode it, but will just try to parse
25895       // whatever is in buffer already. This may occur in circumstances, for
25896       // example when flush() is called.
25897       if (data) {
25898         // Try to decode the data that we received.
25899         self.buffer += self.decoder.decode(data, {stream: true});
25900       }
25901
25902       function collectNextLine() {
25903         var buffer = self.buffer;
25904         var pos = 0;
25905         while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
25906           ++pos;
25907         }
25908         var line = buffer.substr(0, pos);
25909         // Advance the buffer early in case we fail below.
25910         if (buffer[pos] === '\r') {
25911           ++pos;
25912         }
25913         if (buffer[pos] === '\n') {
25914           ++pos;
25915         }
25916         self.buffer = buffer.substr(pos);
25917         return line;
25918       }
25919
25920       // 3.4 WebVTT region and WebVTT region settings syntax
25921       function parseRegion(input) {
25922         var settings = new Settings();
25923
25924         parseOptions(input, function (k, v) {
25925           switch (k) {
25926           case "id":
25927             settings.set(k, v);
25928             break;
25929           case "width":
25930             settings.percent(k, v);
25931             break;
25932           case "lines":
25933             settings.integer(k, v);
25934             break;
25935           case "regionanchor":
25936           case "viewportanchor":
25937             var xy = v.split(',');
25938             if (xy.length !== 2) {
25939               break;
25940             }
25941             // We have to make sure both x and y parse, so use a temporary
25942             // settings object here.
25943             var anchor = new Settings();
25944             anchor.percent("x", xy[0]);
25945             anchor.percent("y", xy[1]);
25946             if (!anchor.has("x") || !anchor.has("y")) {
25947               break;
25948             }
25949             settings.set(k + "X", anchor.get("x"));
25950             settings.set(k + "Y", anchor.get("y"));
25951             break;
25952           case "scroll":
25953             settings.alt(k, v, ["up"]);
25954             break;
25955           }
25956         }, /=/, /\s/);
25957
25958         // Create the region, using default values for any values that were not
25959         // specified.
25960         if (settings.has("id")) {
25961           var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
25962           region.width = settings.get("width", 100);
25963           region.lines = settings.get("lines", 3);
25964           region.regionAnchorX = settings.get("regionanchorX", 0);
25965           region.regionAnchorY = settings.get("regionanchorY", 100);
25966           region.viewportAnchorX = settings.get("viewportanchorX", 0);
25967           region.viewportAnchorY = settings.get("viewportanchorY", 100);
25968           region.scroll = settings.get("scroll", "");
25969           // Register the region.
25970           self.onregion && self.onregion(region);
25971           // Remember the VTTRegion for later in case we parse any VTTCues that
25972           // reference it.
25973           self.regionList.push({
25974             id: settings.get("id"),
25975             region: region
25976           });
25977         }
25978       }
25979
25980       // draft-pantos-http-live-streaming-20
25981       // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5
25982       // 3.5 WebVTT
25983       function parseTimestampMap(input) {
25984         var settings = new Settings();
25985
25986         parseOptions(input, function(k, v) {
25987           switch(k) {
25988           case "MPEGT":
25989             settings.integer(k + 'S', v);
25990             break;
25991           case "LOCA":
25992             settings.set(k + 'L', parseTimeStamp(v));
25993             break;
25994           }
25995         }, /[^\d]:/, /,/);
25996
25997         self.ontimestampmap && self.ontimestampmap({
25998           "MPEGTS": settings.get("MPEGTS"),
25999           "LOCAL": settings.get("LOCAL")
26000         });
26001       }
26002
26003       // 3.2 WebVTT metadata header syntax
26004       function parseHeader(input) {
26005         if (input.match(/X-TIMESTAMP-MAP/)) {
26006           // This line contains HLS X-TIMESTAMP-MAP metadata
26007           parseOptions(input, function(k, v) {
26008             switch(k) {
26009             case "X-TIMESTAMP-MAP":
26010               parseTimestampMap(v);
26011               break;
26012             }
26013           }, /=/);
26014         } else {
26015           parseOptions(input, function (k, v) {
26016             switch (k) {
26017             case "Region":
26018               // 3.3 WebVTT region metadata header syntax
26019               parseRegion(v);
26020               break;
26021             }
26022           }, /:/);
26023         }
26024
26025       }
26026
26027       // 5.1 WebVTT file parsing.
26028       try {
26029         var line;
26030         if (self.state === "INITIAL") {
26031           // We can't start parsing until we have the first line.
26032           if (!/\r\n|\n/.test(self.buffer)) {
26033             return this;
26034           }
26035
26036           line = collectNextLine();
26037
26038           var m = line.match(/^WEBVTT([ \t].*)?$/);
26039           if (!m || !m[0]) {
26040             throw new ParsingError(ParsingError.Errors.BadSignature);
26041           }
26042
26043           self.state = "HEADER";
26044         }
26045
26046         var alreadyCollectedLine = false;
26047         while (self.buffer) {
26048           // We can't parse a line until we have the full line.
26049           if (!/\r\n|\n/.test(self.buffer)) {
26050             return this;
26051           }
26052
26053           if (!alreadyCollectedLine) {
26054             line = collectNextLine();
26055           } else {
26056             alreadyCollectedLine = false;
26057           }
26058
26059           switch (self.state) {
26060           case "HEADER":
26061             // 13-18 - Allow a header (metadata) under the WEBVTT line.
26062             if (/:/.test(line)) {
26063               parseHeader(line);
26064             } else if (!line) {
26065               // An empty line terminates the header and starts the body (cues).
26066               self.state = "ID";
26067             }
26068             continue;
26069           case "NOTE":
26070             // Ignore NOTE blocks.
26071             if (!line) {
26072               self.state = "ID";
26073             }
26074             continue;
26075           case "ID":
26076             // Check for the start of NOTE blocks.
26077             if (/^NOTE($|[ \t])/.test(line)) {
26078               self.state = "NOTE";
26079               break;
26080             }
26081             // 19-29 - Allow any number of line terminators, then initialize new cue values.
26082             if (!line) {
26083               continue;
26084             }
26085             self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
26086             self.state = "CUE";
26087             // 30-39 - Check if self line contains an optional identifier or timing data.
26088             if (line.indexOf("-->") === -1) {
26089               self.cue.id = line;
26090               continue;
26091             }
26092             // Process line as start of a cue.
26093             /*falls through*/
26094           case "CUE":
26095             // 40 - Collect cue timings and settings.
26096             try {
26097               parseCue(line, self.cue, self.regionList);
26098             } catch (e) {
26099               self.reportOrThrowError(e);
26100               // In case of an error ignore rest of the cue.
26101               self.cue = null;
26102               self.state = "BADCUE";
26103               continue;
26104             }
26105             self.state = "CUETEXT";
26106             continue;
26107           case "CUETEXT":
26108             var hasSubstring = line.indexOf("-->") !== -1;
26109             // 34 - If we have an empty line then report the cue.
26110             // 35 - If we have the special substring '-->' then report the cue,
26111             // but do not collect the line as we need to process the current
26112             // one as a new cue.
26113             if (!line || hasSubstring && (alreadyCollectedLine = true)) {
26114               // We are done parsing self cue.
26115               self.oncue && self.oncue(self.cue);
26116               self.cue = null;
26117               self.state = "ID";
26118               continue;
26119             }
26120             if (self.cue.text) {
26121               self.cue.text += "\n";
26122             }
26123             self.cue.text += line;
26124             continue;
26125           case "BADCUE": // BADCUE
26126             // 54-62 - Collect and discard the remaining cue.
26127             if (!line) {
26128               self.state = "ID";
26129             }
26130             continue;
26131           }
26132         }
26133       } catch (e) {
26134         self.reportOrThrowError(e);
26135
26136         // If we are currently parsing a cue, report what we have.
26137         if (self.state === "CUETEXT" && self.cue && self.oncue) {
26138           self.oncue(self.cue);
26139         }
26140         self.cue = null;
26141         // Enter BADWEBVTT state if header was not parsed correctly otherwise
26142         // another exception occurred so enter BADCUE state.
26143         self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
26144       }
26145       return this;
26146     },
26147     flush: function () {
26148       var self = this;
26149       try {
26150         // Finish decoding the stream.
26151         self.buffer += self.decoder.decode();
26152         // Synthesize the end of the current cue or region.
26153         if (self.cue || self.state === "HEADER") {
26154           self.buffer += "\n\n";
26155           self.parse();
26156         }
26157         // If we've flushed, parsed, and we're still on the INITIAL state then
26158         // that means we don't have enough of the stream to parse the first
26159         // line.
26160         if (self.state === "INITIAL") {
26161           throw new ParsingError(ParsingError.Errors.BadSignature);
26162         }
26163       } catch(e) {
26164         self.reportOrThrowError(e);
26165       }
26166       self.onflush && self.onflush();
26167       return this;
26168     }
26169   };
26170
26171   global.WebVTT = WebVTT;
26172
26173 }(this, (this.vttjs || {})));
26174
26175 },{}],107:[function(_dereq_,module,exports){
26176 /**
26177  * Copyright 2013 vtt.js Contributors
26178  *
26179  * Licensed under the Apache License, Version 2.0 (the "License");
26180  * you may not use this file except in compliance with the License.
26181  * You may obtain a copy of the License at
26182  *
26183  *   http://www.apache.org/licenses/LICENSE-2.0
26184  *
26185  * Unless required by applicable law or agreed to in writing, software
26186  * distributed under the License is distributed on an "AS IS" BASIS,
26187  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26188  * See the License for the specific language governing permissions and
26189  * limitations under the License.
26190  */
26191
26192 (function(root, vttjs) {
26193
26194   var autoKeyword = "auto";
26195   var directionSetting = {
26196     "": true,
26197     "lr": true,
26198     "rl": true
26199   };
26200   var alignSetting = {
26201     "start": true,
26202     "middle": true,
26203     "end": true,
26204     "left": true,
26205     "right": true
26206   };
26207
26208   function findDirectionSetting(value) {
26209     if (typeof value !== "string") {
26210       return false;
26211     }
26212     var dir = directionSetting[value.toLowerCase()];
26213     return dir ? value.toLowerCase() : false;
26214   }
26215
26216   function findAlignSetting(value) {
26217     if (typeof value !== "string") {
26218       return false;
26219     }
26220     var align = alignSetting[value.toLowerCase()];
26221     return align ? value.toLowerCase() : false;
26222   }
26223
26224   function extend(obj) {
26225     var i = 1;
26226     for (; i < arguments.length; i++) {
26227       var cobj = arguments[i];
26228       for (var p in cobj) {
26229         obj[p] = cobj[p];
26230       }
26231     }
26232
26233     return obj;
26234   }
26235
26236   function VTTCue(startTime, endTime, text) {
26237     var cue = this;
26238     var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
26239     var baseObj = {};
26240
26241     if (isIE8) {
26242       cue = document.createElement('custom');
26243     } else {
26244       baseObj.enumerable = true;
26245     }
26246
26247     /**
26248      * Shim implementation specific properties. These properties are not in
26249      * the spec.
26250      */
26251
26252     // Lets us know when the VTTCue's data has changed in such a way that we need
26253     // to recompute its display state. This lets us compute its display state
26254     // lazily.
26255     cue.hasBeenReset = false;
26256
26257     /**
26258      * VTTCue and TextTrackCue properties
26259      * http://dev.w3.org/html5/webvtt/#vttcue-interface
26260      */
26261
26262     var _id = "";
26263     var _pauseOnExit = false;
26264     var _startTime = startTime;
26265     var _endTime = endTime;
26266     var _text = text;
26267     var _region = null;
26268     var _vertical = "";
26269     var _snapToLines = true;
26270     var _line = "auto";
26271     var _lineAlign = "start";
26272     var _position = 50;
26273     var _positionAlign = "middle";
26274     var _size = 50;
26275     var _align = "middle";
26276
26277     Object.defineProperty(cue,
26278       "id", extend({}, baseObj, {
26279         get: function() {
26280           return _id;
26281         },
26282         set: function(value) {
26283           _id = "" + value;
26284         }
26285       }));
26286
26287     Object.defineProperty(cue,
26288       "pauseOnExit", extend({}, baseObj, {
26289         get: function() {
26290           return _pauseOnExit;
26291         },
26292         set: function(value) {
26293           _pauseOnExit = !!value;
26294         }
26295       }));
26296
26297     Object.defineProperty(cue,
26298       "startTime", extend({}, baseObj, {
26299         get: function() {
26300           return _startTime;
26301         },
26302         set: function(value) {
26303           if (typeof value !== "number") {
26304             throw new TypeError("Start time must be set to a number.");
26305           }
26306           _startTime = value;
26307           this.hasBeenReset = true;
26308         }
26309       }));
26310
26311     Object.defineProperty(cue,
26312       "endTime", extend({}, baseObj, {
26313         get: function() {
26314           return _endTime;
26315         },
26316         set: function(value) {
26317           if (typeof value !== "number") {
26318             throw new TypeError("End time must be set to a number.");
26319           }
26320           _endTime = value;
26321           this.hasBeenReset = true;
26322         }
26323       }));
26324
26325     Object.defineProperty(cue,
26326       "text", extend({}, baseObj, {
26327         get: function() {
26328           return _text;
26329         },
26330         set: function(value) {
26331           _text = "" + value;
26332           this.hasBeenReset = true;
26333         }
26334       }));
26335
26336     Object.defineProperty(cue,
26337       "region", extend({}, baseObj, {
26338         get: function() {
26339           return _region;
26340         },
26341         set: function(value) {
26342           _region = value;
26343           this.hasBeenReset = true;
26344         }
26345       }));
26346
26347     Object.defineProperty(cue,
26348       "vertical", extend({}, baseObj, {
26349         get: function() {
26350           return _vertical;
26351         },
26352         set: function(value) {
26353           var setting = findDirectionSetting(value);
26354           // Have to check for false because the setting an be an empty string.
26355           if (setting === false) {
26356             throw new SyntaxError("An invalid or illegal string was specified.");
26357           }
26358           _vertical = setting;
26359           this.hasBeenReset = true;
26360         }
26361       }));
26362
26363     Object.defineProperty(cue,
26364       "snapToLines", extend({}, baseObj, {
26365         get: function() {
26366           return _snapToLines;
26367         },
26368         set: function(value) {
26369           _snapToLines = !!value;
26370           this.hasBeenReset = true;
26371         }
26372       }));
26373
26374     Object.defineProperty(cue,
26375       "line", extend({}, baseObj, {
26376         get: function() {
26377           return _line;
26378         },
26379         set: function(value) {
26380           if (typeof value !== "number" && value !== autoKeyword) {
26381             throw new SyntaxError("An invalid number or illegal string was specified.");
26382           }
26383           _line = value;
26384           this.hasBeenReset = true;
26385         }
26386       }));
26387
26388     Object.defineProperty(cue,
26389       "lineAlign", extend({}, baseObj, {
26390         get: function() {
26391           return _lineAlign;
26392         },
26393         set: function(value) {
26394           var setting = findAlignSetting(value);
26395           if (!setting) {
26396             throw new SyntaxError("An invalid or illegal string was specified.");
26397           }
26398           _lineAlign = setting;
26399           this.hasBeenReset = true;
26400         }
26401       }));
26402
26403     Object.defineProperty(cue,
26404       "position", extend({}, baseObj, {
26405         get: function() {
26406           return _position;
26407         },
26408         set: function(value) {
26409           if (value < 0 || value > 100) {
26410             throw new Error("Position must be between 0 and 100.");
26411           }
26412           _position = value;
26413           this.hasBeenReset = true;
26414         }
26415       }));
26416
26417     Object.defineProperty(cue,
26418       "positionAlign", extend({}, baseObj, {
26419         get: function() {
26420           return _positionAlign;
26421         },
26422         set: function(value) {
26423           var setting = findAlignSetting(value);
26424           if (!setting) {
26425             throw new SyntaxError("An invalid or illegal string was specified.");
26426           }
26427           _positionAlign = setting;
26428           this.hasBeenReset = true;
26429         }
26430       }));
26431
26432     Object.defineProperty(cue,
26433       "size", extend({}, baseObj, {
26434         get: function() {
26435           return _size;
26436         },
26437         set: function(value) {
26438           if (value < 0 || value > 100) {
26439             throw new Error("Size must be between 0 and 100.");
26440           }
26441           _size = value;
26442           this.hasBeenReset = true;
26443         }
26444       }));
26445
26446     Object.defineProperty(cue,
26447       "align", extend({}, baseObj, {
26448         get: function() {
26449           return _align;
26450         },
26451         set: function(value) {
26452           var setting = findAlignSetting(value);
26453           if (!setting) {
26454             throw new SyntaxError("An invalid or illegal string was specified.");
26455           }
26456           _align = setting;
26457           this.hasBeenReset = true;
26458         }
26459       }));
26460
26461     /**
26462      * Other <track> spec defined properties
26463      */
26464
26465     // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
26466     cue.displayState = undefined;
26467
26468     if (isIE8) {
26469       return cue;
26470     }
26471   }
26472
26473   /**
26474    * VTTCue methods
26475    */
26476
26477   VTTCue.prototype.getCueAsHTML = function() {
26478     // Assume WebVTT.convertCueToDOMTree is on the global.
26479     return WebVTT.convertCueToDOMTree(window, this.text);
26480   };
26481
26482   root.VTTCue = root.VTTCue || VTTCue;
26483   vttjs.VTTCue = VTTCue;
26484 }(this, (this.vttjs || {})));
26485
26486 },{}],108:[function(_dereq_,module,exports){
26487 /**
26488  * Copyright 2013 vtt.js Contributors
26489  *
26490  * Licensed under the Apache License, Version 2.0 (the "License");
26491  * you may not use this file except in compliance with the License.
26492  * You may obtain a copy of the License at
26493  *
26494  *   http://www.apache.org/licenses/LICENSE-2.0
26495  *
26496  * Unless required by applicable law or agreed to in writing, software
26497  * distributed under the License is distributed on an "AS IS" BASIS,
26498  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26499  * See the License for the specific language governing permissions and
26500  * limitations under the License.
26501  */
26502
26503 (function(root, vttjs) {
26504
26505   var scrollSetting = {
26506     "": true,
26507     "up": true
26508   };
26509
26510   function findScrollSetting(value) {
26511     if (typeof value !== "string") {
26512       return false;
26513     }
26514     var scroll = scrollSetting[value.toLowerCase()];
26515     return scroll ? value.toLowerCase() : false;
26516   }
26517
26518   function isValidPercentValue(value) {
26519     return typeof value === "number" && (value >= 0 && value <= 100);
26520   }
26521
26522   // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
26523   function VTTRegion() {
26524     var _width = 100;
26525     var _lines = 3;
26526     var _regionAnchorX = 0;
26527     var _regionAnchorY = 100;
26528     var _viewportAnchorX = 0;
26529     var _viewportAnchorY = 100;
26530     var _scroll = "";
26531
26532     Object.defineProperties(this, {
26533       "width": {
26534         enumerable: true,
26535         get: function() {
26536           return _width;
26537         },
26538         set: function(value) {
26539           if (!isValidPercentValue(value)) {
26540             throw new Error("Width must be between 0 and 100.");
26541           }
26542           _width = value;
26543         }
26544       },
26545       "lines": {
26546         enumerable: true,
26547         get: function() {
26548           return _lines;
26549         },
26550         set: function(value) {
26551           if (typeof value !== "number") {
26552             throw new TypeError("Lines must be set to a number.");
26553           }
26554           _lines = value;
26555         }
26556       },
26557       "regionAnchorY": {
26558         enumerable: true,
26559         get: function() {
26560           return _regionAnchorY;
26561         },
26562         set: function(value) {
26563           if (!isValidPercentValue(value)) {
26564             throw new Error("RegionAnchorX must be between 0 and 100.");
26565           }
26566           _regionAnchorY = value;
26567         }
26568       },
26569       "regionAnchorX": {
26570         enumerable: true,
26571         get: function() {
26572           return _regionAnchorX;
26573         },
26574         set: function(value) {
26575           if(!isValidPercentValue(value)) {
26576             throw new Error("RegionAnchorY must be between 0 and 100.");
26577           }
26578           _regionAnchorX = value;
26579         }
26580       },
26581       "viewportAnchorY": {
26582         enumerable: true,
26583         get: function() {
26584           return _viewportAnchorY;
26585         },
26586         set: function(value) {
26587           if (!isValidPercentValue(value)) {
26588             throw new Error("ViewportAnchorY must be between 0 and 100.");
26589           }
26590           _viewportAnchorY = value;
26591         }
26592       },
26593       "viewportAnchorX": {
26594         enumerable: true,
26595         get: function() {
26596           return _viewportAnchorX;
26597         },
26598         set: function(value) {
26599           if (!isValidPercentValue(value)) {
26600             throw new Error("ViewportAnchorX must be between 0 and 100.");
26601           }
26602           _viewportAnchorX = value;
26603         }
26604       },
26605       "scroll": {
26606         enumerable: true,
26607         get: function() {
26608           return _scroll;
26609         },
26610         set: function(value) {
26611           var setting = findScrollSetting(value);
26612           // Have to check for false as an empty string is a legal value.
26613           if (setting === false) {
26614             throw new SyntaxError("An invalid or illegal string was specified.");
26615           }
26616           _scroll = setting;
26617         }
26618       }
26619     });
26620   }
26621
26622   root.VTTRegion = root.VTTRegion || VTTRegion;
26623   vttjs.VTTRegion = VTTRegion;
26624 }(this, (this.vttjs || {})));
26625
26626 },{}],109:[function(_dereq_,module,exports){
26627 arguments[4][95][0].apply(exports,arguments)
26628 },{"95":95}]},{},[93])(93)
26629 });