PageSourceSearch

https://www.jova.tv/sites/all/themes/jovatv/video-js/video.js?sz50wi

js jova.tv collected 2026-09-26 10:48:55 UTC 767,788 bytes, 24,290 lines download raw bytes

1/**
2 * @license
3 * Video.js 5.10.5 <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(function (global){
15var topLevel = typeof global !== 'undefined' ? global :
16    typeof window !== 'undefined' ? window : {}
17var minDoc = _dereq_('min-document');
18
19if (typeof document !== 'undefined') {
20    module.exports = document;
21} else {
22    var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
23
24    if (!doccy) {
25        doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
26    }
27
28    module.exports = doccy;
29}
30
31}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
32//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvZG9jdW1lbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgdG9wTGV2ZWwgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6XG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fVxudmFyIG1pbkRvYyA9IHJlcXVpcmUoJ21pbi1kb2N1bWVudCcpO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQ7XG59IGVsc2Uge1xuICAgIHZhciBkb2NjeSA9IHRvcExldmVsWydfX0dMT0JBTF9ET0NVTUVOVF9DQUNIRUA0J107XG5cbiAgICBpZiAoIWRvY2N5KSB7XG4gICAgICAgIGRvY2N5ID0gdG9wTGV2ZWxbJ19fR0xPQkFMX0RPQ1VNRU5UX0NBQ0hFQDQnXSA9IG1pbkRvYztcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRvY2N5O1xufVxuIl19
33},{"min-document":3}],2:[function(_dereq_,module,exports){
34(function (global){
35if (typeof window !== "undefined") {
36    module.exports = window;
37} else if (typeof global !== "undefined") {
38    module.exports = global;
39} else if (typeof self !== "undefined"){
40    module.exports = self;
41} else {
42    module.exports = {};
43}
44
45}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
46//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvd2luZG93LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzZWxmO1xufSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHt9O1xufVxuIl19
47},{}],3:[function(_dereq_,module,exports){
48
49},{}],4:[function(_dereq_,module,exports){
50var getNative = _dereq_('../internal/getNative');
51
52/* Native method references for those with the same name as other `lodash` methods. */
53var nativeNow = getNative(Date, 'now');
54
55/**
56 * Gets the number of milliseconds that have elapsed since the Unix epoch
57 * (1 January 1970 00:00:00 UTC).
58 *
59 * @static
60 * @memberOf _
61 * @category Date
62 * @example
63 *
64 * _.defer(function(stamp) {
65 *   console.log(_.now() - stamp);
66 * }, _.now());
67 * // => logs the number of milliseconds it took for the deferred function to be invoked
68 */
69var now = nativeNow || function() {
70  return new Date().getTime();
71};
72
73module.exports = now;
74
75},{"../internal/getNative":20}],5:[function(_dereq_,module,exports){
76var isObject = _dereq_('../lang/isObject'),
77    now = _dereq_('../date/now');
78
79/** Used as the `TypeError` message for "Functions" methods. */
vendor: 16,886 bytes, lines 80-600
80var FUNC_ERROR_TEXT = 'Expected a function';
81
82/* Native method references for those with the same name as other `lodash` methods. */
83var nativeMax = Math.max;
84
85/**
86 * Creates a debounced function that delays invoking `func` until after `wait`
87 * milliseconds have elapsed since the last time the debounced function was
88 * invoked. The debounced function comes with a `cancel` method to cancel
89 * delayed invocations. Provide an options object to indicate that `func`
90 * should be invoked on the leading and/or trailing edge of the `wait` timeout.
91 * Subsequent calls to the debounced function return the result of the last
92 * `func` invocation.
93 *
94 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
95 * on the trailing edge of the timeout only if the the debounced function is
96 * invoked more than once during the `wait` timeout.
97 *
98 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
99 * for details over the differences between `_.debounce` and `_.throttle`.
100 *
101 * @static
102 * @memberOf _
103 * @category Function
104 * @param {Function} func The function to debounce.
105 * @param {number} [wait=0] The number of milliseconds to delay.
106 * @param {Object} [options] The options object.
107 * @param {boolean} [options.leading=false] Specify invoking on the leading
108 *  edge of the timeout.
109 * @param {number} [options.maxWait] The maximum time `func` is allowed to be
110 *  delayed before it's invoked.
111 * @param {boolean} [options.trailing=true] Specify invoking on the trailing
112 *  edge of the timeout.
113 * @returns {Function} Returns the new debounced function.
114 * @example
115 *
116 * // avoid costly calculations while the window size is in flux
117 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
118 *
119 * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
120 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
121 *   'leading': true,
122 *   'trailing': false
123 * }));
124 *
125 * // ensure `batchLog` is invoked once after 1 second of debounced calls
126 * var source = new EventSource('/stream');
127 * jQuery(source).on('message', _.debounce(batchLog, 250, {
128 *   'maxWait': 1000
129 * }));
130 *
131 * // cancel a debounced call
132 * var todoChanges = _.debounce(batchLog, 1000);
133 * Object.observe(models.todo, todoChanges);
134 *
135 * Object.observe(models, function(changes) {
136 *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
137 *     todoChanges.cancel();
138 *   }
139 * }, ['delete']);
140 *
141 * // ...at some point `models.todo` is changed
142 * models.todo.completed = true;
143 *
144 * // ...before 1 second has passed `models.todo` is deleted
145 * // which cancels the debounced `todoChanges` call
146 * delete models.todo;
147 */
148function debounce(func, wait, options) {
149  var args,
150      maxTimeoutId,
151      result,
152      stamp,
153      thisArg,
154      timeoutId,
155      trailingCall,
156      lastCalled = 0,
157      maxWait = false,
158      trailing = true;
159
160  if (typeof func != 'function') {
161    throw new TypeError(FUNC_ERROR_TEXT);
162  }
163  wait = wait < 0 ? 0 : (+wait || 0);
164  if (options === true) {
165    var leading = true;
166    trailing = false;
167  } else if (isObject(options)) {
168    leading = !!options.leading;
169    maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
170    trailing = 'trailing' in options ? !!options.trailing : trailing;
171  }
172
173  function cancel() {
174    if (timeoutId) {
175      clearTimeout(timeoutId);
176    }
177    if (maxTimeoutId) {
178      clearTimeout(maxTimeoutId);
179    }
180    lastCalled = 0;
181    maxTimeoutId = timeoutId = trailingCall = undefined;
182  }
183
184  function complete(isCalled, id) {
185    if (id) {
186      clearTimeout(id);
187    }
188    maxTimeoutId = timeoutId = trailingCall = undefined;
189    if (isCalled) {
190      lastCalled = now();
191      result = func.apply(thisArg, args);
192      if (!timeoutId && !maxTimeoutId) {
193        args = thisArg = undefined;
194      }
195    }
196  }
197
198  function delayed() {
199    var remaining = wait - (now() - stamp);
200    if (remaining <= 0 || remaining > wait) {
201      complete(trailingCall, maxTimeoutId);
202    } else {
203      timeoutId = setTimeout(delayed, remaining);
204    }
205  }
206
207  function maxDelayed() {
208    complete(trailing, timeoutId);
209  }
210
211  function debounced() {
212    args = arguments;
213    stamp = now();
214    thisArg = this;
215    trailingCall = trailing && (timeoutId || !leading);
216
217    if (maxWait === false) {
218      var leadingCall = leading && !timeoutId;
219    } else {
220      if (!maxTimeoutId && !leading) {
221        lastCalled = stamp;
222      }
223      var remaining = maxWait - (stamp - lastCalled),
224          isCalled = remaining <= 0 || remaining > maxWait;
225
226      if (isCalled) {
227        if (maxTimeoutId) {
228          maxTimeoutId = clearTimeout(maxTimeoutId);
229        }
230        lastCalled = stamp;
231        result = func.apply(thisArg, args);
232      }
233      else if (!maxTimeoutId) {
234        maxTimeoutId = setTimeout(maxDelayed, remaining);
235      }
236    }
237    if (isCalled && timeoutId) {
238      timeoutId = clearTimeout(timeoutId);
239    }
240    else if (!timeoutId && wait !== maxWait) {
241      timeoutId = setTimeout(delayed, wait);
242    }
243    if (leadingCall) {
244      isCalled = true;
245      result = func.apply(thisArg, args);
246    }
247    if (isCalled && !timeoutId && !maxTimeoutId) {
248      args = thisArg = undefined;
249    }
250    return result;
251  }
252  debounced.cancel = cancel;
253  return debounced;
254}
255
256module.exports = debounce;
257
258},{"../date/now":4,"../lang/isObject":33}],6:[function(_dereq_,module,exports){
259/** Used as the `TypeError` message for "Functions" methods. */
260var FUNC_ERROR_TEXT = 'Expected a function';
261
262/* Native method references for those with the same name as other `lodash` methods. */
263var nativeMax = Math.max;
264
265/**
266 * Creates a function that invokes `func` with the `this` binding of the
267 * created function and arguments from `start` and beyond provided as an array.
268 *
269 * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
270 *
271 * @static
272 * @memberOf _
273 * @category Function
274 * @param {Function} func The function to apply a rest parameter to.
275 * @param {number} [start=func.length-1] The start position of the rest parameter.
276 * @returns {Function} Returns the new function.
277 * @example
278 *
279 * var say = _.restParam(function(what, names) {
280 *   return what + ' ' + _.initial(names).join(', ') +
281 *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
282 * });
283 *
284 * say('hello', 'fred', 'barney', 'pebbles');
285 * // => 'hello fred, barney, & pebbles'
286 */
287function restParam(func, start) {
288  if (typeof func != 'function') {
289    throw new TypeError(FUNC_ERROR_TEXT);
290  }
291  start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
292  return function() {
293    var args = arguments,
294        index = -1,
295        length = nativeMax(args.length - start, 0),
296        rest = Array(length);
297
298    while (++index < length) {
299      rest[index] = args[start + index];
300    }
301    switch (start) {
302      case 0: return func.call(this, rest);
303      case 1: return func.call(this, args[0], rest);
304      case 2: return func.call(this, args[0], args[1], rest);
305    }
306    var otherArgs = Array(start + 1);
307    index = -1;
308    while (++index < start) {
309      otherArgs[index] = args[index];
310    }
311    otherArgs[start] = rest;
312    return func.apply(this, otherArgs);
313  };
314}
315
316module.exports = restParam;
317
318},{}],7:[function(_dereq_,module,exports){
319var debounce = _dereq_('./debounce'),
320    isObject = _dereq_('../lang/isObject');
321
322/** Used as the `TypeError` message for "Functions" methods. */
323var FUNC_ERROR_TEXT = 'Expected a function';
324
325/**
326 * Creates a throttled function that only invokes `func` at most once per
327 * every `wait` milliseconds. The throttled function comes with a `cancel`
328 * method to cancel delayed invocations. Provide an options object to indicate
329 * that `func` should be invoked on the leading and/or trailing edge of the
330 * `wait` timeout. Subsequent calls to the throttled function return the
331 * result of the last `func` call.
332 *
333 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
334 * on the trailing edge of the timeout only if the the throttled function is
335 * invoked more than once during the `wait` timeout.
336 *
337 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
338 * for details over the differences between `_.throttle` and `_.debounce`.
339 *
340 * @static
341 * @memberOf _
342 * @category Function
343 * @param {Function} func The function to throttle.
344 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
345 * @param {Object} [options] The options object.
346 * @param {boolean} [options.leading=true] Specify invoking on the leading
347 *  edge of the timeout.
348 * @param {boolean} [options.trailing=true] Specify invoking on the trailing
349 *  edge of the timeout.
350 * @returns {Function} Returns the new throttled function.
351 * @example
352 *
353 * // avoid excessively updating the position while scrolling
354 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
355 *
356 * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
357 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
358 *   'trailing': false
359 * }));
360 *
361 * // cancel a trailing throttled call
362 * jQuery(window).on('popstate', throttled.cancel);
363 */
364function throttle(func, wait, options) {
365  var leading = true,
366      trailing = true;
367
368  if (typeof func != 'function') {
369    throw new TypeError(FUNC_ERROR_TEXT);
370  }
371  if (options === false) {
372    leading = false;
373  } else if (isObject(options)) {
374    leading = 'leading' in options ? !!options.leading : leading;
375    trailing = 'trailing' in options ? !!options.trailing : trailing;
376  }
377  return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
378}
379
380module.exports = throttle;
381
382},{"../lang/isObject":33,"./debounce":5}],8:[function(_dereq_,module,exports){
383/**
384 * Copies the values of `source` to `array`.
385 *
386 * @private
387 * @param {Array} source The array to copy values from.
388 * @param {Array} [array=[]] The array to copy values to.
389 * @returns {Array} Returns `array`.
390 */
391function arrayCopy(source, array) {
392  var index = -1,
393      length = source.length;
394
395  array || (array = Array(length));
396  while (++index < length) {
397    array[index] = source[index];
398  }
399  return array;
400}
401
402module.exports = arrayCopy;
403
404},{}],9:[function(_dereq_,module,exports){
405/**
406 * A specialized version of `_.forEach` for arrays without support for callback
407 * shorthands and `this` binding.
408 *
409 * @private
410 * @param {Array} array The array to iterate over.
411 * @param {Function} iteratee The function invoked per iteration.
412 * @returns {Array} Returns `array`.
413 */
414function arrayEach(array, iteratee) {
415  var index = -1,
416      length = array.length;
417
418  while (++index < length) {
419    if (iteratee(array[index], index, array) === false) {
420      break;
421    }
422  }
423  return array;
424}
425
426module.exports = arrayEach;
427
428},{}],10:[function(_dereq_,module,exports){
429/**
430 * Copies properties of `source` to `object`.
431 *
432 * @private
433 * @param {Object} source The object to copy properties from.
434 * @param {Array} props The property names to copy.
435 * @param {Object} [object={}] The object to copy properties to.
436 * @returns {Object} Returns `object`.
437 */
438function baseCopy(source, props, object) {
439  object || (object = {});
440
441  var index = -1,
442      length = props.length;
443
444  while (++index < length) {
445    var key = props[index];
446    object[key] = source[key];
447  }
448  return object;
449}
450
451module.exports = baseCopy;
452
453},{}],11:[function(_dereq_,module,exports){
454var createBaseFor = _dereq_('./createBaseFor');
455
456/**
457 * The base implementation of `baseForIn` and `baseForOwn` which iterates
458 * over `object` properties returned by `keysFunc` invoking `iteratee` for
459 * each property. Iteratee functions may exit iteration early by explicitly
460 * returning `false`.
461 *
462 * @private
463 * @param {Object} object The object to iterate over.
464 * @param {Function} iteratee The function invoked per iteration.
465 * @param {Function} keysFunc The function to get the keys of `object`.
466 * @returns {Object} Returns `object`.
467 */
468var baseFor = createBaseFor();
469
470module.exports = baseFor;
471
472},{"./createBaseFor":18}],12:[function(_dereq_,module,exports){
473var baseFor = _dereq_('./baseFor'),
474    keysIn = _dereq_('../object/keysIn');
475
476/**
477 * The base implementation of `_.forIn` without support for callback
478 * shorthands and `this` binding.
479 *
480 * @private
481 * @param {Object} object The object to iterate over.
482 * @param {Function} iteratee The function invoked per iteration.
483 * @returns {Object} Returns `object`.
484 */
485function baseForIn(object, iteratee) {
486  return baseFor(object, iteratee, keysIn);
487}
488
489module.exports = baseForIn;
490
491},{"../object/keysIn":39,"./baseFor":11}],13:[function(_dereq_,module,exports){
492var arrayEach = _dereq_('./arrayEach'),
493    baseMergeDeep = _dereq_('./baseMergeDeep'),
494    isArray = _dereq_('../lang/isArray'),
495    isArrayLike = _dereq_('./isArrayLike'),
496    isObject = _dereq_('../lang/isObject'),
497    isObjectLike = _dereq_('./isObjectLike'),
498    isTypedArray = _dereq_('../lang/isTypedArray'),
499    keys = _dereq_('../object/keys');
500
501/**
502 * The base implementation of `_.merge` without support for argument juggling,
503 * multiple sources, and `this` binding `customizer` functions.
504 *
505 * @private
506 * @param {Object} object The destination object.
507 * @param {Object} source The source object.
508 * @param {Function} [customizer] The function to customize merged values.
509 * @param {Array} [stackA=[]] Tracks traversed source objects.
510 * @param {Array} [stackB=[]] Associates values with source counterparts.
511 * @returns {Object} Returns `object`.
512 */
513function baseMerge(object, source, customizer, stackA, stackB) {
514  if (!isObject(object)) {
515    return object;
516  }
517  var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
518      props = isSrcArr ? undefined : keys(source);
519
520  arrayEach(props || source, function(srcValue, key) {
521    if (props) {
522      key = srcValue;
523      srcValue = source[key];
524    }
525    if (isObjectLike(srcValue)) {
526      stackA || (stackA = []);
527      stackB || (stackB = []);
528      baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
529    }
530    else {
531      var value = object[key],
532          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
533          isCommon = result === undefined;
534
535      if (isCommon) {
536        result = srcValue;
537      }
538      if ((result !== undefined || (isSrcArr && !(key in object))) &&
539          (isCommon || (result === result ? (result !== value) : (value === value)))) {
540        object[key] = result;
541      }
542    }
543  });
544  return object;
545}
546
547module.exports = baseMerge;
548
549},{"../lang/isArray":30,"../lang/isObject":33,"../lang/isTypedArray":36,"../object/keys":38,"./arrayEach":9,"./baseMergeDeep":14,"./isArrayLike":21,"./isObjectLike":26}],14:[function(_dereq_,module,exports){
550var arrayCopy = _dereq_('./arrayCopy'),
551    isArguments = _dereq_('../lang/isArguments'),
552    isArray = _dereq_('../lang/isArray'),
553    isArrayLike = _dereq_('./isArrayLike'),
554    isPlainObject = _dereq_('../lang/isPlainObject'),
555    isTypedArray = _dereq_('../lang/isTypedArray'),
556    toPlainObject = _dereq_('../lang/toPlainObject');
557
558/**
559 * A specialized version of `baseMerge` for arrays and objects which performs
560 * deep merges and tracks traversed objects enabling objects with circular
561 * references to be merged.
562 *
563 * @private
564 * @param {Object} object The destination object.
565 * @param {Object} source The source object.
566 * @param {string} key The key of the value to merge.
567 * @param {Function} mergeFunc The function to merge values.
568 * @param {Function} [customizer] The function to customize merged values.
569 * @param {Array} [stackA=[]] Tracks traversed source objects.
570 * @param {Array} [stackB=[]] Associates values with source counterparts.
571 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
572 */
573function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
574  var length = stackA.length,
575      srcValue = source[key];
576
577  while (length--) {
578    if (stackA[length] == srcValue) {
579      object[key] = stackB[length];
580      return;
581    }
582  }
583  var value = object[key],
584      result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
585      isCommon = result === undefined;
586
587  if (isCommon) {
588    result = srcValue;
589    if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
590      result = isArray(value)
591        ? value
592        : (isArrayLike(value) ? arrayCopy(value) : []);
593    }
594    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
595      result = isArguments(value)
596        ? toPlainObject(value)
597        : (isPlainObject(value) ? value : {});
598    }
599    else {
600      isCommon = false;
vendor: 8,163 bytes, lines 601-866
601    }
602  }
603  // Add the source value to the stack of traversed objects and associate
604  // it with its merged value.
605  stackA.push(srcValue);
606  stackB.push(result);
607
608  if (isCommon) {
609    // Recursively merge objects and arrays (susceptible to call stack limits).
610    object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
611  } else if (result === result ? (result !== value) : (value === value)) {
612    object[key] = result;
613  }
614}
615
616module.exports = baseMergeDeep;
617
618},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isPlainObject":34,"../lang/isTypedArray":36,"../lang/toPlainObject":37,"./arrayCopy":8,"./isArrayLike":21}],15:[function(_dereq_,module,exports){
619var toObject = _dereq_('./toObject');
620
621/**
622 * The base implementation of `_.property` without support for deep paths.
623 *
624 * @private
625 * @param {string} key The key of the property to get.
626 * @returns {Function} Returns the new function.
627 */
628function baseProperty(key) {
629  return function(object) {
630    return object == null ? undefined : toObject(object)[key];
631  };
632}
633
634module.exports = baseProperty;
635
636},{"./toObject":28}],16:[function(_dereq_,module,exports){
637var identity = _dereq_('../utility/identity');
638
639/**
640 * A specialized version of `baseCallback` which only supports `this` binding
641 * and specifying the number of arguments to provide to `func`.
642 *
643 * @private
644 * @param {Function} func The function to bind.
645 * @param {*} thisArg The `this` binding of `func`.
646 * @param {number} [argCount] The number of arguments to provide to `func`.
647 * @returns {Function} Returns the callback.
648 */
649function bindCallback(func, thisArg, argCount) {
650  if (typeof func != 'function') {
651    return identity;
652  }
653  if (thisArg === undefined) {
654    return func;
655  }
656  switch (argCount) {
657    case 1: return function(value) {
658      return func.call(thisArg, value);
659    };
660    case 3: return function(value, index, collection) {
661      return func.call(thisArg, value, index, collection);
662    };
663    case 4: return function(accumulator, value, index, collection) {
664      return func.call(thisArg, accumulator, value, index, collection);
665    };
666    case 5: return function(value, other, key, object, source) {
667      return func.call(thisArg, value, other, key, object, source);
668    };
669  }
670  return function() {
671    return func.apply(thisArg, arguments);
672  };
673}
674
675module.exports = bindCallback;
676
677},{"../utility/identity":42}],17:[function(_dereq_,module,exports){
678var bindCallback = _dereq_('./bindCallback'),
679    isIterateeCall = _dereq_('./isIterateeCall'),
680    restParam = _dereq_('../function/restParam');
681
682/**
683 * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
684 *
685 * @private
686 * @param {Function} assigner The function to assign values.
687 * @returns {Function} Returns the new assigner function.
688 */
689function createAssigner(assigner) {
690  return restParam(function(object, sources) {
691    var index = -1,
692        length = object == null ? 0 : sources.length,
693        customizer = length > 2 ? sources[length - 2] : undefined,
694        guard = length > 2 ? sources[2] : undefined,
695        thisArg = length > 1 ? sources[length - 1] : undefined;
696
697    if (typeof customizer == 'function') {
698      customizer = bindCallback(customizer, thisArg, 5);
699      length -= 2;
700    } else {
701      customizer = typeof thisArg == 'function' ? thisArg : undefined;
702      length -= (customizer ? 1 : 0);
703    }
704    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
705      customizer = length < 3 ? undefined : customizer;
706      length = 1;
707    }
708    while (++index < length) {
709      var source = sources[index];
710      if (source) {
711        assigner(object, source, customizer);
712      }
713    }
714    return object;
715  });
716}
717
718module.exports = createAssigner;
719
720},{"../function/restParam":6,"./bindCallback":16,"./isIterateeCall":24}],18:[function(_dereq_,module,exports){
721var toObject = _dereq_('./toObject');
722
723/**
724 * Creates a base function for `_.forIn` or `_.forInRight`.
725 *
726 * @private
727 * @param {boolean} [fromRight] Specify iterating from right to left.
728 * @returns {Function} Returns the new base function.
729 */
730function createBaseFor(fromRight) {
731  return function(object, iteratee, keysFunc) {
732    var iterable = toObject(object),
733        props = keysFunc(object),
734        length = props.length,
735        index = fromRight ? length : -1;
736
737    while ((fromRight ? index-- : ++index < length)) {
738      var key = props[index];
739      if (iteratee(iterable[key], key, iterable) === false) {
740        break;
741      }
742    }
743    return object;
744  };
745}
746
747module.exports = createBaseFor;
748
749},{"./toObject":28}],19:[function(_dereq_,module,exports){
750var baseProperty = _dereq_('./baseProperty');
751
752/**
753 * Gets the "length" property value of `object`.
754 *
755 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
756 * that affects Safari on at least iOS 8.1-8.3 ARM64.
757 *
758 * @private
759 * @param {Object} object The object to query.
760 * @returns {*} Returns the "length" value.
761 */
762var getLength = baseProperty('length');
763
764module.exports = getLength;
765
766},{"./baseProperty":15}],20:[function(_dereq_,module,exports){
767var isNative = _dereq_('../lang/isNative');
768
769/**
770 * Gets the native function at `key` of `object`.
771 *
772 * @private
773 * @param {Object} object The object to query.
774 * @param {string} key The key of the method to get.
775 * @returns {*} Returns the function if it's native, else `undefined`.
776 */
777function getNative(object, key) {
778  var value = object == null ? undefined : object[key];
779  return isNative(value) ? value : undefined;
780}
781
782module.exports = getNative;
783
784},{"../lang/isNative":32}],21:[function(_dereq_,module,exports){
785var getLength = _dereq_('./getLength'),
786    isLength = _dereq_('./isLength');
787
788/**
789 * Checks if `value` is array-like.
790 *
791 * @private
792 * @param {*} value The value to check.
793 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
794 */
795function isArrayLike(value) {
796  return value != null && isLength(getLength(value));
797}
798
799module.exports = isArrayLike;
800
801},{"./getLength":19,"./isLength":25}],22:[function(_dereq_,module,exports){
802/**
803 * Checks if `value` is a host object in IE < 9.
804 *
805 * @private
806 * @param {*} value The value to check.
807 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
808 */
809var isHostObject = (function() {
810  try {
811    Object({ 'toString': 0 } + '');
812  } catch(e) {
813    return function() { return false; };
814  }
815  return function(value) {
816    // IE < 9 presents many host objects as `Object` objects that can coerce
817    // to strings despite having improperly defined `toString` methods.
818    return typeof value.toString != 'function' && typeof (value + '') == 'string';
819  };
820}());
821
822module.exports = isHostObject;
823
824},{}],23:[function(_dereq_,module,exports){
825/** Used to detect unsigned integer values. */
826var reIsUint = /^\d+$/;
827
828/**
829 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
830 * of an array-like value.
831 */
832var MAX_SAFE_INTEGER = 9007199254740991;
833
834/**
835 * Checks if `value` is a valid array-like index.
836 *
837 * @private
838 * @param {*} value The value to check.
839 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
840 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
841 */
842function isIndex(value, length) {
843  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
844  length = length == null ? MAX_SAFE_INTEGER : length;
845  return value > -1 && value % 1 == 0 && value < length;
846}
847
848module.exports = isIndex;
849
850},{}],24:[function(_dereq_,module,exports){
851var isArrayLike = _dereq_('./isArrayLike'),
852    isIndex = _dereq_('./isIndex'),
853    isObject = _dereq_('../lang/isObject');
854
855/**
856 * Checks if the provided arguments are from an iteratee call.
857 *
858 * @private
859 * @param {*} value The potential iteratee value argument.
860 * @param {*} index The potential iteratee index or key argument.
861 * @param {*} object The potential iteratee object argument.
862 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
863 */
864function isIterateeCall(value, index, object) {
865  if (!isObject(object)) {
866    return false;
867  }
868  var type = typeof index;
869  if (type == 'number'
870      ? (isArrayLike(object) && isIndex(index, object.length))
871      : (type == 'string' && index in object)) {
872    var other = object[index];
873    return value === value ? (value === other) : (other !== other);
874  }
875  return false;
876}
877
878module.exports = isIterateeCall;
879
880},{"../lang/isObject":33,"./isArrayLike":21,"./isIndex":23}],25:[function(_dereq_,module,exports){
881/**
882 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
883 * of an array-like value.
884 */
885var MAX_SAFE_INTEGER = 9007199254740991;
886
887/**
888 * Checks if `value` is a valid array-like length.
889 *
890 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
891 *
892 * @private
893 * @param {*} value The value to check.
894 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
895 */
896function isLength(value) {
897  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
898}
899
900module.exports = isLength;
901
902},{}],26:[function(_dereq_,module,exports){
903/**
904 * Checks if `value` is object-like.
905 *
906 * @private
907 * @param {*} value The value to check.
908 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
909 */
910function isObjectLike(value) {
911  return !!value && typeof value == 'object';
912}
913
914module.exports = isObjectLike;
915
916},{}],27:[function(_dereq_,module,exports){
917var isArguments = _dereq_('../lang/isArguments'),
918    isArray = _dereq_('../lang/isArray'),
919    isIndex = _dereq_('./isIndex'),
920    isLength = _dereq_('./isLength'),
921    isString = _dereq_('../lang/isString'),
922    keysIn = _dereq_('../object/keysIn');
923
924/** Used for native method references. */
925var objectProto = Object.prototype;
926
927/** Used to check objects for own properties. */
928var hasOwnProperty = objectProto.hasOwnProperty;
929
930/**
931 * A fallback implementation of `Object.keys` which creates an array of the
932 * own enumerable property names of `object`.
933 *
934 * @private
935 * @param {Object} object The object to query.
936 * @returns {Array} Returns the array of property names.
937 */
938function shimKeys(object) {
939  var props = keysIn(object),
940      propsLength = props.length,
941      length = propsLength && object.length;
942
943  var allowIndexes = !!length && isLength(length) &&
944    (isArray(object) || isArguments(object) || isString(object));
945
946  var index = -1,
947      result = [];
948
949  while (++index < propsLength) {
950    var key = props[index];
951    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
952      result.push(key);
953    }
954  }
955  return result;
956}
957
958module.exports = shimKeys;
959
960},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isString":35,"../object/keysIn":39,"./isIndex":23,"./isLength":25}],28:[function(_dereq_,module,exports){
961var isObject = _dereq_('../lang/isObject'),
962    isString = _dereq_('../lang/isString'),
963    support = _dereq_('../support');
964
965/**
966 * Converts `value` to an object if it's not one.
967 *
968 * @private
969 * @param {*} value The value to process.
970 * @returns {Object} Returns the object.
971 */
972function toObject(value) {
973  if (support.unindexedChars && isString(value)) {
974    var index = -1,
975        length = value.length,
976        result = Object(value);
977
978    while (++index < length) {
979      result[index] = value.charAt(index);
980    }
981    return result;
982  }
983  return isObject(value) ? value : Object(value);
984}
985
986module.exports = toObject;
987
988},{"../lang/isObject":33,"../lang/isString":35,"../support":41}],29:[function(_dereq_,module,exports){
989var isArrayLike = _dereq_('../internal/isArrayLike'),
990    isObjectLike = _dereq_('../internal/isObjectLike');
991
992/** Used for native method references. */
993var objectProto = Object.prototype;
994
995/** Used to check objects for own properties. */
996var hasOwnProperty = objectProto.hasOwnProperty;
997
998/** Native method references. */
999var propertyIsEnumerable = objectProto.propertyIsEnumerable;
1000
1001/**
1002 * Checks if `value` is classified as an `arguments` object.
1003 *
1004 * @static
1005 * @memberOf _
1006 * @category Lang
1007 * @param {*} value The value to check.
1008 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
1009 * @example
1010 *
1011 * _.isArguments(function() { return arguments; }());
1012 * // => true
1013 *
1014 * _.isArguments([1, 2, 3]);
1015 * // => false
1016 */
1017function isArguments(value) {
1018  return isObjectLike(value) && isArrayLike(value) &&
1019    hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
1020}
1021
1022module.exports = isArguments;
1023
1024},{"../internal/isArrayLike":21,"../internal/isObjectLike":26}],30:[function(_dereq_,module,exports){
1025var getNative = _dereq_('../internal/getNative'),
1026    isLength = _dereq_('../internal/isLength'),
1027    isObjectLike = _dereq_('../internal/isObjectLike');
1028
1029/** `Object#toString` result references. */
1030var arrayTag = '[object Array]';
1031
1032/** Used for native method references. */
1033var objectProto = Object.prototype;
1034
1035/**
1036 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1037 * of values.
1038 */
1039var objToString = objectProto.toString;
1040
1041/* Native method references for those with the same name as other `lodash` methods. */
1042var nativeIsArray = getNative(Array, 'isArray');
1043
1044/**
1045 * Checks if `value` is classified as an `Array` object.
1046 *
1047 * @static
1048 * @memberOf _
1049 * @category Lang
1050 * @param {*} value The value to check.
1051 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
1052 * @example
1053 *
1054 * _.isArray([1, 2, 3]);
1055 * // => true
1056 *
1057 * _.isArray(function() { return arguments; }());
1058 * // => false
1059 */
1060var isArray = nativeIsArray || function(value) {
1061  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
1062};
1063
1064module.exports = isArray;
1065
1066},{"../internal/getNative":20,"../internal/isLength":25,"../internal/isObjectLike":26}],31:[function(_dereq_,module,exports){
1067var isObject = _dereq_('./isObject');
1068
1069/** `Object#toString` result references. */
1070var funcTag = '[object Function]';
1071
1072/** Used for native method references. */
1073var objectProto = Object.prototype;
1074
1075/**
1076 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1077 * of values.
1078 */
1079var objToString = objectProto.toString;
1080
1081/**
1082 * Checks if `value` is classified as a `Function` object.
1083 *
1084 * @static
1085 * @memberOf _
1086 * @category Lang
1087 * @param {*} value The value to check.
1088 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
1089 * @example
1090 *
1091 * _.isFunction(_);
1092 * // => true
1093 *
1094 * _.isFunction(/abc/);
1095 * // => false
1096 */
1097function isFunction(value) {
vendor: 8,376 bytes, lines 1098-1361
1098  // The use of `Object#toString` avoids issues with the `typeof` operator
1099  // in older versions of Chrome and Safari which return 'function' for regexes
1100  // and Safari 8 which returns 'object' for typed array constructors.
1101  return isObject(value) && objToString.call(value) == funcTag;
1102}
1103
1104module.exports = isFunction;
1105
1106},{"./isObject":33}],32:[function(_dereq_,module,exports){
1107var isFunction = _dereq_('./isFunction'),
1108    isHostObject = _dereq_('../internal/isHostObject'),
1109    isObjectLike = _dereq_('../internal/isObjectLike');
1110
1111/** Used to detect host constructors (Safari > 5). */
1112var reIsHostCtor = /^\[object .+?Constructor\]$/;
1113
1114/** Used for native method references. */
1115var objectProto = Object.prototype;
1116
1117/** Used to resolve the decompiled source of functions. */
1118var fnToString = Function.prototype.toString;
1119
1120/** Used to check objects for own properties. */
1121var hasOwnProperty = objectProto.hasOwnProperty;
1122
1123/** Used to detect if a method is native. */
1124var reIsNative = RegExp('^' +
1125  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
1126  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1127);
1128
1129/**
1130 * Checks if `value` is a native function.
1131 *
1132 * @static
1133 * @memberOf _
1134 * @category Lang
1135 * @param {*} value The value to check.
1136 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
1137 * @example
1138 *
1139 * _.isNative(Array.prototype.push);
1140 * // => true
1141 *
1142 * _.isNative(_);
1143 * // => false
1144 */
1145function isNative(value) {
1146  if (value == null) {
1147    return false;
1148  }
1149  if (isFunction(value)) {
1150    return reIsNative.test(fnToString.call(value));
1151  }
1152  return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
1153}
1154
1155module.exports = isNative;
1156
1157},{"../internal/isHostObject":22,"../internal/isObjectLike":26,"./isFunction":31}],33:[function(_dereq_,module,exports){
1158/**
1159 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
1160 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1161 *
1162 * @static
1163 * @memberOf _
1164 * @category Lang
1165 * @param {*} value The value to check.
1166 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
1167 * @example
1168 *
1169 * _.isObject({});
1170 * // => true
1171 *
1172 * _.isObject([1, 2, 3]);
1173 * // => true
1174 *
1175 * _.isObject(1);
1176 * // => false
1177 */
1178function isObject(value) {
1179  // Avoid a V8 JIT bug in Chrome 19-20.
1180  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
1181  var type = typeof value;
1182  return !!value && (type == 'object' || type == 'function');
1183}
1184
1185module.exports = isObject;
1186
1187},{}],34:[function(_dereq_,module,exports){
1188var baseForIn = _dereq_('../internal/baseForIn'),
1189    isArguments = _dereq_('./isArguments'),
1190    isHostObject = _dereq_('../internal/isHostObject'),
1191    isObjectLike = _dereq_('../internal/isObjectLike'),
1192    support = _dereq_('../support');
1193
1194/** `Object#toString` result references. */
1195var objectTag = '[object Object]';
1196
1197/** Used for native method references. */
1198var objectProto = Object.prototype;
1199
1200/** Used to check objects for own properties. */
1201var hasOwnProperty = objectProto.hasOwnProperty;
1202
1203/**
1204 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1205 * of values.
1206 */
1207var objToString = objectProto.toString;
1208
1209/**
1210 * Checks if `value` is a plain object, that is, an object created by the
1211 * `Object` constructor or one with a `[[Prototype]]` of `null`.
1212 *
1213 * **Note:** This method assumes objects created by the `Object` constructor
1214 * have no inherited enumerable properties.
1215 *
1216 * @static
1217 * @memberOf _
1218 * @category Lang
1219 * @param {*} value The value to check.
1220 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
1221 * @example
1222 *
1223 * function Foo() {
1224 *   this.a = 1;
1225 * }
1226 *
1227 * _.isPlainObject(new Foo);
1228 * // => false
1229 *
1230 * _.isPlainObject([1, 2, 3]);
1231 * // => false
1232 *
1233 * _.isPlainObject({ 'x': 0, 'y': 0 });
1234 * // => true
1235 *
1236 * _.isPlainObject(Object.create(null));
1237 * // => true
1238 */
1239function isPlainObject(value) {
1240  var Ctor;
1241
1242  // Exit early for non `Object` objects.
1243  if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
1244      (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
1245    return false;
1246  }
1247  // IE < 9 iterates inherited properties before own properties. If the first
1248  // iterated property is an object's own property then there are no inherited
1249  // enumerable properties.
1250  var result;
1251  if (support.ownLast) {
1252    baseForIn(value, function(subValue, key, object) {
1253      result = hasOwnProperty.call(object, key);
1254      return false;
1255    });
1256    return result !== false;
1257  }
1258  // In most environments an object's own properties are iterated before
1259  // its inherited properties. If the last iterated property is an object's
1260  // own property then there are no inherited enumerable properties.
1261  baseForIn(value, function(subValue, key) {
1262    result = key;
1263  });
1264  return result === undefined || hasOwnProperty.call(value, result);
1265}
1266
1267module.exports = isPlainObject;
1268
1269},{"../internal/baseForIn":12,"../internal/isHostObject":22,"../internal/isObjectLike":26,"../support":41,"./isArguments":29}],35:[function(_dereq_,module,exports){
1270var isObjectLike = _dereq_('../internal/isObjectLike');
1271
1272/** `Object#toString` result references. */
1273var stringTag = '[object String]';
1274
1275/** Used for native method references. */
1276var objectProto = Object.prototype;
1277
1278/**
1279 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1280 * of values.
1281 */
1282var objToString = objectProto.toString;
1283
1284/**
1285 * Checks if `value` is classified as a `String` primitive or object.
1286 *
1287 * @static
1288 * @memberOf _
1289 * @category Lang
1290 * @param {*} value The value to check.
1291 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
1292 * @example
1293 *
1294 * _.isString('abc');
1295 * // => true
1296 *
1297 * _.isString(1);
1298 * // => false
1299 */
1300function isString(value) {
1301  return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
1302}
1303
1304module.exports = isString;
1305
1306},{"../internal/isObjectLike":26}],36:[function(_dereq_,module,exports){
1307var isLength = _dereq_('../internal/isLength'),
1308    isObjectLike = _dereq_('../internal/isObjectLike');
1309
1310/** `Object#toString` result references. */
1311var argsTag = '[object Arguments]',
1312    arrayTag = '[object Array]',
1313    boolTag = '[object Boolean]',
1314    dateTag = '[object Date]',
1315    errorTag = '[object Error]',
1316    funcTag = '[object Function]',
1317    mapTag = '[object Map]',
1318    numberTag = '[object Number]',
1319    objectTag = '[object Object]',
1320    regexpTag = '[object RegExp]',
1321    setTag = '[object Set]',
1322    stringTag = '[object String]',
1323    weakMapTag = '[object WeakMap]';
1324
1325var arrayBufferTag = '[object ArrayBuffer]',
1326    float32Tag = '[object Float32Array]',
1327    float64Tag = '[object Float64Array]',
1328    int8Tag = '[object Int8Array]',
1329    int16Tag = '[object Int16Array]',
1330    int32Tag = '[object Int32Array]',
1331    uint8Tag = '[object Uint8Array]',
1332    uint8ClampedTag = '[object Uint8ClampedArray]',
1333    uint16Tag = '[object Uint16Array]',
1334    uint32Tag = '[object Uint32Array]';
1335
1336/** Used to identify `toStringTag` values of typed arrays. */
1337var typedArrayTags = {};
1338typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1339typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1340typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1341typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1342typedArrayTags[uint32Tag] = true;
1343typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1344typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1345typedArrayTags[dateTag] = typedArrayTags[errorTag] =
1346typedArrayTags[funcTag] = typedArrayTags[mapTag] =
1347typedArrayTags[numberTag] = typedArrayTags[objectTag] =
1348typedArrayTags[regexpTag] = typedArrayTags[setTag] =
1349typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
1350
1351/** Used for native method references. */
1352var objectProto = Object.prototype;
1353
1354/**
1355 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1356 * of values.
1357 */
1358var objToString = objectProto.toString;
1359
1360/**
1361 * Checks if `value` is classified as a typed array.
1362 *
1363 * @static
1364 * @memberOf _
1365 * @category Lang
1366 * @param {*} value The value to check.
1367 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
1368 * @example
1369 *
1370 * _.isTypedArray(new Uint8Array);
1371 * // => true
1372 *
1373 * _.isTypedArray([]);
1374 * // => false
1375 */
1376function isTypedArray(value) {
1377  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
1378}
1379
1380module.exports = isTypedArray;
1381
1382},{"../internal/isLength":25,"../internal/isObjectLike":26}],37:[function(_dereq_,module,exports){
1383var baseCopy = _dereq_('../internal/baseCopy'),
1384    keysIn = _dereq_('../object/keysIn');
1385
1386/**
1387 * Converts `value` to a plain object flattening inherited enumerable
1388 * properties of `value` to own properties of the plain object.
1389 *
1390 * @static
1391 * @memberOf _
1392 * @category Lang
1393 * @param {*} value The value to convert.
1394 * @returns {Object} Returns the converted plain object.
1395 * @example
1396 *
1397 * function Foo() {
1398 *   this.b = 2;
1399 * }
1400 *
1401 * Foo.prototype.c = 3;
1402 *
1403 * _.assign({ 'a': 1 }, new Foo);
1404 * // => { 'a': 1, 'b': 2 }
1405 *
1406 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
1407 * // => { 'a': 1, 'b': 2, 'c': 3 }
1408 */
1409function toPlainObject(value) {
1410  return baseCopy(value, keysIn(value));
1411}
1412
1413module.exports = toPlainObject;
1414
1415},{"../internal/baseCopy":10,"../object/keysIn":39}],38:[function(_dereq_,module,exports){
1416var getNative = _dereq_('../internal/getNative'),
1417    isArrayLike = _dereq_('../internal/isArrayLike'),
1418    isObject = _dereq_('../lang/isObject'),
1419    shimKeys = _dereq_('../internal/shimKeys'),
1420    support = _dereq_('../support');
1421
1422/* Native method references for those with the same name as other `lodash` methods. */
1423var nativeKeys = getNative(Object, 'keys');
1424
1425/**
1426 * Creates an array of the own enumerable property names of `object`.
1427 *
1428 * **Note:** Non-object values are coerced to objects. See the
1429 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
1430 * for more details.
1431 *
1432 * @static
1433 * @memberOf _
1434 * @category Object
1435 * @param {Object} object The object to query.
1436 * @returns {Array} Returns the array of property names.
1437 * @example
1438 *
1439 * function Foo() {
1440 *   this.a = 1;
1441 *   this.b = 2;
1442 * }
1443 *
1444 * Foo.prototype.c = 3;
1445 *
1446 * _.keys(new Foo);
1447 * // => ['a', 'b'] (iteration order is not guaranteed)
1448 *
1449 * _.keys('hi');
1450 * // => ['0', '1']
1451 */
1452var keys = !nativeKeys ? shimKeys : function(object) {
1453  var Ctor = object == null ? undefined : object.constructor;
1454  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
1455      (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
1456    return shimKeys(object);
1457  }
1458  return isObject(object) ? nativeKeys(object) : [];
1459};
1460
1461module.exports = keys;
1462
1463},{"../internal/getNative":20,"../internal/isArrayLike":21,"../internal/shimKeys":27,"../lang/isObject":33,"../support":41}],39:[function(_dereq_,module,exports){
1464var arrayEach = _dereq_('../internal/arrayEach'),
1465    isArguments = _dereq_('../lang/isArguments'),
1466    isArray = _dereq_('../lang/isArray'),
1467    isFunction = _dereq_('../lang/isFunction'),
1468    isIndex = _dereq_('../internal/isIndex'),
1469    isLength = _dereq_('../internal/isLength'),
1470    isObject = _dereq_('../lang/isObject'),
1471    isString = _dereq_('../lang/isString'),
1472    support = _dereq_('../support');
1473
1474/** `Object#toString` result references. */
1475var arrayTag = '[object Array]',
1476    boolTag = '[object Boolean]',
1477    dateTag = '[object Date]',
1478    errorTag = '[object Error]',
1479    funcTag = '[object Function]',
1480    numberTag = '[object Number]',
1481    objectTag = '[object Object]',
1482    regexpTag = '[object RegExp]',
1483    stringTag = '[object String]';
1484
1485/** Used to fix the JScript `[[DontEnum]]` bug. */
1486var shadowProps = [
1487  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
1488  'toLocaleString', 'toString', 'valueOf'
1489];
1490
1491/** Used for native method references. */
1492var errorProto = Error.prototype,
1493    objectProto = Object.prototype,
1494    stringProto = String.prototype;
1495
1496/** Used to check objects for own properties. */
1497var hasOwnProperty = objectProto.hasOwnProperty;
1498
1499/**
1500 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1501 * of values.
1502 */
1503var objToString = objectProto.toString;
1504
1505/** Used to avoid iterating over non-enumerable properties in IE < 9. */
1506var nonEnumProps = {};
1507nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleStr
1507ing': true, 'toString': true, 'valueOf': true };
1508nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
1509nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
1510nonEnumProps[objectTag] = { 'constructor': true };
1511
1512arrayEach(shadowProps, function(key) {
1513  for (var tag in nonEnumProps) {
1514    if (hasOwnProperty.call(nonEnumProps, tag)) {
1515      var props = nonEnumProps[tag];
1516      props[key] = hasOwnProperty.call(props, key);
1517    }
1518  }
1519});
1520
1521/**
1522 * Creates an array of the own and inherited enumerable property names of `object`.
1523 *
1524 * **Note:** Non-object values are coerced to objects.
1525 *
1526 * @static
1527 * @memberOf _
1528 * @category Object
1529 * @param {Object} object The object to query.
1530 * @returns {Array} Returns the array of property names.
1531 * @example
1532 *
1533 * function Foo() {
1534 *   this.a = 1;
1535 *   this.b = 2;
1536 * }
1537 *
1538 * Foo.prototype.c = 3;
1539 *
1540 * _.keysIn(new Foo);
1541 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
1542 */
1543function keysIn(object) {
1544  if (object == null) {
1545    return [];
1546  }
1547  if (!isObject(object)) {
1548    object = Object(object);
1549  }
1550  var length = object.length;
1551
1552  length = (length && isLength(length) &&
1553    (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
1554
1555  var Ctor = object.constructor,
1556      index = -1,
1557      proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
1558      isProto = proto === object,
1559      result = Array(length),
1560      skipIndexes = length > 0,
1561      skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
1562      skipProto = support.enumPrototypes && isFunction(object);
1563
1564  while (++index < length) {
1565    result[index] = (index + '');
1566  }
1567  // lodash skips the `constructor` property when it infers it's iterating
1568  // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
1569  // attribute of an existing property and the `constructor` property of a
1570  // prototype defaults to non-enumerable.
1571  for (var key in object) {
1572    if (!(skipProto && key == 'prototype') &&
1573        !(skipErrorProps && (key == 'message' || key == 'name')) &&
1574        !(skipIndexes && isIndex(key, length)) &&
1575        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
1576      result.push(key);
1577    }
1578  }
1579  if (support.nonEnumShadows && object !== objectProto) {
1580    var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
1581        nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
1582
1583    if (tag == objectTag) {
1584      proto = objectProto;
1585    }
1586    length = shadowProps.length;
1587    while (length--) {
1588      key = shadowProps[length];
1589      var nonEnum = nonEnums[key];
1590      if (!(isProto && nonEnum) &&
1591          (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
1592        result.push(key);
1593      }
1594    }
1595  }
1596  return result;
1597}
1598
1599module.exports = keysIn;
1600
1601},{"../internal/arrayEach":9,"../internal/isIndex":23,"../internal/isLength":25,"../lang/isArguments":29,"../lang/isArray":30,"../lang/isFunction":31,"../lang/isObject":33,"../lang/isString":35,"../support":41}],40:[function(_dereq_,module,exports){
1602var baseMerge = _dereq_('../internal/baseMerge'),
1603    createAssigner = _dereq_('../internal/createAssigner');
1604
1605/**
1606 * Recursively merges own enumerable properties of the source object(s), that
1607 * don't resolve to `undefined` into the destination object. Subsequent sources
1608 * overwrite property assignments of previous sources. If `customizer` is
1609 * provided it's invoked to produce the merged values of the destination and
1610 * source properties. If `customizer` returns `undefined` merging is handled
1611 * by the method instead. The `customizer` is bound to `thisArg` and invoked
1612 * with five arguments: (objectValue, sourceValue, key, object, source).
1613 *
1614 * @static
1615 * @memberOf _
1616 * @category Object
1617 * @param {Object} object The destination object.
1618 * @param {...Object} [sources] The source objects.
1619 * @param {Function} [customizer] The function to customize assigned values.
1620 * @param {*} [thisArg] The `this` binding of `customizer`.
1621 * @returns {Object} Returns `object`.
1622 * @example
1623 *
1624 * var users = {
1625 *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
1626 * };
1627 *
1628 * var ages = {
1629 *   'data': [{ 'age': 36 }, { 'age': 40 }]
1630 * };
1631 *
1632 * _.merge(users, ages);
1633 * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
1634 *
1635 * // using a customizer callback
1636 * var object = {
1637 *   'fruits': ['apple'],
1638 *   'vegetables': ['beet']
1639 * };
1640 *
1641 * var other = {
1642 *   'fruits': ['banana'],
1643 *   'vegetables': ['carrot']
1644 * };
1645 *
1646 * _.merge(object, other, function(a, b) {
1647 *   if (_.isArray(a)) {
1648 *     return a.concat(b);
1649 *   }
1650 * });
1651 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
1652 */
1653var merge = createAssigner(baseMerge);
1654
1655module.exports = merge;
1656
1657},{"../internal/baseMerge":13,"../internal/createAssigner":17}],41:[function(_dereq_,module,exports){
1658/** Used for native method references. */
1659var arrayProto = Array.prototype,
1660    errorProto = Error.prototype,
1661    objectProto = Object.prototype;
1662
1663/** Native method references. */
1664var propertyIsEnumerable = objectProto.propertyIsEnumerable,
1665    splice = arrayProto.splice;
1666
1667/**
1668 * An object environment feature flags.
1669 *
1670 * @static
1671 * @memberOf _
1672 * @type Object
1673 */
1674var support = {};
1675
1676(function(x) {
1677  var Ctor = function() { this.x = x; },
1678      object = { '0': x, 'length': x },
1679      props = [];
1680
1681  Ctor.prototype = { 'valueOf': x, 'y': x };
1682  for (var key in new Ctor) { props.push(key); }
1683
1684  /**
1685   * Detect if `name` or `message` properties of `Error.prototype` are
1686   * enumerable by default (IE < 9, Safari < 5.1).
1687   *
1688   * @memberOf _.support
1689   * @type boolean
1690   */
1691  support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
1692    propertyIsEnumerable.call(errorProto, 'name');
1693
1694  /**
1695   * Detect if `prototype` properties are enumerable by default.
1696   *
1697   * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
1698   * (if the prototype or a property on the prototype has been set)
1699   * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
1700   * property to `true`.
1701   *
1702   * @memberOf _.support
1703   * @type boolean
1704   */
1705  support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
1706
1707  /**
1708   * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
1709   *
1710   * In IE < 9 an object's own properties, shadowing non-enumerable ones,
1711   * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
1712   *
1713   * @memberOf _.support
1714   * @type boolean
1715   */
1716  support.nonEnumShadows = !/valueOf/.test(props);
1717
1718  /**
1719   * Detect if own properties are iterated after inherited properties (IE < 9).
1720   *
1721   * @memberOf _.support
1722   * @type boolean
1723   */
1724  support.ownLast = props[0] != 'x';
1725
1726  /**
1727   * Detect if `Array#shift` and `Array#splice` augment array-like objects
1728   * correctly.
1729   *
1730   * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
1731   * `shift()` and `splice()` functions that fail to remove the last element,
1732   * `value[0]`, of array-like objects even though the "length" property is
1733   * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
1734   * while `splice()` is buggy regardless of mode in IE < 9.
1735   *
1736   * @memberOf _.support
1737   * @type boolean
1738   */
1739  support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
1740
1741  /**
1742   * Detect lack of support for accessing string characters by index.
1743   *
1744   * IE < 8 can't access characters by index. IE 8 can only access characters
1745   * by index on string literals, not string objects.
1746   *
1747   * @memberOf _.support
1748   * @type boolean
1749   */
1750  support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
1751}(1, 0));
1752
1753module.exports = support;
1754
1755},{}],42:[function(_dereq_,module,exports){
1756/**
1757 * This method returns the first argument provided to it.
1758 *
1759 * @static
1760 * @memberOf _
1761 * @category Utility
1762 * @param {*} value Any value.
1763 * @returns {*} Returns `value`.
1764 * @example
1765 *
1766 * var object = { 'user': 'fred' };
1767 *
1768 * _.identity(object) === object;
1769 * // => true
1770 */
1771function identity(value) {
1772  return value;
1773}
1774
1775module.exports = identity;
1776
1777},{}],43:[function(_dereq_,module,exports){
1778'use strict';
1779
1780var keys = _dereq_('object-keys');
1781
1782module.exports = function hasSymbols() {
1783	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
1784	if (typeof Symbol.iterator === 'symbol') { return true; }
1785
1786	var obj = {};
1787	var sym = Symbol('test');
1788	if (typeof sym === 'string') { return false; }
1789
1790	// temp disabled per https://github.com/ljharb/object.assign/issues/17
1791	// if (sym instanceof Symbol) { return false; }
1792	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
1793	// if (!(Object(sym) instanceof Symbol)) { return false; }
1794
1795	var symVal = 42;
1796	obj[sym] = symVal;
1797	for (sym in obj) { return false; }
1798	if (keys(obj).length !== 0) { return false; }
1799	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
1800
1801	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
1802
1803	var syms = Object.getOwnPropertySymbols(obj);
1804	if (syms.length !== 1 || syms[0] !== sym) { return false; }
1805
1806	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
1807
1808	if (typeof Object.getOwnPropertyDescriptor === 'function') {
1809		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
1810		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
1811	}
1812
1813	return true;
1814};
1815
1816},{"object-keys":50}],44:[function(_dereq_,module,exports){
1817'use strict';
1818
1819// modified from https://github.com/es-shims/es6-shim
1820var keys = _dereq_('object-keys');
1821var bind = _dereq_('function-bind');
1822var canBeObject = function (obj) {
1823	return typeof obj !== 'undefined' && obj !== null;
1824};
1825var hasSymbols = _dereq_('./hasSymbols')();
1826var toObject = Object;
1827var push = bind.call(Function.call, Array.prototype.push);
1828var propIsEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable);
1829
1830module.exports = function assign(target, source1) {
1831	if (!canBeObject(target)) { throw new TypeError('target must be an object'); }
1832	var objTarget = toObject(target);
1833	var s, source, i, props, syms, value, key;
1834	for (s = 1; s < arguments.length; ++s) {
1835		source = toObject(arguments[s]);
1836		props = keys(source);
1837		if (hasSymbols && Object.getOwnPropertySymbols) {
1838			syms = Object.getOwnPropertySymbols(source);
1839			for (i = 0; i < syms.length; ++i) {
1840				key = syms[i];
1841				if (propIsEnumerable(source, key)) {
1842					push(props, key);
1843				}
1844			}
1845		}
1846		for (i = 0; i < props.length; ++i) {
1847			key = props[i];
1848			value = source[key];
1849			if (propIsEnumerable(source, key)) {
1850				objTarget[key] = value;
1851			}
1852		}
1853	}
1854	return objTarget;
1855};
1856
1857},{"./hasSymbols":43,"function-bind":49,"object-keys":50}],45:[function(_dereq_,module,exports){
1858'use strict';
1859
1860var defineProperties = _dereq_('define-properties');
1861
1862var implementation = _dereq_('./implementation');
1863var getPolyfill = _dereq_('./polyfill');
1864var shim = _dereq_('./shim');
1865
1866defineProperties(implementation, {
1867	implementation: implementation,
1868	getPolyfill: getPolyfill,
1869	shim: shim
1870});
1871
1872module.exports = implementation;
1873
1874},{"./implementation":44,"./polyfill":52,"./shim":53,"define-properties":46}],46:[function(_dereq_,module,exports){
1875'use strict';
1876
1877var keys = _dereq_('object-keys');
1878var foreach = _dereq_('foreach');
1879var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
1880
1881var toStr = Object.prototype.toString;
1882
1883var isFunction = function (fn) {
1884	return typeof fn === 'function' && toStr.call(fn) === '[object Function]';
1885};
1886
1887var arePropertyDescriptorsSupported = function () {
1888	var obj = {};
1889	try {
1890		Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
1891        /* eslint-disable no-unused-vars, no-restricted-syntax */
1892        for (var _ in obj) { return false; }
1893        /* eslint-enable no-unused-vars, no-restricted-syntax */
1894		return obj.x === obj;
1895	} catch (e) { /* this is IE 8. */
1896		return false;
1897	}
1898};
1899var supportsDescriptors = Object.defineProperty && arePropertyDescriptorsSupported();
1900
1901var defineProperty = function (object, name, value, predicate) {
1902	if (name in object && (!isFunction(predicate) || !predicate())) {
1903		return;
1904	}
1905	if (supportsDescriptors) {
1906		Object.defineProperty(object, name, {
1907			configurable: true,
1908			enumerable: false,
1909			value: value,
1910			writable: true
1911		});
1912	} else {
1913		object[name] = value;
1914	}
1915};
1916
1917var defineProperties = function (object, map) {
1918	var predicates = arguments.length > 2 ? arguments[2] : {};
1919	var props = keys(map);
1920	if (hasSymbols) {
1921		props = props.concat(Object.getOwnPropertySymbols(map));
1922	}
1923	foreach(props, function (name) {
1924		defineProperty(object, name, map[name], predicates[name]);
1925	});
1926};
1927
1928defineProperties.supportsDescriptors = !!supportsDescriptors;
1929
1930module.exports = defineProperties;
1931
1932},{"foreach":47,"object-keys":50}],47:[function(_dereq_,module,exports){
1933
1934var hasOwn = Object.prototype.hasOwnProperty;
1935var toString = Object.prototype.toString;
1936
1937module.exports = function forEach (obj, fn, ctx) {
1938    if (toString.call(fn) !== '[object Function]') {
1939        throw new TypeError('iterator must be a function');
1940    }
1941    var l = obj.length;
1942    if (l === +l) {
1943        for (var i = 0; i < l; i++) {
1944            fn.call(ctx, obj[i], i, obj);
1945        }
1946    } else {
1947        for (var k in obj) {
1948            if (hasOwn.call(obj, k)) {
1949                fn.call(ctx, obj[k], k, obj);
1950            }
1951        }
1952    }
1953};
1954
1955
1956},{}],48:[function(_dereq_,module,exports){
1957var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
1958var slice = Array.prototype.slice;
1959var toStr = Object.prototype.toString;
1960var funcType = '[object Function]';
1961
1962module.exports = function bind(that) {
1963    var target = this;
1964    if (typeof target !== 'function' || toStr.call(target) !== funcType) {
1965        throw new TypeError(ERROR_MESSAGE + target);
1966    }
1967    var args = slice.call(arguments, 1);
1968
1969    var bound;
1970    var binder = function () {
1971        if (this instanceof bound) {
1972            var result = target.apply(
1973                this,
1974                args.concat(slice.call(arguments))
1975            );
1976            if (Object(result) === result) {
1977                return result;
1978            }
1979            return this;
1980        } else {
1981            return target.apply(
1982                that,
1983                args.concat(slice.call(arguments))
1984            );
1985        }
1986    };
1987
1988    var boundLength = Math.max(0, target.length - args.length);
1989    var boundArgs = [];
1990    for (var i = 0; i < boundLength; i++) {
1991        boundArgs.push('$' + i);
1992    }
1993
1994    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
1995
1996    if (target.prototype) {
1997        var Empty = function Empty() {};
1998        Empty.prototype = target.prototype;
1999        bound.prototype = new Empty();
2000        Empty.prototype = null;
2001    }
2002
2003    return bound;
2004};
2005
2006},{}],49:[function(_dereq_,module,exports){
2007var implementation = _dereq_('./implementation');
2008
2009module.exports = Function.prototype.bind || implementation;
2010
2011},{"./implementation":48}],50:[function(_dereq_,module,exports){
2012'use strict';
2013
2014// modified from https://github.com/es-shims/es5-shim
2015var has = Object.prototype.hasOwnProperty;
2016var toStr = Object.prototype.toString;
2017var slice = Array.prototype.slice;
2018var isArgs = _dereq_('./isArguments');
2019var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
2020var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
2021var dontEnums = [
2022	'toString',
2023	'toLocaleString',
2024	'valueOf',
2025	'hasOwnProperty',
2026	'isPrototypeOf',
2027	'propertyIsEnumerable',
2028	'constructor'
2029];
2030var equalsConstructorPrototype = function (o) {
2031	var ctor = o.constructor;
2032	return ctor && ctor.prototype === o;
2033};
2034var blacklistedKeys = {
2035	$console: true,
2036	$frame: true,
2037	$frameElement: true,
2038	$frames: true,
2039	$parent: true,
2040	$self: true,
2041	$webkitIndexedDB: true,
2042	$webkitStorageInfo: true,
2043	$window: true
2044};
2045var hasAutomationEqualityBug = (function () {
2046	/* global window */
2047	if (typeof window === 'undefined') { return false; }
2048	for (var k in window) {
2049		try {
2050			if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
2051				try {
2052					equalsConstructorPrototype(window[k]);
2053				} catch (e) {
2054					return true;
2055				}
2056			}
2057		} catch (e) {
2058			return true;
2059		}
2060	}
2061	return false;
2062}());
2063var equalsConstructorPrototypeIfNotBuggy = function (o) {
2064	/* global window */
2065	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
2066		return equalsConstructorPrototype(o);
2067	}
2068	try {
2069		return equalsConstructorPrototype(o);
2070	} catch (e) {
2071		return false;
2072	}
2073};
2074
2075var keysShim = function keys(object) {
2076	var isObject = object !== null && typeof object === 'object';
2077	var isFunction = toStr.call(object) === '[object Function]';
2078	var isArguments = isArgs(object);
2079	var isString = isObject && toStr.call(object) === '[object String]';
2080	var theKeys = [];
2081
2082	if (!isObject && !isFunction && !isArguments) {
2083		throw new TypeError('Object.keys called on a non-object');
2084	}
2085
2086	var skipProto = hasProtoEnumBug && isFunction;
2087	if (isString && object.length > 0 && !has.call(object, 0)) {
2088		for (var i = 0; i < object.length; ++i) {
2089			theKeys.push(String(i));
2090		}
2091	}
2092
2093	if (isArguments && object.length > 0) {
2094		for (var j = 0; j < object.length; ++j) {
2095			theKeys.push(String(j));
2096		}
2097	} else {
2098		for (var name in object) {
2099			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
2100				theKeys.push(String(name));
2101			}
2102		}
2103	}
2104
2105	if (hasDontEnumBug) {
2106		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
2107
2108		for (var k = 0; k < dontEnums.length; ++k) {
2109			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
2110				theKeys.push(dontEnums[k]);
2111			}
2112		}
2113	}
2114	return theKeys;
2115};
2116
2117keysShim.shim = function shimObjectKeys() {
2118	if (Object.keys) {
2119		var keysWorksWithArguments = (function () {
2120			// Safari 5.0 bug
2121			return (Object.keys(arguments) || '').length === 2;
2122		}(1, 2));
2123		if (!keysWorksWithArguments) {
2124			var originalKeys = Object.keys;
2125			Object.keys = function keys(object) {
2126				if (isArgs(object)) {
2127					return originalKeys(slice.call(object));
2128				} else {
2129					return originalKeys(object);
2130				}
2131			};
2132		}
2133	} else {
2134		Object.keys = keysShim;
2135	}
2136	return Object.keys || keysShim;
2137};
2138
2139module.exports = keysShim;
2140
2141},{"./isArguments":51}],51:[function(_dereq_,module,exports){
2142'use strict';
2143
2144var toStr = Object.prototype.toString;
2145
2146module.exports = function isArguments(value) {
2147	var str = toStr.call(value);
2148	var isArgs = str === '[object Arguments]';
2149	if (!isArgs) {
2150		isArgs = str !== '[object Array]' &&
2151			value !== null &&
2152			typeof value === 'object' &&
2153			typeof value.length === 'number' &&
2154			value.length >= 0 &&
2155			toStr.call(value.callee) === '[object Function]';
2156	}
2157	return isArgs;
2158};
2159
2160},{}],52:[function(_dereq_,module,exports){
2161'use strict';
2162
2163var implementation = _dereq_('./implementation');
2164
2165var lacksProperEnumerationOrder = function () {
2166	if (!Object.assign) {
2167		return false;
2168	}
2169	// v8, specifically in node 4.x, has a bug with incorrect property enumeration order
2170	// note: this does not detect the bug unless there's 20 characters
2171	var str = 'abcdefghijklmnopqrst';
2172	var letters = str.split('');
2173	var map = {};
2174	for (var i = 0; i < letters.length; ++i) {
2175		map[letters[i]] = letters[i];
2176	}
2177	var obj = Object.assign({}, map);
2178	var actual = '';
2179	for (var k in obj) {
2180		actual += k;
2181	}
2182	return str !== actual;
2183};
2184
2185var assignHasPendingExceptions = function () {
2186	if (!Object.assign || !Object.preventExtensions) {
2187		return false;
2188	}
2189	// Firefox 37 still has "pending exception" logic in its Object.assign implementation,
2190	// which is 72% slower than our shim, and Firefox 40's native implementation.
2191	var thrower = Object.preventExtensions({ 1: 2 });
2192	try {
2193		Object.assign(thrower, 'xy');
2194	} catch (e) {
2195		return thrower[1] === 'y';
2196	}
2197};
2198
2199module.exports = function getPolyfill() {
2200	if (!Object.assign) {
2201		return implementation;
2202	}
2203	if (lacksProperEnumerationOrder()) {
2204		return implementation;
2205	}
2206	if (assignHasPendingExceptions()) {
2207		return implementation;
2208	}
2209	return Object.assign;
2210};
2211
2212},{"./implementation":44}],53:[function(_dereq_,module,exports){
2213'use strict';
2214
2215var define = _dereq_('define-properties');
2216var getPolyfill = _dereq_('./polyfill');
2217
2218module.exports = function shimAssign() {
2219	var polyfill = getPolyfill();
2220	define(
2221		Object,
2222		{ assign: polyfill },
2223		{ assign: function () { return Object.assign !== polyfill; } }
2224	);
2225	return polyfill;
2226};
2227
2228},{"./polyfill":52,"define-properties":46}],54:[function(_dereq_,module,exports){
2229module.exports = SafeParseTuple
2230
2231function SafeParseTuple(obj, reviver) {
2232    var json
2233    var error = null
2234
2235    try {
2236        json = JSON.parse(obj, reviver)
2237    } catch (err) {
2238        error = err
2239    }
2240
2241    return [error, json]
2242}
2243
2244},{}],55:[function(_dereq_,module,exports){
2245function clean (s) {
2246  return s.replace(/\n\r?\s*/g, '')
2247}
2248
2249
2250module.exports = function tsml (sa) {
2251  var s = ''
2252    , i = 0
2253
2254  for (; i < arguments.length; i++)
2255    s += clean(sa[i]) + (arguments[i + 1] || '')
2256
2257  return s
2258}
2259},{}],56:[function(_dereq_,module,exports){
2260"use strict";
2261var window = _dereq_("global/window")
2262var once = _dereq_("once")
2263var isFunction = _dereq_("is-function")
2264var parseHeaders = _dereq_("parse-headers")
2265var xtend = _dereq_("xtend")
2266
2267module.exports = createXHR
2268createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
2269createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
2270
2271forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
2272    createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
2273        options = initParams(uri, options, callback)
2274        options.method = method.toUpperCase()
2275        return _createXHR(options)
2276    }
2277})
2278
2279function forEachArray(array, iterator) {
2280    for (var i = 0; i < array.length; i++) {
2281        iterator(array[i])
2282    }
2283}
2284
2285function isEmpty(obj){
2286    for(var i in obj){
2287        if(obj.hasOwnProperty(i)) return false
2288    }
2289    return true
2290}
2291
2292function initParams(uri, options, callback) {
2293    var params = uri
2294
2295    if (isFunction(options)) {
2296        callback = options
2297        if (typeof uri === "string") {
2298            params = {uri:uri}
2299        }
2300    } else {
2301        params = xtend(options, {uri: uri})
2302    }
2303
2304    params.callback = callback
2305    return params
2306}
2307
2308function createXHR(uri, options, callback) {
2309    options = initParams(uri, options, callback)
2310    return _createXHR(options)
2311}
2312
2313function _createXHR(options) {
2314    var callback = options.callback
2315    if(typeof callback === "undefined"){
2316        throw new Error("callback argument missing")
2317    }
2318    callback = once(callback)
2319
2320    function readystatechange() {
2321        if (xhr.readyState === 4) {
2322            loadFunc()
2323        }
2324    }
2325
2326    function getBody() {
2327        // Chrome with requestType=blob throws errors arround when even testing access to responseText
2328        var body = undefined
2329
2330        if (xhr.response) {
2331            body = xhr.response
2332        } else if (xhr.responseType === "text" || !xhr.responseType) {
2333            body = xhr.responseText || xhr.responseXML
2334        }
2335
2336        if (isJson) {
2337            try {
2338                body = JSON.parse(body)
2339            } catch (e) {}
2340        }
2341
2342        return body
2343    }
2344
2345    var failureResponse = {
2346                body: undefined,
2347                headers: {},
2348                statusCode: 0,
2349                method: method,
2350                url: uri,
2351                rawRequest: xhr
2352            }
2353
2354    function errorFunc(evt) {
2355        clearTimeout(timeoutTimer)
2356        if(!(evt instanceof Error)){
2357            evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
2358        }
2359        evt.statusCode = 0
2360        callback(evt, failureResponse)
2361    }
2362
2363    // will load the data & process the response in a special response object
2364    function loadFunc() {
2365        if (aborted) return
2366        var status
2367        clearTimeout(timeoutTimer)
2368        if(options.useXDR && xhr.status===undefined) {
2369            //IE8 CORS GET successful response doesn't have a status field, but body is fine
2370            status = 200
2371        } else {
2372            status = (xhr.status === 1223 ? 204 : xhr.status)
2373        }
2374        var response = failureResponse
2375        var err = null
2376
2377        if (status !== 0){
2378            response = {
2379                body: getBody(),
2380                statusCode: status,
2381                method: method,
2382                headers: {},
2383                url: uri,
2384                rawRequest: xhr
2385            }
2386            if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
2387                response.headers = parseHeaders(xhr.getAllResponseHeaders())
2388            }
2389        } else {
2390            err = new Error("Internal XMLHttpRequest Error")
2391        }
2392        callback(err, response, response.body)
2393
2394    }
2395
2396    var xhr = options.xhr || null
2397
2398    if (!xhr) {
2399        if (options.cors || options.useXDR) {
2400            xhr = new createXHR.XDomainRequest()
2401        }else{
2402            xhr = new createXHR.XMLHttpRequest()
2403        }
2404    }
2405
2406    var key
2407    var aborted
2408    var uri = xhr.url = options.uri || options.url
2409    var method = xhr.method = options.method || "GET"
2410    var body = options.body || options.data || null
2411    var headers = xhr.headers = options.headers || {}
2412    var sync = !!options.sync
2413    var isJson = false
2414    var timeoutTimer
2415
2416    if ("json" in options) {
2417        isJson = true
2418        headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
2419        if (method !== "GET" && method !== "HEAD") {
2420            headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
2421            body = JSON.stringify(options.json)
2422        }
2423    }
2424
2425    xhr.onreadystatechange = readystatechange
2426    xhr.onload = loadFunc
2427    xhr.onerror = errorFunc
2428    // IE9 must have onprogress be set to a unique function.
2429    xhr.onprogress = function () {
2430        // IE must die
2431    }
2432    xhr.ontimeout = errorFunc
2433    xhr.open(method, uri, !sync, options.username, options.password)
2434    //has to be after open
2435    if(!sync) {
2436        xhr.withCredentials = !!options.withCredentials
2437    }
2438    // Cannot set timeout with sync request
2439    // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
2440    // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
2441    if (!sync && options.timeout > 0 ) {
2442        timeoutTimer = setTimeout(function(){
2443            aborted=true//IE9 may still call readystatechange
2444            xhr.abort("timeout")
2445            var e = new Error("XMLHttpRequest timeout")
2446            e.code = "ETIMEDOUT"
2447            errorFunc(e)
2448        }, options.timeout )
2449    }
2450
2451    if (xhr.setRequestHeader) {
2452        for(key in headers){
2453            if(headers.hasOwnProperty(key)){
2454                xhr.setRequestHeader(key, headers[key])
2455            }
2456        }
2457    } else if (options.headers && !isEmpty(options.headers)) {
2458        throw new Error("Headers cannot be set on an XDomainRequest object")
2459    }
2460
2461    if ("responseType" in options) {
2462        xhr.responseType = options.responseType
2463    }
2464
2465    if ("beforeSend" in options &&
2466        typeof options.beforeSend === "function"
2467    ) {
2468        options.beforeSend(xhr)
2469    }
2470
2471    xhr.send(body)
2472
2473    return xhr
2474
2475
2476}
2477
2478function noop() {}
2479
2480},{"global/window":2,"is-function":57,"once":58,"parse-headers":61,"xtend":62}],57:[function(_dereq_,module,exports){
2481module.exports = isFunction
2482
2483var toString = Object.prototype.toString
2484
2485function isFunction (fn) {
2486  var string = toString.call(fn)
2487  return string === '[object Function]' ||
2488    (typeof fn === 'function' && string !== '[object RegExp]') ||
2489    (typeof window !== 'undefined' &&
2490     // IE8 and below
2491     (fn === window.setTimeout ||
2492      fn === window.alert ||
2493      fn === window.confirm ||
2494      fn === window.prompt))
2495};
2496
2497},{}],58:[function(_dereq_,module,exports){
2498module.exports = once
2499
2500once.proto = once(function () {
2501  Object.defineProperty(Function.prototype, 'once', {
2502    value: function () {
2503      return once(this)
2504    },
2505    configurable: true
2506  })
2507})
2508
2509function once (fn) {
2510  var called = false
2511  return function () {
2512    if (called) return
2513    called = true
2514    return fn.apply(this, arguments)
2515  }
2516}
2517
2518},{}],59:[function(_dereq_,module,exports){
2519var isFunction = _dereq_('is-function')
2520
2521module.exports = forEach
2522
2523var toString = Object.prototype.toString
2524var hasOwnProperty = Object.prototype.hasOwnProperty
2525
2526function forEach(list, iterator, context) {
2527    if (!isFunction(iterator)) {
2528        throw new TypeError('iterator must be a function')
2529    }
2530
2531    if (arguments.length < 3) {
2532        context = this
2533    }
2534    
2535    if (toString.call(list) === '[object Array]')
2536        forEachArray(list, iterator, context)
2537    else if (typeof list === 'string')
2538        forEachString(list, iterator, context)
2539    else
2540        forEachObject(list, iterator, context)
2541}
2542
2543function forEachArray(array, iterator, context) {
2544    for (var i = 0, len = array.length; i < len; i++) {
2545        if (hasOwnProperty.call(array, i)) {
2546            iterator.call(context, array[i], i, array)
2547        }
2548    }
2549}
2550
2551function forEachString(string, iterator, context) {
2552    for (var i = 0, len = string.length; i < len; i++) {
2553        // no such thing as a sparse string.
2554        iterator.call(context, string.charAt(i), i, string)
2555    }
2556}
2557
2558function forEachObject(object, iterator, context) {
2559    for (var k in object) {
2560        if (hasOwnProperty.call(object, k)) {
2561            iterator.call(context, object[k], k, object)
2562        }
2563    }
2564}
2565
2566},{"is-function":57}],60:[function(_dereq_,module,exports){
2567
2568exports = module.exports = trim;
2569
2570function trim(str){
2571  return str.replace(/^\s*|\s*$/g, '');
2572}
2573
2574exports.left = function(str){
2575  return str.replace(/^\s*/, '');
2576};
2577
2578exports.right = function(str){
2579  return str.replace(/\s*$/, '');
2580};
2581
2582},{}],61:[function(_dereq_,module,exports){
2583var trim = _dereq_('trim')
2584  , forEach = _dereq_('for-each')
2585  , isArray = function(arg) {
2586      return Object.prototype.toString.call(arg) === '[object Array]';
2587    }
2588
2589module.exports = function (headers) {
2590  if (!headers)
2591    return {}
2592
2593  var result = {}
2594
2595  forEach(
2596      trim(headers).split('\n')
2597    , function (row) {
2598        var index = row.indexOf(':')
2599          , key = trim(row.slice(0, index)).toLowerCase()
2600          , value = trim(row.slice(index + 1))
2601
2602        if (typeof(result[key]) === 'undefined') {
2603          result[key] = value
2604        } else if (isArray(result[key])) {
2605          result[key].push(value)
2606        } else {
2607          result[key] = [ result[key], value ]
2608        }
2609      }
2610  )
2611
2612  return result
2613}
2614},{"for-each":59,"trim":60}],62:[function(_dereq_,module,exports){
2615module.exports = extend
2616
2617var hasOwnProperty = Object.prototype.hasOwnProperty;
2618
2619function extend() {
2620    var target = {}
2621
2622    for (var i = 0; i < arguments.length; i++) {
2623        var source = arguments[i]
2624
2625        for (var key in source) {
2626            if (hasOwnProperty.call(source, key)) {
2627                target[key] = source[key]
2628            }
2629        }
2630    }
2631
2632    return target
2633}
2634
2635},{}],63:[function(_dereq_,module,exports){
2636/**
2637 * @file big-play-button.js
2638 */
2639'use strict';
2640
2641exports.__esModule = true;
2642
2643function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2644
2645function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2646
2647function _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; }
2648
2649var _buttonJs = _dereq_('./button.js');
2650
2651var _buttonJs2 = _interopRequireDefault(_buttonJs);
2652
2653var _componentJs = _dereq_('./component.js');
2654
2655var _componentJs2 = _interopRequireDefault(_componentJs);
2656
2657/**
2658 * Initial play button. Shows before the video has played. The hiding of the
2659 * big play button is done via CSS and player states.
2660 *
2661 * @param {Object} player  Main Player
2662 * @param {Object=} options Object of option names and values
2663 * @extends Button
2664 * @class BigPlayButton
2665 */
2666
2667var BigPlayButton = (function (_Button) {
2668  _inherits(BigPlayButton, _Button);
2669
2670  function BigPlayButton(player, options) {
2671    _classCallCheck(this, BigPlayButton);
2672
2673    _Button.call(this, player, options);
2674  }
2675
2676  /**
2677   * Allow sub components to stack CSS class names
2678   *
2679   * @return {String} The constructed class name
2680   * @method buildCSSClass
2681   */
2682
2683  BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
2684    return 'vjs-big-play-button';
2685  };
2686
2687  /**
2688   * Handles click for play
2689   *
2690   * @method handleClick
2691   */
2692
2693  BigPlayButton.prototype.handleClick = function handleClick() {
2694    this.player_.play();
2695  };
2696
2697  return BigPlayButton;
2698})(_buttonJs2['default']);
2699
2700BigPlayButton.prototype.controlText_ = 'Play Video';
2701
2702_componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton);
2703exports['default'] = BigPlayButton;
2704module.exports = exports['default'];
2705
2706},{"./button.js":64,"./component.js":67}],64:[function(_dereq_,module,exports){
2707/**
2708 * @file button.js
2709 */
2710'use strict';
2711
2712exports.__esModule = true;
2713
2714function _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; } }
2715
2716function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2717
2718function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2719
2720function _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, { c
2720onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
2721
2722var _clickableComponentJs = _dereq_('./clickable-component.js');
2723
2724var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
2725
2726var _component = _dereq_('./component');
2727
2728var _component2 = _interopRequireDefault(_component);
2729
2730var _utilsEventsJs = _dereq_('./utils/events.js');
2731
2732var Events = _interopRequireWildcard(_utilsEventsJs);
2733
2734var _utilsFnJs = _dereq_('./utils/fn.js');
2735
2736var Fn = _interopRequireWildcard(_utilsFnJs);
2737
2738var _utilsLogJs = _dereq_('./utils/log.js');
2739
2740var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
2741
2742var _globalDocument = _dereq_('global/document');
2743
2744var _globalDocument2 = _interopRequireDefault(_globalDocument);
2745
2746var _objectAssign = _dereq_('object.assign');
2747
2748var _objectAssign2 = _interopRequireDefault(_objectAssign);
2749
2750/**
2751 * Base class for all buttons
2752 *
2753 * @param {Object} player  Main Player
2754 * @param {Object=} options Object of option names and values
2755 * @extends ClickableComponent
2756 * @class Button
2757 */
2758
2759var Button = (function (_ClickableComponent) {
2760  _inherits(Button, _ClickableComponent);
2761
2762  function Button(player, options) {
2763    _classCallCheck(this, Button);
2764
2765    _ClickableComponent.call(this, player, options);
2766  }
2767
2768  /**
2769   * Create the component's DOM element
2770   *
2771   * @param {String=} type Element's node type. e.g. 'div'
2772   * @param {Object=} props An object of properties that should be set on the element
2773   * @param {Object=} attributes An object of attributes that should be set on the element
2774   * @return {Element}
2775   * @method createEl
2776   */
2777
2778  Button.prototype.createEl = function createEl() {
2779    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0];
2780    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2781    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
2782
2783    props = _objectAssign2['default']({
2784      className: this.buildCSSClass()
2785    }, props);
2786
2787    if (tag !== 'button') {
2788      _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
2789
2790      // Add properties for clickable element which is not a native HTML button
2791      props = _objectAssign2['default']({
2792        tabIndex: 0
2793      }, props);
2794
2795      // Add ARIA attributes for clickable element which is not a native HTML button
2796      attributes = _objectAssign2['default']({
2797        role: 'button'
2798      }, attributes);
2799    }
2800
2801    // Add attributes for button element
2802    attributes = _objectAssign2['default']({
2803      type: 'button', // Necessary since the default button type is "submit"
2804      'aria-live': 'polite' // let the screen reader user know that the text of the button may change
2805    }, attributes);
2806
2807    var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
2808
2809    this.createControlTextEl(el);
2810
2811    return el;
2812  };
2813
2814  /**
2815   * Adds a child component inside this button
2816   *
2817   * @param {String|Component} child The class name or instance of a child to add
2818   * @param {Object=} options Options, including options to be passed to children of the child.
2819   * @return {Component} The child component (created by this process if a string was used)
2820   * @deprecated
2821   * @method addChild
2822   */
2823
2824  Button.prototype.addChild = function addChild(child) {
2825    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2826
2827    var className = this.constructor.name;
2828    _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
2829
2830    // Avoid the error message generated by ClickableComponent's addChild method
2831    return _component2['default'].prototype.addChild.call(this, child, options);
2832  };
2833
2834  /**
2835   * Handle KeyPress (document level) - Extend with specific functionality for button
2836   *
2837   * @method handleKeyPress
2838   */
2839
2840  Button.prototype.handleKeyPress = function handleKeyPress(event) {
2841    // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
2842    if (event.which === 32 || event.which === 13) {} else {
2843      _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
2844    }
2845  };
2846
2847  return Button;
2848})(_clickableComponentJs2['default']);
2849
2850_component2['default'].registerComponent('Button', Button);
2851exports['default'] = Button;
2852module.exports = exports['default'];
2853
2854},{"./clickable-component.js":65,"./component":67,"./utils/events.js":144,"./ut
2854ils/fn.js":145,"./utils/log.js":148,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){
2855/**
2856 * @file button.js
2857 */
2858'use strict';
2859
2860exports.__esModule = true;
2861
2862function _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; } }
2863
2864function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2865
2866function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2867
2868function _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; }
2869
2870var _component = _dereq_('./component');
2871
2872var _component2 = _interopRequireDefault(_component);
2873
2874var _utilsDomJs = _dereq_('./utils/dom.js');
2875
2876var Dom = _interopRequireWildcard(_utilsDomJs);
2877
2878var _utilsEventsJs = _dereq_('./utils/events.js');
2879
2880var Events = _interopRequireWildcard(_utilsEventsJs);
2881
2882var _utilsFnJs = _dereq_('./utils/fn.js');
2883
2884var Fn = _interopRequireWildcard(_utilsFnJs);
2885
2886var _utilsLogJs = _dereq_('./utils/log.js');
2887
2888var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
2889
2890var _globalDocument = _dereq_('global/document');
2891
2892var _globalDocument2 = _interopRequireDefault(_globalDocument);
2893
2894var _objectAssign = _dereq_('object.assign');
2895
2896var _objectAssign2 = _interopRequireDefault(_objectAssign);
2897
2898/**
2899 * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button
2900 *
2901 * @param {Object} player  Main Player
2902 * @param {Object=} options Object of option names and values
2903 * @extends Component
2904 * @class ClickableComponent
2905 */
2906
2907var ClickableComponent = (function (_Component) {
2908  _inherits(ClickableComponent, _Component);
2909
2910  function ClickableComponent(player, options) {
2911    _classCallCheck(this, ClickableComponent);
2912
2913    _Component.call(this, player, options);
2914
2915    this.emitTapEvents();
2916
2917    this.on('tap', this.handleClick);
2918    this.on('click', this.handleClick);
2919    this.on('focus', this.handleFocus);
2920    this.on('blur', this.handleBlur);
2921  }
2922
2923  /**
2924   * Create the component's DOM element
2925   *
2926   * @param {String=} type Element's node type. e.g. 'div'
2927   * @param {Object=} props An object of properties that should be set on the element
2928   * @param {Object=} attributes An object of attributes that should be set on the element
2929   * @return {Element}
2930   * @method createEl
2931   */
2932
2933  ClickableComponent.prototype.createEl = function createEl() {
2934    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
2935    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2936    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
2937
2938    props = _objectAssign2['default']({
2939      className: this.buildCSSClass(),
2940      tabIndex: 0
2941    }, props);
2942
2943    if (tag === 'button') {
2944      _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
2945    }
2946
2947    // Add ARIA attributes for clickable element which is not a native HTML button
2948    attributes = _objectAssign2['default']({
2949      role: 'button',
2950      'aria-live': 'polite' // let the screen reader user know that the text of the element may change
2951    }, attributes);
2952
2953    var el = _Component.prototype.createEl.call(this, tag, props, attributes);
2954
2955    this.createControlTextEl(el);
2956
2957    return el;
2958  };
2959
2960  /**
2961   * create control text
2962   *
2963   * @param {Element} el Parent element for the control text
2964   * @return {Element}
2965   * @method controlText
2966   */
2967
2968  ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
2969    this.controlTextEl_ = Dom.createEl('span', {
2970      className: 'vjs-control-text'
2971    });
2972
2973    if (el) {
2974      el.appendChild(this.controlTextEl_);
2975    }
2976
2977    this.controlText(this.controlText_);
2978
2979    return this.controlTextEl_;
2980  };
2981
2982  /**
2983   * Controls text - both request and localize
2984   *
2985   * @param {String} text Text for element
2986   * @return {String}
2987   * @method controlText
2988   */
2989
2990  ClickableComponent.prototype.controlText = function controlText(text) {
2991    if (!text) return this.controlText_ || 'Need Text';
2992
2993    this.controlText_ = text;
2994    this.controlTextEl_.innerHTML = this.localize(this.controlText_);
2995
2996    return this;
2997  };
2998
2999  /**
3000   * Allows sub components to stack CSS class names
3001   *
3002   * @return {String}
3003   * @method buildCSSClass
3004   */
3005
3006  ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
3007    return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
3008  };
3009
3010  /**
3011   * Adds a child component inside this clickable-component
3012   *
3013   * @param {String|Component} child The class name or instance of a child to add
3014   * @param {Object=} options Options, including options to be passed to children of the child.
3015   * @return {Component} The child component (created by this process if a string was used)
3016   * @method addChild
3017   */
3018
3019  ClickableComponent.prototype.addChild = function addChild(child) {
3020    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
3021
3022    // TODO: Fix adding an actionable child to a ClickableComponent; currently
3023    // it will cause issues with assistive technology (e.g. screen readers)
3024    // which support ARIA, since an element with role="button" cannot have
3025    // actionable child elements.
3026
3027    //let className = this.constructor.name;
3028    //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);
3029
3030    return _Component.prototype.addChild.call(this, child, options);
3031  };
3032
3033  /**
3034   * Enable the component element
3035   *
3036   * @return {Component}
3037   * @method enable
3038   */
3039
3040  ClickableComponent.prototype.enable = function enable() {
3041    this.removeClass('vjs-disabled');
3042    this.el_.setAttribute('aria-disabled', 'false');
3043    return this;
3044  };
3045
3046  /**
3047   * Disable the component element
3048   *
3049   * @return {Component}
3050   * @method disable
3051   */
3052
3053  ClickableComponent.prototype.disable = function disable() {
3054    this.addClass('vjs-disabled');
3055    this.el_.setAttribute('aria-disabled', 'true');
3056    return this;
3057  };
3058
3059  /**
3060   * Handle Click - Override with specific functionality for component
3061   *
3062   * @method handleClick
3063   */
3064
3065  ClickableComponent.prototype.handleClick = function handleClick() {};
3066
3067  /**
3068   * Handle Focus - Add keyboard functionality to element
3069   *
3070   * @method handleFocus
3071   */
3072
3073  ClickableComponent.prototype.handleFocus = function handleFocus() {
3074    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
3075  };
3076
3077  /**
3078   * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed
3079   *
3080   * @method handleKeyPress
3081   */
3082
3083  ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
3084    // Support Space (32) or Enter (13) key operation to fire a click event
3085    if (event.which === 32 || event.which === 13) {
3086      event.preventDefault();
3087      this.handleClick(event);
3088    } else if (_Component.prototype.handleKeyPress) {
3089      _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
3090    }
3091  };
3092
3093  /**
3094   * Handle Blur - Remove keyboard triggers
3095   *
3096   * @method handleBlur
3097   */
3098
3099  ClickableComponent.prototype.handleBlur = function handleBlur() {
3100    Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
3101  };
3102
3103  return ClickableComponent;
3104})(_component2['default']);
3105
3106_component2['default'].registerComponent('ClickableComponent', ClickableComponent);
3107exports['default'] = ClickableComponent;
3108module.exports = exports['default'];
3109
3110},{"./component":67,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/log.js":148,"global/document":1,"object.assign":45}],66:[function(_dereq_,module,exports){
3111'use strict';
3112
3113exports.__esModule = true;
3114
3115function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3116
3117function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
3118
3119function _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; }
3120
3121var _button = _dereq_('./button');
3122
3123var _button2 = _interopRequireDefault(_button);
3124
3125var _component = _dereq_('./component');
3126
3127var _component2 = _interopRequireDefault(_component);
3128
3129/**
3130 * The `CloseButton` component is a button which fires a "close" event
3131 * when it is activated.
3132 *
3133 * @extends Button
3134 * @class CloseButton
3135 */
3136
3137var CloseButton = (function (_Button) {
3138  _inherits(CloseButton, _Button);
3139
3140  function CloseButton(player, options) {
3141    _classCallCheck(this, CloseButton);
3142
3143    _Button.call(this, player, options);
3144    this.controlText(options && options.controlText || this.localize('Close'));
3145  }
3146
3147  CloseButton.prototype.buildCSSClass = function buildCSSClass() {
3148    return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
3149  };
3150
3151  CloseButton.prototype.handleClick = function handleClick() {
3152    this.trigger({ type: 'close', bubbles: false });
3153  };
3154
3155  return CloseButton;
3156})(_button2['default']);
3157
3158_component2['default'].registerComponent('CloseButton', CloseButton);
3159exports['default'] = CloseButton;
3160module.exports = exports['default'];
3161
3162},{"./button":64,"./component":67}],67:[function(_dereq_,module,exports){
3163/**
3164 * @file component.js
3165 *
3166 * Player Component - Base class for all UI objects
3167 */
3168
3169'use strict';
3170
3171exports.__esModule = true;
3172
3173function _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; } }
3174
3175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3176
3177function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
3178
3179var _globalWindow = _dereq_('global/window');
3180
3181var _globalWindow2 = _interopRequireDefault(_globalWindow);
3182
3183var _utilsDomJs = _dereq_('./utils/dom.js');
3184
3185var Dom = _interopRequireWildcard(_utilsDomJs);
3186
3187var _utilsFnJs = _dereq_('./utils/fn.js');
3188
3189var Fn = _interopRequireWildcard(_utilsFnJs);
3190
3191var _utilsGuidJs = _dereq_('./utils/guid.js');
3192
3193var Guid = _interopRequireWildcard(_utilsGuidJs);
3194
3195var _utilsEventsJs = _dereq_('./utils/events.js');
3196
3197var Events = _interopRequireWildcard(_utilsEventsJs);
3198
3199var _utilsLogJs = _dereq_('./utils/log.js');
3200
3201var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
3202
3203var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
3204
3205var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
3206
3207var _objectAssign = _dereq_('object.assign');
3208
3209var _objectAssign2 = _interopRequireDefault(_objectAssign);
3210
3211var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
3212
3213var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
3214
3215/**
3216 * Base UI Component class
3217 * Components are embeddable UI objects that are represented by both a
3218 * javascript object and an element in the DOM. They can be children of other
3219 * components, and can have many children themselves.
3220 * ```js
3221 *     // adding a button to the player
3222 *     var button = player.addChild('button');
3223 *     button.el(); // -> button element
3224 * ```
3225 * ```html
3226 *     <div class="video-js">
3227 *       <div class="vjs-button">Button</div>
3228 *     </div>
3229 * ```
3230 * Components are also event targets.
3231 * ```js
3232 *     button.on('click', function(){
3233 *       console.log('Button Clicked!');
3234 *     });
3235 *     button.trigger('customevent');
3236 * ```
3237 *
3238 * @param {Object} player  Main Player
3239 * @param {Object=} options Object of option names and values
3240 * @param {Function=} ready    Ready callback function
3241 * @class Component
3242 */
3243
3244var Component = (function () {
3245  function Component(player, options, ready) {
3246    _classCallCheck(this, Component);
3247
3248    // The component might be the player itself and we can't pass `this` to super
3249    if (!player && this.play) {
3250      this.player_ = player = this; // eslint-disable-line
3251    } else {
3252        this.player_ = player;
3253      }
3254
3255    // Make a copy of prototype.options_ to protect against overriding defaults
3256    this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_);
3257
3258    // Updated options with supplied options
3259    options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options);
3260
3261    // Get ID from options or options element if one is supplied
3262    this.id_ = options.id || options.el && options.el.id;
3263
3264    // If there was no ID from the options, generate one
3265    if (!this.id_) {
3266      // Don't require the player ID function in the case of mock players
3267      var id = player && player.id && player.id() || 'no_player';
3268
3269      this.id_ = id + '_component_' + Guid.newGUID();
3270    }
3271
3272    this.name_ = options.name || null;
3273
3274    // Create element if one wasn't provided in options
3275    if (options.el) {
3276      this.el_ = options.el;
3277    } else if (options.createEl !== false) {
3278      this.el_ = this.createEl();
3279    }
3280
3281    this.children_ = [];
3282    this.childIndex_ = {};
3283    this.childNameIndex_ = {};
3284
3285    // Add any child components in options
3286    if (options.initChildren !== false) {
3287      this.initChildren();
3288    }
3289
3290    this.ready(ready);
3291    // Don't want to trigger ready here or it will before init is actually
3292    // finished for all children that run this constructor
3293
3294    if (options.reportTouchActivity !== false) {
3295      this.enableTouchActivity();
3296    }
3297  }
3298
3299  /**
3300   * Dispose of the component and all child components
3301   *
3302   * @method dispose
3303   */
3304
3305  Component.prototype.dispose = function dispose() {
3306    this.trigger({ type: 'dispose', bubbles: false });
3307
3308    // Dispose all children.
3309    if (this.children_) {
3310      for (var i = this.children_.length - 1; i >= 0; i--) {
3311        if (this.children_[i].dispose) {
3312          this.children_[i].dispose();
3313        }
3314      }
3315    }
3316
3317    // Delete child references
3318    this.children_ = null;
3319    this.childIndex_ = null;
3320    this.childNameIndex_ = null;
3321
3322    // Remove all event listeners.
3323    this.off();
3324
3325    // Remove element from DOM
3326    if (this.el_.parentNode) {
3327      this.el_.parentNode.removeChild(this.el_);
3328    }
3329
3330    Dom.removeElData(this.el_);
3331    this.el_ = null;
3332  };
3333
3334  /**
3335   * Return the component's player
3336   *
3337   * @return {Player}
3338   * @method player
3339   */
3340
3341  Component.prototype.player = function player() {
3342    return this.player_;
3343  };
3344
3345  /**
3346   * Deep merge of options objects
3347   * Whenever a property is an object on both options objects
3348   * the two properties will be merged using mergeOptions.
3349   *
3350   * ```js
3351   *     Parent.prototype.options_ = {
3352   *       optionSet: {
3353   *         'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },
3354   *         'childTwo': {},
3355   *         'childThree': {}
3356   *       }
3357   *     }
3358   *     newOptions = {
3359   *       optionSet: {
3360   *         'childOne': { 'foo': 'baz', 'abc': '123' }
3361   *         'childTwo': null,
3362   *         'childFour': {}
3363   *       }
3364   *     }
3365   *
3366   *     this.options(newOptions);
3367   * ```
3368   * RESULT
3369   * ```js
3370   *     {
3371   *       optionSet: {
3372   *         'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' },
3373   *         'childTwo': null, // Disabled. Won't be initialized.
3374   *         'childThree': {},
3375   *         'childFour': {}
3376   *       }
3377   *     }
3378   * ```
3379   *
3380   * @param  {Object} obj Object of new option values
3381   * @return {Object}     A NEW object of this.options_ and obj merged
3382   * @method options
3383   */
3384
3385  Component.prototype.options = function options(obj) {
3386    _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
3387
3388    if (!obj) {
3389      return this.options_;
3390    }
3391
3392    this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj);
3393    return this.options_;
3394  };
3395
3396  /**
3397   * Get the component's DOM element
3398   * ```js
3399   *     var domEl = myComponent.el();
3400   * ```
3401   *
3402   * @return {Element}
3403   * @method el
3404   */
3405
3406  Component.prototype.el = function el() {
3407    return this.el_;
3408  };
3409
3410  /**
3411   * Create the component's DOM element
3412   *
3413   * @param  {String=} tagName  Element's node type. e.g. 'div'
3414   * @param  {Object=} properties An object of properties that should be set
3415   * @param  {Object=} attributes An object of attributes that should be set
3416   * @return {Element}
3417   * @method createEl
3418   */
3419
3420  Component.prototype.createEl = function createEl(tagName, properties, attributes) {
3421    return Dom.createEl(tagName, properties, attributes);
3422  };
3423
3424  Component.prototype.localize = function localize(string) {
3425    var code = this.player_.language && this.player_.language();
3426    var languages = this.player_.languages && this.player_.languages();
3427
3428    if (!code || !languages) {
3429      return string;
3430    }
3431
3432    var language = languages[code];
3433
3434    if (language && language[string]) {
3435      return language[string];
3436    }
3437
3438    var primaryCode = code.split('-')[0];
3439    var primaryLang = languages[primaryCode];
3440
3441    if (primaryLang && primaryLang[string]) {
3442      return primaryLang[string];
3443    }
3444
3445    return string;
3446  };
3447
3448  /**
3449   * Return the component's DOM element where children are inserted.
3450   * Will either be the same as el() or a new element defined in createEl().
3451   *
3452   * @return {Element}
3453   * @method contentEl
3454   */
3455
3456  Component.prototype.contentEl = function contentEl() {
3457    return this.contentEl_ || this.el_;
3458  };
3459
3460  /**
3461   * Get the component's ID
3462   * ```js
3463   *     var id = myComponent.id();
3464   * ```
3465   *
3466   * @return {String}
3467   * @method id
3468   */
3469
3470  Component.prototype.id = function id() {
3471    return this.id_;
3472  };
3473
3474  /**
3475   * Get the component's name. The name is often used to reference the component.
3476   * ```js
3477   *     var name = myComponent.name();
3478   * ```
3479   *
3480   * @return {String}
3481   * @method name
3482   */
3483
3484  Component.prototype.name = function name() {
3485    return this.name_;
3486  };
3487
3488  /**
3489   * Get an array of all child components
3490   * ```js
3491   *     var kids = myComponent.children();
3492   * ```
3493   *
3494   * @return {Array} The children
3495   * @method children
3496   */
3497
3498  Component.prototype.children = function children() {
3499    return this.children_;
3500  };
3501
3502  /**
3503   * Returns a child component with the provided ID
3504   *
3505   * @return {Component}
3506   * @method getChildById
3507   */
3508
3509  Component.prototype.getChildById = function getChildById(id) {
3510    return this.childIndex_[id];
3511  };
3512
3513  /**
3514   * Returns a child component with the provided name
3515   *
3516   * @return {Component}
3517   * @method getChild
3518   */
3519
3520  Component.prototype.getChild = function getChild(name) {
3521    return this.childNameIndex_[name];
3522  };
3523
3524  /**
3525   * Adds a child component inside this component
3526   * ```js
3527   *     myComponent.el();
3528   *     // -> <div class='my-component'></div>
3529   *     myComponent.children();
3530   *     // [empty array]
3531   *
3532   *     var myButton = myComponent.addChild('MyButton');
3533   *     // -> <div class='my-component'><div class="my-button">myButton<div></div>
3534   *     // -> myButton === myComponent.children()[0];
3535   * ```
3536   * Pass in options for child constructors and options for children of the child
3537   * ```js
3538   *     var myButton = myComponent.addChild('MyButton', {
3539   *       text: 'Press Me',
3540   *       buttonChildExample: {
3541   *         buttonChildOption: true
3542   *       }
3543   *     });
3544   * ```
3545   *
3546   * @param {String|Component} child The class name or instance of a child to add
3547   * @param {Object=} options Options, including options to be passed to children of the child.
3548   * @param {Number} index into our children array to attempt to add the child
3549   * @return {Component} The child component (created by this process if a string was used)
3550   * @method addChild
3551   */
3552
3553  Component.prototype.addChild = function addChild(child) {
3554    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
3555    var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2];
3556
3557    var component = undefined;
3558    var componentName = undefined;
3559
3560    // If child is a string, create nt with options
3561    if (typeof child === 'string') {
3562      componentName = child;
3563
3564      // Options can also be specified as a boolean, so convert to an empty object if false.
3565      if (!options) {
3566        options = {};
3567      }
3568
3569      // Same as above, but true is deprecated so show a warning.
3570      if (options === true) {
3571        _utilsLogJs2['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`.');
3572        options = {};
3573      }
3574
3575      // If no componentClass in options, assume componentClass is the name lowercased
3576      // (e.g. playButton)
3577      var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName);
3578
3579      // Set name through options
3580      options.name = componentName;
3581
3582      // Create a new object & element for this controls set
3583      // If there's no .player_, this is a player
3584      var ComponentClass = Component.getComponent(componentClassName);
3585
3586      if (!ComponentClass) {
3587        throw new Error('Component ' + componentClassName + ' does not exist');
3588      }
3589
3590      // data stored directly on the videojs object may be
3591      // misidentified as a component to retain
3592      // backwards-compatibility with 4.x. check to make sure the
3593      // component class can be instantiated.
3594      if (typeof ComponentClass !== 'function') {
3595        return null;
3596      }
3597
3598      component = new ComponentClass(this.player_ || this, options);
3599
3600      // child is a component instance
3601    } else {
3602        component = child;
3603      }
3604
3605    this.children_.splice(index, 0, component);
3606
3607    if (typeof component.id === 'function') {
3608      this.childIndex_[component.id()] = component;
3609    }
3610
3611    // If a name wasn't used to create the component, check if we can use the
3612    // name function of the component
3613    componentName = componentName || component.name && component.name();
3614
3615    if (componentName) {
3616      this.childNameIndex_[componentName] = component;
3617    }
3618
3619    // Add the UI object's element to the container div (box)
3620    // Having an element is not required
3621    if (typeof component.el === 'function' && component.el()) {
3622      var childNodes = this.contentEl().children;
vendor: 5,718 bytes, lines 3623-3806
3623      var refNode = childNodes[index] || null;
3624      this.contentEl().insertBefore(component.el(), refNode);
3625    }
3626
3627    // Return so it can stored on parent object if desired.
3628    return component;
3629  };
3630
3631  /**
3632   * Remove a child component from this component's list of children, and the
3633   * child component's element from this component's element
3634   *
3635   * @param  {Component} component Component to remove
3636   * @method removeChild
3637   */
3638
3639  Component.prototype.removeChild = function removeChild(component) {
3640    if (typeof component === 'string') {
3641      component = this.getChild(component);
3642    }
3643
3644    if (!component || !this.children_) {
3645      return;
3646    }
3647
3648    var childFound = false;
3649
3650    for (var i = this.children_.length - 1; i >= 0; i--) {
3651      if (this.children_[i] === component) {
3652        childFound = true;
3653        this.children_.splice(i, 1);
3654        break;
3655      }
3656    }
3657
3658    if (!childFound) {
3659      return;
3660    }
3661
3662    this.childIndex_[component.id()] = null;
3663    this.childNameIndex_[component.name()] = null;
3664
3665    var compEl = component.el();
3666
3667    if (compEl && compEl.parentNode === this.contentEl()) {
3668      this.contentEl().removeChild(component.el());
3669    }
3670  };
3671
3672  /**
3673   * Add and initialize default child components from options
3674   * ```js
3675   *     // when an instance of MyComponent is created, all children in options
3676   *     // will be added to the instance by their name strings and options
3677   *     MyComponent.prototype.options_ = {
3678   *       children: [
3679   *         'myChildComponent'
3680   *       ],
3681   *       myChildComponent: {
3682   *         myChildOption: true
3683   *       }
3684   *     };
3685   *
3686   *     // Or when creating the component
3687   *     var myComp = new MyComponent(player, {
3688   *       children: [
3689   *         'myChildComponent'
3690   *       ],
3691   *       myChildComponent: {
3692   *         myChildOption: true
3693   *       }
3694   *     });
3695   * ```
3696   * The children option can also be an array of
3697   * child options objects (that also include a 'name' key).
3698   * This can be used if you have two child components of the
3699   * same type that need different options.
3700   * ```js
3701   *     var myComp = new MyComponent(player, {
3702   *       children: [
3703   *         'button',
3704   *         {
3705   *           name: 'button',
3706   *           someOtherOption: true
3707   *         },
3708   *         {
3709   *           name: 'button',
3710   *           someOtherOption: false
3711   *         }
3712   *       ]
3713   *     });
3714   * ```
3715   *
3716   * @method initChildren
3717   */
3718
3719  Component.prototype.initChildren = function initChildren() {
3720    var _this = this;
3721
3722    var children = this.options_.children;
3723
3724    if (children) {
3725      (function () {
3726        // `this` is `parent`
3727        var parentOptions = _this.options_;
3728
3729        var handleAdd = function handleAdd(child) {
3730          var name = child.name;
3731          var opts = child.opts;
3732
3733          // Allow options for children to be set at the parent options
3734          // e.g. videojs(id, { controlBar: false });
3735          // instead of videojs(id, { children: { controlBar: false });
3736          if (parentOptions[name] !== undefined) {
3737            opts = parentOptions[name];
3738          }
3739
3740          // Allow for disabling default components
3741          // e.g. options['children']['posterImage'] = false
3742          if (opts === false) {
3743            return;
3744          }
3745
3746          // Allow options to be passed as a simple boolean if no configuration
3747          // is necessary.
3748          if (opts === true) {
3749            opts = {};
3750          }
3751
3752          // We also want to pass the original player options to each component as well so they don't need to
3753          // reach back into the player for options later.
3754          opts.playerOptions = _this.options_.playerOptions;
3755
3756          // Create and add the child component.
3757          // Add a direct reference to the child by name on the parent instance.
3758          // If two of the same component are used, different names should be supplied
3759          // for each
3760          var newChild = _this.addChild(name, opts);
3761          if (newChild) {
3762            _this[name] = newChild;
3763          }
3764        };
3765
3766        // Allow for an array of children details to passed in the options
3767        var workingChildren = undefined;
3768        var Tech = Component.getComponent('Tech');
3769
3770        if (Array.isArray(children)) {
3771          workingChildren = children;
3772        } else {
3773          workingChildren = Object.keys(children);
3774        }
3775
3776        workingChildren
3777        // children that are in this.options_ but also in workingChildren  would
3778        // give us extra children we do not want. So, we want to filter them out.
3779        .concat(Object.keys(_this.options_).filter(function (child) {
3780          return !workingChildren.some(function (wchild) {
3781            if (typeof wchild === 'string') {
3782              return child === wchild;
3783            } else {
3784              return child === wchild.name;
3785            }
3786          });
3787        })).map(function (child) {
3788          var name = undefined,
3789              opts = undefined;
3790
3791          if (typeof child === 'string') {
3792            name = child;
3793            opts = children[name] || _this.options_[name] || {};
3794          } else {
3795            name = child.name;
3796            opts = child;
3797          }
3798
3799          return { name: name, opts: opts };
3800        }).filter(function (child) {
3801          // we have to make sure that child.name isn't in the techOrder since
3802          // techs are registerd as Components but can't aren't compatible
3803          // See https://github.com/videojs/video.js/issues/2772
3804          var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name));
3805          return c && !Tech.isTech(c);
3806        }
3806).forEach(handleAdd);
3807      })();
3808    }
3809  };
3810
3811  /**
3812   * Allows sub components to stack CSS class names
3813   *
3814   * @return {String} The constructed class name
3815   * @method buildCSSClass
3816   */
3817
3818  Component.prototype.buildCSSClass = function buildCSSClass() {
3819    // Child classes can include a function that does:
3820    // return 'CLASS NAME' + this._super();
3821    return '';
3822  };
3823
3824  /**
3825   * Add an event listener to this component's element
3826   * ```js
3827   *     var myFunc = function(){
3828   *       var myComponent = this;
3829   *       // Do something when the event is fired
3830   *     };
3831   *
3832   *     myComponent.on('eventType', myFunc);
3833   * ```
3834   * The context of myFunc will be myComponent unless previously bound.
3835   * Alternatively, you can add a listener to another element or component.
3836   * ```js
3837   *     myComponent.on(otherElement, 'eventName', myFunc);
3838   *     myComponent.on(otherComponent, 'eventName', myFunc);
3839   * ```
3840   * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)`
3841   * and `otherComponent.on('eventName', myFunc)` is that this way the listeners
3842   * will be automatically cleaned up when either component is disposed.
3843   * It will also bind myComponent as the context of myFunc.
3844   * **NOTE**: When using this on elements in the page other than window
3845   * and document (both permanent), if you remove the element from the DOM
3846   * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up
3847   * references to it and allow the browser to garbage collect it.
3848   *
3849   * @param  {String|Component} first   The event type or other component
3850   * @param  {Function|String}      second  The event handler or event type
3851   * @param  {Function}             third   The event handler
3852   * @return {Component}
3853   * @method on
3854   */
3855
3856  Component.prototype.on = function on(first, second, third) {
3857    var _this2 = this;
3858
3859    if (typeof first === 'string' || Array.isArray(first)) {
3860      Events.on(this.el_, first, Fn.bind(this, second));
3861
3862      // Targeting another component or element
3863    } else {
3864        (function () {
3865          var target = first;
3866          var type = second;
3867          var fn = Fn.bind(_this2, third);
3868
3869          // When this component is disposed, remove the listener from the other component
3870          var removeOnDispose = function removeOnDispose() {
3871            return _this2.off(target, type, fn);
3872          };
3873
3874          // Use the same function ID so we can remove it later it using the ID
3875          // of the original listener
3876          removeOnDispose.guid = fn.guid;
3877          _this2.on('dispose', removeOnDispose);
3878
3879          // If the other component is disposed first we need to clean the reference
3880          // to the other component in this component's removeOnDispose listener
3881          // Otherwise we create a memory leak.
3882          var cleanRemover = function cleanRemover() {
3883            return _this2.off('dispose', removeOnDispose);
3884          };
3885
3886          // Add the same function ID so we can easily remove it later
3887          cleanRemover.guid = fn.guid;
3888
3889          // Check if this is a DOM node
3890          if (first.nodeName) {
3891            // Add the listener to the other element
3892            Events.on(target, type, fn);
3893            Events.on(target, 'dispose', cleanRemover);
3894
3895            // Should be a component
3896            // Not using `instanceof Component` because it makes mock players difficult
3897          } else if (typeof first.on === 'function') {
3898              // Add the listener to the other component
3899              target.on(type, fn);
3900              target.on('dispose', cleanRemover);
3901            }
3902        })();
3903      }
3904
3905    return this;
3906  };
3907
3908  /**
3909   * Remove an event listener from this component's element
3910   * ```js
3911   *     myComponent.off('eventType', myFunc);
3912   * ```
3913   * If myFunc is excluded, ALL listeners for the event type will be removed.
3914   * If eventType is excluded, ALL listeners will be removed from the component.
3915   * Alternatively you can use `off` to remove listeners that were added to other
3916   * elements or components using `myComponent.on(otherComponent...`.
3917   * In this case both the event type and listener function are REQUIRED.
3918   * ```js
3919   *     myComponent.off(otherElement, 'eventType', myFunc);
3920   *     myComponent.off(otherComponent, 'eventType', myFunc);
3921   * ```
3922   *
3923   * @param  {String=|Component}  first  The event type or other component
3924   * @param  {Function=|String}       second The listener function or event type
3925   * @param  {Function=}              third  The listener for other component
3926   * @return {Component}
3927   * @method off
3928   */
3929
3930  Component.prototype.off = function off(first, second, third) {
3931    if (!first || typeof first === 'string' || Array.isArray(first)) {
3932      Events.off(this.el_, first, second);
3933    } else {
3934      var target = first;
3935      var type = second;
3936      // Ensure there's at least a guid, even if the function hasn't been used
3937      var fn = Fn.bind(this, third);
3938
3939      // Remove the dispose listener on this component,
3940      // which was given the same guid as the event listener
3941      this.off('dispose', fn);
3942
3943      if (first.nodeName) {
3944        // Remove the listener
3945        Events.off(target, type, fn);
3946        // Remove the listener for cleaning the dispose listener
3947        Events.off(target, 'dispose', fn);
3948      } else {
3949        target.off(type, fn);
3950        target.off('dispose', fn);
3951      }
3952    }
3953
3954    return this;
3955  };
3956
3957  /**
3958   * Add an event listener to be triggered only once and then removed
3959   * ```js
3960   *     myComponent.one('eventName', myFunc);
3961   * ```
3962   * Alternatively you can add a listener to another element or component
3963   * that will be triggered only once.
3964   * ```js
3965   *     myComponent.one(otherElement, 'eventName', myFunc);
3966   *     myComponent.one(otherComponent, 'eventName', myFunc);
3967   * ```
3968   *
3969   * @param  {String|Component}  first   The event type or other component
3970   * @param  {Function|String}       second  The listener function or event type
3971   * @param  {Function=}             third   The listener function for other component
3972   * @return {Component}
3973   * @method one
3974   */
3975
3976  Component.prototype.one = function one(first, second, third) {
3977    var _this3 = this,
3978        _arguments = arguments;
3979
3980    if (typeof first === 'string' || Array.isArray(first)) {
3981      Events.one(this.el_, first, Fn.bind(this, second));
3982    } else {
3983      (function () {
3984        var target = first;
3985        var type = second;
3986        var fn = Fn.bind(_this3, third);
3987
3988        var newFunc = function newFunc() {
3989          _this3.off(target, type, newFunc);
3990          fn.apply(null, _arguments);
3991        };
3992
3993        // Keep the same function ID so we can remove it later
3994        newFunc.guid = fn.guid;
3995
3996        _this3.on(target, type, newFunc);
3997      })();
3998    }
3999
4000    return this;
4001  };
4002
4003  /**
4004   * Trigger an event on an element
4005   * ```js
4006   *     myComponent.trigger('eventName');
4007   *     myComponent.trigger({'type':'eventName'});
4008   *     myComponent.trigger('eventName', {data: 'some data'});
4009   *     myComponent.trigger({'type':'eventName'}, {data: 'some data'});
4010   * ```
4011   *
4012   * @param  {Event|Object|String} event  A string (the type) or an event object with a type attribute
4013   * @param  {Object} [hash] data hash to pass along with the event
4014   * @return {Component}       self
4015   * @method trigger
4016   */
4017
4018  Component.prototype.trigger = function trigger(event, hash) {
4019    Events.trigger(this.el_, event, hash);
4020    return this;
4021  };
4022
4023  /**
4024   * Bind a listener to the component's ready state.
4025   * Different from event listeners in that if the ready event has already happened
4026   * it will trigger the function immediately.
4027   *
4028   * @param  {Function} fn Ready listener
4029   * @param  {Boolean} sync Exec the listener synchronously if component is ready
4030   * @return {Component}
4031   * @method ready
4032   */
4033
4034  Component.prototype.ready = function ready(fn) {
4035    var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
4036
4037    if (fn) {
4038      if (this.isReady_) {
4039        if (sync) {
4040          fn.call(this);
4041        } else {
4042          // Call the function asynchronously by default for consistency
4043          this.setTimeout(fn, 1);
4044        }
4045      } else {
4046        this.readyQueue_ = this.readyQueue_ || [];
4047        this.readyQueue_.push(fn);
4048      }
4049    }
4050    return this;
4051  };
4052
4053  /**
4054   * Trigger the ready listeners
4055   *
4056   * @return {Component}
4057   * @method triggerReady
4058   */
4059
4060  Component.prototype.triggerReady = function triggerReady() {
4061    this.isReady_ = true;
4062
4063    // Ensure ready is triggerd asynchronously
4064    this.setTimeout(function () {
4065      var readyQueue = this.readyQueue_;
4066
4067      // Reset Ready Queue
4068      this.readyQueue_ = [];
4069
4070      if (readyQueue && readyQueue.length > 0) {
4071        readyQueue.forEach(function (fn) {
4072          fn.call(this);
4073        }, this);
4074      }
4075
4076      // Allow for using event listeners also
4077      this.trigger('ready');
4078    }, 1);
4079  };
4080
4081  /**
4082   * Finds a single DOM element matching `selector` within the component's
4083   * `contentEl` or another custom context.
4084   *
4085   * @method $
4086   * @param  {String} selector
4087   *         A valid CSS selector, which will be passed to `querySelector`.
4088   *
4089   * @param  {Element|String} [context=document]
4090   *         A DOM element within which to query. Can also be a selector
4091   *         string in which case the first matching element will be used
4092   *         as context. If missing (or no element matches selector), falls
4093   *         back to `document`.
4094   *
4095   * @return {Element|null}
4096   */
4097
4098  Component.prototype.$ = function $(selector, context) {
4099    return Dom.$(selector, context || this.contentEl());
4100  };
4101
4102  /**
4103   * Finds a all DOM elements matching `selector` within the component's
4104   * `contentEl` or another custom context.
4105   *
4106   * @method $$
4107   * @param  {String} selector
4108   *         A valid CSS selector, which will be passed to `querySelectorAll`.
4109   *
4110   * @param  {Element|String} [context=document]
4111   *         A DOM element within which to query. Can also be a selector
4112   *         string in which case the first matching element will be used
4113   *         as context. If missing (or no element matches selector), falls
4114   *         back to `document`.
4115   *
4116   * @return {NodeList}
4117   */
4118
4119  Component.prototype.$$ = function $$(selector, context) {
4120    return Dom.$$(selector, context || this.contentEl());
4121  };
4122
4123  /**
4124   * Check if a component's element has a CSS class name
4125   *
4126   * @param {String} classToCheck Classname to check
4127   * @return {Component}
4128   * @method hasClass
4129   */
4130
4131  Component.prototype.hasClass = function hasClass(classToCheck) {
4132    return Dom.hasElClass(this.el_, classToCheck);
4133  };
4134
4135  /**
4136   * Add a CSS class name to the component's element
4137   *
4138   * @param {String} classToAdd Classname to add
4139   * @return {Component}
4140   * @method addClass
4141   */
4142
4143  Component.prototype.addClass = function addClass(classToAdd) {
4144    Dom.addElClass(this.el_, classToAdd);
4145    return this;
4146  };
4147
4148  /**
4149   * Remove a CSS class name from the component's element
4150   *
4151   * @param {String} classToRemove Classname to remove
4152   * @return {Component}
4153   * @method removeClass
4154   */
4155
4156  Component.prototype.removeClass = function removeClass(classToRemove) {
4157    Dom.removeElClass(this.el_, classToRemove);
4158    return this;
4159  };
4160
4161  /**
4162   * Add or remove a CSS class name from the component's element
4163   *
4164   * @param  {String} classToToggle
4165   * @param  {Boolean|Function} [predicate]
4166   *         Can be a function that returns a Boolean. If `true`, the class
4167   *         will be added; if `false`, the class will be removed. If not
4168   *         given, the class will be added if not present and vice versa.
4169   *
4170   * @return {Component}
4171   * @method toggleClass
4172   */
4173
4174  Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
4175    Dom.toggleElClass(this.el_, classToToggle, predicate);
4176    return this;
4177  };
4178
4179  /**
4180   * Show the component element if hidden
4181   *
4182   * @return {Component}
4183   * @method show
4184   */
4185
4186  Component.prototype.show = function show() {
4187    this.removeClass('vjs-hidden');
4188    return this;
4189  };
4190
4191  /**
4192   * Hide the component element if currently showing
4193   *
4194   * @return {Component}
4195   * @method hide
4196   */
4197
4198  Component.prototype.hide = function hide() {
4199    this.addClass('vjs-hidden');
4200    return this;
4201  };
4202
4203  /**
4204   * Lock an item in its visible state
4205   * To be used with fadeIn/fadeOut.
4206   *
4207   * @return {Component}
4208   * @private
4209   * @method lockShowing
4210   */
4211
4212  Component.prototype.lockShowing = function lockShowing() {
4213    this.addClass('vjs-lock-showing');
4214    return this;
4215  };
4216
4217  /**
4218   * Unlock an item to be hidden
4219   * To be used with fadeIn/fadeOut.
4220   *
4221   * @return {Component}
4222   * @private
4223   * @method unlockShowing
4224   */
4225
4226  Component.prototype.unlockShowing = function unlockShowing() {
4227    this.removeClass('vjs-lock-showing');
4228    return this;
4229  };
4230
4231  /**
4232   * Set or get the width of the component (CSS values)
4233   * Setting the video tag dimension values only works with values in pixels.
4234   * Percent values will not work.
4235   * Some percents can be used, but width()/height() will return the number + %,
4236   * not the actual computed width/height.
4237   *
4238   * @param  {Number|String=} num   Optional width number
4239   * @param  {Boolean} skipListeners Skip the 'resize' event trigger
4240   * @return {Component} This component, when setting the width
4241   * @return {Number|String} The width, when getting
4242   * @method width
4243   */
4244
4245  Component.prototype.width = function width(num, skipListeners) {
4246    return this.dimension('width', num, skipListeners);
4247  };
4248
4249  /**
4250   * Get or set the height of the component (CSS values)
4251   * Setting the video tag dimension values only works with values in pixels.
4252   * Percent values will not work.
4253   * Some percents can be used, but width()/height() will return the number + %,
4254   * not the actual computed width/height.
4255   *
4256   * @param  {Number|String=} num     New component height
4257   * @param  {Boolean=} skipListeners Skip the resize event trigger
4258   * @return {Component} This component, when setting the height
4259   * @return {Number|String} The height, when getting
4260   * @method height
4261   */
4262
4263  Component.prototype.height = function height(num, skipListeners) {
4264    return this.dimension('height', num, skipListeners);
4265  };
4266
4267  /**
4268   * Set both width and height at the same time
4269   *
4270   * @param  {Number|String} width Width of player
4271   * @param  {Number|String} height Height of player
4272   * @return {Component} The component
4273   * @method dimensions
4274   */
4275
4276  Component.prototype.dimensions = function dimensions(width, height) {
4277    // Skip resize listeners on width for optimization
4278    return this.width(width, true).height(height);
4279  };
4280
4281  /**
4282   * Get or set width or height
4283   * This is the shared code for the width() and height() methods.
4284   * All for an integer, integer + 'px' or integer + '%';
4285   * Known issue: Hidden elements officially have a width of 0. We're defaulting
4286   * to the style.width value and falling back to computedStyle which has the
4287   * hidden element issue. Info, but probably not an efficient fix:
4288   * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/
4289   *
4290   * @param  {String} widthOrHeight  'width' or 'height'
4291   * @param  {Number|String=} num     New dimension
4292   * @param  {Boolean=} skipListeners Skip resize event trigger
4293   * @return {Component} The component if a dimension was set
4294   * @return {Number|String} The dimension if nothing was set
4295   * @private
4296   * @method dimension
4297   */
4298
4299  Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
4300    if (num !== undefined) {
4301      // Set to zero if null or literally NaN (NaN !== NaN)
4302      if (num === null || num !== num) {
4303        num = 0;
4304      }
4305
4306      // Check if using css width/height (% or px) and adjust
4307      if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
4308        this.el_.style[widthOrHeight] = num;
4309      } else if (num === 'auto') {
4310        this.el_.style[widthOrHeight] = '';
4311      } else {
4312        this.el_.style[widthOrHeight] = num + 'px';
4313      }
4314
4315      // skipListeners allows us to avoid triggering the resize event when setting both width and height
4316      if (!skipListeners) {
4317        this.trigger('resize');
4318      }
4319
4320      // Return component
4321      return this;
4322    }
4323
4324    // Not setting a value, so getting it
4325    // Make sure element exists
4326    if (!this.el_) {
4327      return 0;
4328    }
4329
4330    // Get dimension value from style
4331    var val = this.el_.style[widthOrHeight];
4332    var pxIndex = val.indexOf('px');
4333
4334    if (pxIndex !== -1) {
4335      // Return the pixel value with no 'px'
4336      return parseInt(val.slice(0, pxIndex), 10);
4337    }
4338
4339    // No px so using % or no style was set, so falling back to offsetWidth/height
4340    // If component has display:none, offset will return 0
4341    // TODO: handle display:none and no dimension style using px
4342    return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10);
4343  };
4344
4345  /**
4346   * Get width or height of computed style
4347   * @param  {String} widthOrHeight  'width' or 'height'
4348   * @return {Number|Boolean} The bolean false if nothing was set
4349   * @method currentDimension
4350   */
4351
4352  Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
4353    var computedWidthOrHeight = 0;
4354
4355    if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
4356      throw new Error('currentDimension only accepts width or height value');
4357    }
4358
4359    if (typeof _globalWindow2['default'].getComputedStyle === 'function') {
4360      var computedStyle = _globalWindow2['default'].getComputedStyle(this.el_);
4361      computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
4362    } else if (this.el_.currentStyle) {
4363      // ie 8 doesn't support computed style, shim it
4364      // return clientWidth or clientHeight instead for better accuracy
4365      var rule = 'offset' + _utilsToTitleCaseJs2['default'](widthOrHeight);
4366      computedWidthOrHeight = this.el_[rule];
4367    }
4368
4369    // remove 'px' from variable and parse as integer
4370    computedWidthOrHeight = parseFloat(computedWidthOrHeight);
4371    return computedWidthOrHeight;
4372  };
4373
4374  /**
4375   * Get an object which contains width and height values of computed style
4376   * @return {Object} The dimensions of element
4377   * @method currentDimensions
4378   */
4379
4380  Component.prototype.currentDimensions = function currentDimensions() {
4381    return {
4382      width: this.currentDimension('width'),
4383      height: this.currentDimension('height')
4384    };
4385  };
4386
4387  /**
4388   * Get width of computed style
4389   * @return {Integer}
4390   * @method currentWidth
4391   */
4392
4393  Component.prototype.currentWidth = function currentWidth() {
4394    return this.currentDimension('width');
4395  };
4396
4397  /**
4398   * Get height of computed style
4399   * @return {Integer}
4400   * @method currentHeight
4401   */
4402
4403  Component.prototype.currentHeight = function currentHeight() {
4404    return this.currentDimension('height');
4405  };
4406
4407  /**
4408   * Emit 'tap' events when touch events are supported
4409   * This is used to support toggling the controls through a tap on the video.
4410   * We're requiring them to be enabled because otherwise every component would
4411   * have this extra overhead unnecessarily, on mobile devices where extra
4412   * overhead is especially bad.
4413   *
4414   * @private
4415   * @method emitTapEvents
4416   */
4417
4418  Component.prototype.emitTapEvents = function emitTapEvents() {
4419    // Track the start time so we can determine how long the touch lasted
4420    var touchStart = 0;
4421    var firstTouch = null;
4422
4423    // Maximum movement allowed during a touch event to still be considered a tap
4424    // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
4425    var tapMovementThreshold = 10;
4426
4427    // The maximum length a touch can be while still being considered a tap
4428    var touchTimeThreshold = 200;
4429
4430    var couldBeTap = undefined;
4431
4432    this.on('touchstart', function (event) {
4433      // If more than one finger, don't consider treating this as a click
4434      if (event.touches.length === 1) {
4435        // Copy the touches object to prevent modifying the original
4436        firstTouch = _objectAssign2['default']({}, event.touches[0]);
4437        // Record start time so we can detect a tap vs. "touch and hold"
4438        touchStart = new Date().getTime();
4439        // Reset couldBeTap tracking
4440        couldBeTap = true;
4441      }
4442    });
4443
4444    this.on('touchmove', function (event) {
4445      // If more than one finger, don't consider treating this as a click
4446      if (event.touches.length > 1) {
4447        couldBeTap = false;
vendor: 4,486 bytes, lines 4448-4557
4448      } else if (firstTouch) {
4449        // Some devices will throw touchmoves for all but the slightest of taps.
4450        // So, if we moved only a small distance, this could still be a tap
4451        var xdiff = event.touches[0].pageX - firstTouch.pageX;
4452        var ydiff = event.touches[0].pageY - firstTouch.pageY;
4453        var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
4454
4455        if (touchDistance > tapMovementThreshold) {
4456          couldBeTap = false;
4457        }
4458      }
4459    });
4460
4461    var noTap = function noTap() {
4462      couldBeTap = false;
4463    };
4464
4465    // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
4466    this.on('touchleave', noTap);
4467    this.on('touchcancel', noTap);
4468
4469    // When the touch ends, measure how long it took and trigger the appropriate
4470    // event
4471    this.on('touchend', function (event) {
4472      firstTouch = null;
4473      // Proceed only if the touchmove/leave/cancel event didn't happen
4474      if (couldBeTap === true) {
4475        // Measure how long the touch lasted
4476        var touchTime = new Date().getTime() - touchStart;
4477
4478        // Make sure the touch was less than the threshold to be considered a tap
4479        if (touchTime < touchTimeThreshold) {
4480          // Don't let browser turn this into a click
4481          event.preventDefault();
4482          this.trigger('tap');
4483          // It may be good to copy the touchend event object and change the
4484          // type to tap, if the other event properties aren't exact after
4485          // Events.fixEvent runs (e.g. event.target)
4486        }
4487      }
4488    });
4489  };
4490
4491  /**
4492   * Report user touch activity when touch events occur
4493   * User activity is used to determine when controls should show/hide. It's
4494   * relatively simple when it comes to mouse events, because any mouse event
4495   * should show the controls. So we capture mouse events that bubble up to the
4496   * player and report activity when that happens.
4497   * With touch events it isn't as easy. We can't rely on touch events at the
4498   * player level, because a tap (touchstart + touchend) on the video itself on
4499   * mobile devices is meant to turn controls off (and on). User activity is
4500   * checked asynchronously, so what could happen is a tap event on the video
4501   * turns the controls off, then the touchend event bubbles up to the player,
4502   * which if it reported user activity, would turn the controls right back on.
4503   * (We also don't want to completely block touch events from bubbling up)
4504   * Also a touchmove, touch+hold, and anything other than a tap is not supposed
4505   * to turn the controls back on on a mobile device.
4506   * Here we're setting the default component behavior to report user activity
4507   * whenever touch events happen, and this can be turned off by components that
4508   * want touch events to act differently.
4509   *
4510   * @method enableTouchActivity
4511   */
4512
4513  Component.prototype.enableTouchActivity = function enableTouchActivity() {
4514    // Don't continue if the root player doesn't support reporting user activity
4515    if (!this.player() || !this.player().reportUserActivity) {
4516      return;
4517    }
4518
4519    // listener for reporting that the user is active
4520    var report = Fn.bind(this.player(), this.player().reportUserActivity);
4521
4522    var touchHolding = undefined;
4523
4524    this.on('touchstart', function () {
4525      report();
4526      // For as long as the they are touching the device or have their mouse down,
4527      // we consider them active even if they're not moving their finger or mouse.
4528      // So we want to continue to update that they are active
4529      this.clearInterval(touchHolding);
4530      // report at the same interval as activityCheck
4531      touchHolding = this.setInterval(report, 250);
4532    });
4533
4534    var touchEnd = function touchEnd(event) {
4535      report();
4536      // stop the interval that maintains activity if the touch is holding
4537      this.clearInterval(touchHolding);
4538    };
4539
4540    this.on('touchmove', report);
4541    this.on('touchend', touchEnd);
4542    this.on('touchcancel', touchEnd);
4543  };
4544
4545  /**
4546   * Creates timeout and sets up disposal automatically.
4547   *
4548   * @param {Function} fn The function to run after the timeout.
4549   * @param {Number} timeout Number of ms to delay before executing specified function.
4550   * @return {Number} Returns the timeout ID
4551   * @method setTimeout
4552   */
4553
4554  Component.prototype.setTimeout = function setTimeout(fn, timeout) {
4555    fn = Fn.bind(this, fn);
4556
4557    // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/
4557or Phantomjs, we can't.
4558    var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout);
4559
4560    var disposeFn = function disposeFn() {
4561      this.clearTimeout(timeoutId);
4562    };
4563
4564    disposeFn.guid = 'vjs-timeout-' + timeoutId;
4565
4566    this.on('dispose', disposeFn);
4567
4568    return timeoutId;
4569  };
4570
4571  /**
4572   * Clears a timeout and removes the associated dispose listener
4573   *
4574   * @param {Number} timeoutId The id of the timeout to clear
4575   * @return {Number} Returns the timeout ID
4576   * @method clearTimeout
4577   */
4578
4579  Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
4580    _globalWindow2['default'].clearTimeout(timeoutId);
4581
4582    var disposeFn = function disposeFn() {};
4583
4584    disposeFn.guid = 'vjs-timeout-' + timeoutId;
4585
4586    this.off('dispose', disposeFn);
4587
4588    return timeoutId;
4589  };
4590
4591  /**
4592   * Creates an interval and sets up disposal automatically.
4593   *
4594   * @param {Function} fn The function to run every N seconds.
4595   * @param {Number} interval Number of ms to delay before executing specified function.
4596   * @return {Number} Returns the interval ID
4597   * @method setInterval
4598   */
4599
4600  Component.prototype.setInterval = function setInterval(fn, interval) {
4601    fn = Fn.bind(this, fn);
4602
4603    var intervalId = _globalWindow2['default'].setInterval(fn, interval);
4604
4605    var disposeFn = function disposeFn() {
4606      this.clearInterval(intervalId);
4607    };
4608
4609    disposeFn.guid = 'vjs-interval-' + intervalId;
4610
4611    this.on('dispose', disposeFn);
4612
4613    return intervalId;
4614  };
4615
4616  /**
4617   * Clears an interval and removes the associated dispose listener
4618   *
4619   * @param {Number} intervalId The id of the interval to clear
4620   * @return {Number} Returns the interval ID
4621   * @method clearInterval
4622   */
4623
4624  Component.prototype.clearInterval = function clearInterval(intervalId) {
4625    _globalWindow2['default'].clearInterval(intervalId);
4626
4627    var disposeFn = function disposeFn() {};
4628
4629    disposeFn.guid = 'vjs-interval-' + intervalId;
4630
4631    this.off('dispose', disposeFn);
4632
4633    return intervalId;
4634  };
4635
4636  /**
4637   * Registers a component
4638   *
4639   * @param {String} name Name of the component to register
4640   * @param {Object} comp The component to register
4641   * @static
4642   * @method registerComponent
4643   */
4644
4645  Component.registerComponent = function registerComponent(name, comp) {
4646    if (!Component.components_) {
4647      Component.components_ = {};
4648    }
4649
4650    Component.components_[name] = comp;
4651    return comp;
4652  };
4653
4654  /**
4655   * Gets a component by name
4656   *
4657   * @param {String} name Name of the component to get
4658   * @return {Component}
4659   * @static
4660   * @method getComponent
4661   */
4662
4663  Component.getComponent = function getComponent(name) {
4664    if (Component.components_ && Component.components_[name]) {
4665      return Component.components_[name];
4666    }
4667
4668    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
4669      _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
4670      return _globalWindow2['default'].videojs[name];
4671    }
4672  };
4673
4674  /**
4675   * Sets up the constructor using the supplied init method
4676   * or uses the init of the parent object
4677   *
4678   * @param {Object} props An object of properties
4679   * @static
4680   * @deprecated
4681   * @method extend
4682   */
4683
4684  Component.extend = function extend(props) {
4685    props = props || {};
4686
4687    _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead');
4688
4689    // Set up the constructor using the supplied init method
4690    // or using the init of the parent object
4691    // Make sure to check the unobfuscated version for external libs
4692    var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
4693    // In Resig's simple class inheritance (previously used) the constructor
4694    //  is a function that calls `this.init.apply(arguments)`
4695    // However that would prevent us from using `ParentObject.call(this);`
4696    //  in a Child constructor because the `this` in `this.init`
4697    //  would still refer to the Child and cause an infinite loop.
4698    // We would instead have to do
4699    //    `ParentObject.prototype.init.apply(this, arguments);`
4700    //  Bleh. We're not creating a _super() function, so it's good to keep
4701    //  the parent constructor reference simple.
4702    var subObj = function subObj() {
4703      init.apply(this, arguments);
4704    };
4705
4706    // Inherit from this object's prototype
4707    subObj.prototype = Object.create(this.prototype);
4708    // Reset the constructor property for subObj otherwise
4709    // instances of subObj would have the constructor of the parent Object
4710    subObj.prototype.constructor = subObj;
4711
4712    // Make the class extendable
4713    subObj.extend = Component.extend;
4714
4715    // Extend subObj's prototype with functions and other properties from props
4716    for (var _name in props) {
4717      if (props.hasOwnProperty(_name)) {
4718        subObj.prototype[_name] = props[_name];
4719      }
4720    }
4721
4722    return subObj;
4723  };
4724
4725  return Component;
4726})();
4727
4728Component.registerComponent('Component', Component);
4729exports['default'] = Component;
4730module.exports = exports['default'];
4731
4732},{"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/guid.js":147,"./utils/log.js":148,"./utils/merge-options.js":149,"./utils/to-title-case.js":152,"global/window":2,"object.assign":45}],68:[function(_dereq_,module,exports){
4733/**
4734 * @file audio-track-button.js
4735 */
4736'use strict';
4737
4738exports.__esModule = true;
4739
4740function _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; } }
4741
4742function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4743
4744function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4745
4746function _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; }
4747
4748var _trackButtonJs = _dereq_('../track-button.js');
4749
4750var _trackButtonJs2 = _interopRequireDefault(_trackButtonJs);
4751
4752var _componentJs = _dereq_('../../component.js');
4753
4754var _componentJs2 = _interopRequireDefault(_componentJs);
4755
4756var _utilsFnJs = _dereq_('../../utils/fn.js');
4757
4758var Fn = _interopRequireWildcard(_utilsFnJs);
4759
4760var _audioTrackMenuItemJs = _dereq_('./audio-track-menu-item.js');
4761
4762var _audioTrackMenuItemJs2 = _interopRequireDefault(_audioTrackMenuItemJs);
4763
4764/**
4765 * The base class for buttons that toggle specific text track types (e.g. subtitles)
4766 *
4767 * @param {Player|Object} player
4768 * @param {Object=} options
4769 * @extends TrackButton
4770 * @class AudioTrackButton
4771 */
4772
4773var AudioTrackButton = (function (_TrackButton) {
4774  _inherits(AudioTrackButton, _TrackButton);
4775
4776  function AudioTrackButton(player) {
4777    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
4778
4779    _classCallCheck(this, AudioTrackButton);
4780
4781    options.tracks = player.audioTracks && player.audioTracks();
4782
4783    _TrackButton.call(this, player, options);
4784
4785    this.el_.setAttribute('aria-label', 'Audio Menu');
4786  }
4787
4788  /**
4789   * Allow sub components to stack CSS class names
4790   *
4791   * @return {String} The constructed class name
4792   * @method buildCSSClass
4793   */
4794
4795  AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
4796    return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
4797  };
4798
4799  /**
4800   * Create a menu item for each audio track
4801   *
4802   * @return {Array} Array of menu items
4803   * @method createItems
4804   */
4805
4806  AudioTrackButton.prototype.createItems = function createItems() {
4807    var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
4808
4809    var tracks = this.player_.audioTracks && this.player_.audioTracks();
4810
4811    if (!tracks) {
4812      return items;
4813    }
4814
4815    for (var i = 0; i < tracks.length; i++) {
4816      var track = tracks[i];
4817
4818      items.push(new _audioTrackMenuItemJs2['default'](this.player_, {
4819        // MenuItem is selectable
4820        'selectable': true,
4821        'track': track
4822      }));
4823    }
4824
4825    return items;
4826  };
4827
4828  return AudioTrackButton;
4829})(_trackButtonJs2['default']);
4830
4831_componentJs2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
4832exports['default'] = AudioTrackButton;
4833module.exports = exports['default'];
4834
4835},{"../../component.js":67,"../../utils/fn.js":145,"../track-button.js":98,"./audio-track-menu-item.js":69}],69:[function(_dereq_,module,exports){
4836/**
4837 * @file audio-track-menu-item.js
4838 */
4839'use strict';
4840
4841exports.__esModule = true;
4842
4843function _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; } }
4844
4845function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4846
4847function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4848
4849function _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, { c
4849onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
4850
4851var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
4852
4853var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
4854
4855var _componentJs = _dereq_('../../component.js');
4856
4857var _componentJs2 = _interopRequireDefault(_componentJs);
4858
4859var _utilsFnJs = _dereq_('../../utils/fn.js');
4860
4861var Fn = _interopRequireWildcard(_utilsFnJs);
4862
4863/**
4864 * The audio track menu item
4865 *
4866 * @param {Player|Object} player
4867 * @param {Object=} options
4868 * @extends MenuItem
4869 * @class AudioTrackMenuItem
4870 */
4871
4872var AudioTrackMenuItem = (function (_MenuItem) {
4873  _inherits(AudioTrackMenuItem, _MenuItem);
4874
4875  function AudioTrackMenuItem(player, options) {
4876    var _this = this;
4877
4878    _classCallCheck(this, AudioTrackMenuItem);
4879
4880    var track = options.track;
4881    var tracks = player.audioTracks();
4882
4883    // Modify options for parent MenuItem class's init.
4884    options.label = track.label || track.language || 'Unknown';
4885    options.selected = track.enabled;
4886
4887    _MenuItem.call(this, player, options);
4888
4889    this.track = track;
4890
4891    if (tracks) {
4892      (function () {
4893        var changeHandler = Fn.bind(_this, _this.handleTracksChange);
4894
4895        tracks.addEventListener('change', changeHandler);
4896        _this.on('dispose', function () {
4897          tracks.removeEventListener('change', changeHandler);
4898        });
4899      })();
4900    }
4901  }
4902
4903  /**
4904   * Handle click on audio track
4905   *
4906   * @method handleClick
4907   */
4908
4909  AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
4910    var tracks = this.player_.audioTracks();
4911
4912    _MenuItem.prototype.handleClick.call(this, event);
4913
4914    if (!tracks) return;
4915
4916    for (var i = 0; i < tracks.length; i++) {
4917      var track = tracks[i];
4918
4919      if (track === this.track) {
4920        track.enabled = true;
4921      }
4922    }
4923  };
4924
4925  /**
4926   * Handle audio track change
4927   *
4928   * @method handleTracksChange
4929   */
4930
4931  AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
4932    this.selected(this.track.enabled);
4933  };
4934
4935  return AudioTrackMenuItem;
4936})(_menuMenuItemJs2['default']);
4937
4938_componentJs2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
4939exports['default'] = AudioTrackMenuItem;
4940module.exports = exports['default'];
4941
4942},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145}],70:[function(_dereq_,module,exports){
4943/**
4944 * @file control-bar.js
4945 */
4946'use strict';
4947
4948exports.__esModule = true;
4949
4950function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4951
4952function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4953
4954function _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; }
4955
4956var _componentJs = _dereq_('../component.js');
4957
4958var _componentJs2 = _interopRequireDefault(_componentJs);
4959
4960// Required children
4961
4962var _playToggleJs = _dereq_('./play-toggle.js');
4963
4964var _playToggleJs2 = _interopRequireDefault(_playToggleJs);
4965
4966var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js');
4967
4968var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs);
4969
4970var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js');
4971
4972var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs);
4973
4974var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js');
4975
4976var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs);
4977
4978var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-control
4978s/remaining-time-display.js');
4979
4980var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs);
4981
4982var _liveDisplayJs = _dereq_('./live-display.js');
4983
4984var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs);
4985
4986var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js');
4987
4988var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs);
4989
4990var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js');
4991
4992var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs);
4993
4994var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js');
4995
4996var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs);
4997
4998var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js');
4999
5000var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs);
5001
5002var _muteToggleJs = _dereq_('./mute-toggle.js');
5003
5004var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
5005
5006var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js');
5007
5008var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChaptersButtonJs);
5009
5010var _textTrackControlsDescriptionsButtonJs = _dereq_('./text-track-controls/descriptions-button.js');
5011
5012var _textTrackControlsDescriptionsButtonJs2 = _interopRequireDefault(_textTrackControlsDescriptionsButtonJs);
5013
5014var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js');
5015
5016var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs);
5017
5018var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js');
5019
5020var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs);
5021
5022var _audioTrackControlsAudioTrackButtonJs = _dereq_('./audio-track-controls/audio-track-button.js');
5023
5024var _audioTrackControlsAudioTrackButtonJs2 = _interopRequireDefault(_audioTrackControlsAudioTrackButtonJs);
5025
5026var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js');
5027
5028var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs);
5029
5030var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js');
5031
5032var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs);
5033
5034/**
5035 * Container of main controls
5036 *
5037 * @extends Component
5038 * @class ControlBar
5039 */
5040
5041var ControlBar = (function (_Component) {
5042  _inherits(ControlBar, _Component);
5043
5044  function ControlBar() {
5045    _classCallCheck(this, ControlBar);
5046
5047    _Component.apply(this, arguments);
5048  }
5049
5050  /**
5051   * Create the component's DOM element
5052   *
5053   * @return {Element}
5054   * @method createEl
5055   */
5056
5057  ControlBar.prototype.createEl = function createEl() {
5058    return _Component.prototype.createEl.call(this, 'div', {
5059      className: 'vjs-control-bar',
5060      dir: 'ltr'
5061    }, {
5062      'role': 'group' // The control bar is a group, so it can contain menuitems
5063    });
5064  };
5065
5066  return ControlBar;
5067})(_componentJs2['default']);
5068
5069ControlBar.prototype.options_ = {
5070  loadEvent: 'play',
5071  children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
5072};
5073
5074_componentJs2['default'].registerComponent('ControlBar', ControlBar);
5075exports['default'] = ControlBar;
5076module.exports = exports['default'];
5077
5078},{"../component.js":67,"./audio-track-controls/audio-track-button.js":68,"./fullscreen-toggle.js":71,"./live-display.js":72,"./mute-toggle.js":73,"./play-toggle.js":74,"./playback-rate-menu/playback-rate-menu-button.js":75,"./progress-control/progress-control.js":80,"./spacer-controls/custom-control-spacer.js":83,"./text-track-controls/captions-button.js":86,"./text-track-controls/chapters-button.js":87,"./text-track-controls/descriptions-button.js":89,"./text-track-controls/subtitles-button.js":91,"./time-control
5078s/current-time-display.js":94,"./time-controls/duration-display.js":95,"./time-controls/remaining-time-display.js":96,"./time-controls/time-divider.js":97,"./volume-control/volume-control.js":100,"./volume-menu-button.js":102}],71:[function(_dereq_,module,exports){
5079/**
5080 * @file fullscreen-toggle.js
5081 */
5082'use strict';
5083
5084exports.__esModule = true;
5085
5086function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5087
5088function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5089
5090function _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; }
5091
5092var _buttonJs = _dereq_('../button.js');
5093
5094var _buttonJs2 = _interopRequireDefault(_buttonJs);
5095
5096var _componentJs = _dereq_('../component.js');
5097
5098var _componentJs2 = _interopRequireDefault(_componentJs);
5099
5100/**
5101 * Toggle fullscreen video
5102 *
5103 * @extends Button
5104 * @class FullscreenToggle
5105 */
5106
5107var FullscreenToggle = (function (_Button) {
5108  _inherits(FullscreenToggle, _Button);
5109
5110  function FullscreenToggle() {
5111    _classCallCheck(this, FullscreenToggle);
5112
5113    _Button.apply(this, arguments);
5114  }
5115
5116  /**
5117   * Allow sub components to stack CSS class names
5118   *
5119   * @return {String} The constructed class name
5120   * @method buildCSSClass
5121   */
5122
5123  FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
5124    return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
5125  };
5126
5127  /**
5128   * Handles click for full screen
5129   *
5130   * @method handleClick
5131   */
5132
5133  FullscreenToggle.prototype.handleClick = function handleClick() {
5134    if (!this.player_.isFullscreen()) {
5135      this.player_.requestFullscreen();
5136      this.controlText('Non-Fullscreen');
5137    } else {
5138      this.player_.exitFullscreen();
5139      this.controlText('Fullscreen');
5140    }
5141  };
5142
5143  return FullscreenToggle;
5144})(_buttonJs2['default']);
5145
5146FullscreenToggle.prototype.controlText_ = 'Fullscreen';
5147
5148_componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
5149exports['default'] = FullscreenToggle;
5150module.exports = exports['default'];
5151
5152},{"../button.js":64,"../component.js":67}],72:[function(_dereq_,module,exports){
5153/**
5154 * @file live-display.js
5155 */
5156'use strict';
5157
5158exports.__esModule = true;
5159
5160function _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; } }
5161
5162function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5163
5164function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5165
5166function _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; }
5167
5168var _component = _dereq_('../component');
5169
5170var _component2 = _interopRequireDefault(_component);
5171
5172var _utilsDomJs = _dereq_('../utils/dom.js');
5173
5174var Dom = _interopRequireWildcard(_utilsDomJs);
5175
5176/**
5177 * Displays the live indicator
5178 * TODO - Future make it click to snap to live
5179 *
5180 * @extends Component
5181 * @class LiveDisplay
5182 */
5183
5184var LiveDisplay = (function (_Component) {
5185  _inherits(LiveDisplay, _Component);
5186
5187  function LiveDisplay(player, options) {
5188    _classCallCheck(this, LiveDisplay);
5189
5190    _Component.call(this, player, options);
5191
5192    this.updateShowing();
5193    this.on(this.player(), 'durationchange', this.updateShowing);
5194  }
5195
5196  /**
5197   * Create the component's DOM element
5198   *
5199   * @return {Element}
5200   * @method createEl
5201   */
5202
5203  LiveDisplay.prototype.createEl = function createEl() {
5204    var el = _Component.prototype.createEl.call(this, 'div', {
5205      className: 'vjs-live-control vjs-control'
5206    });
5207
5208    this.contentEl_ = Dom.createEl('div', {
5209      className: 'vjs-live-display',
5210      innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
5211    }, {
5212      'aria-live': 'off'
5213    });
5214
5215    el.appendChild(this.contentEl_);
5216    return el;
5217  };
5218
5219  LiveDisplay.prototype.updateShowing = function updateShowing() {
5220    if (this.player().duration() === Infinity) {
5221      this.show();
5222    } else {
5223      this.hide();
5224    }
5225  };
5226
5227  return LiveDisplay;
5228})(_component2['default']);
5229
5230_component2['default'].registerComponent('LiveDisplay', LiveDisplay);
5231exports['default'] = LiveDisplay;
5232module.exports = exports['default'];
5233
5234},{"../component":67,"../utils/dom.js":143}],73:[function(_dereq_,module,exports){
5235/**
5236 * @file mute-toggle.js
5237 */
5238'use strict';
5239
5240exports.__esModule = true;
5241
5242function _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; } }
5243
5244function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5245
5246function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5247
5248function _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; }
5249
5250var _button = _dereq_('../button');
5251
5252var _button2 = _interopRequireDefault(_button);
5253
5254var _component = _dereq_('../component');
5255
5256var _component2 = _interopRequireDefault(_component);
5257
5258var _utilsDomJs = _dereq_('../utils/dom.js');
5259
5260var Dom = _interopRequireWildcard(_utilsDomJs);
5261
5262/**
5263 * A button component for muting the audio
5264 *
5265 * @param {Player|Object} player
5266 * @param {Object=} options
5267 * @extends Button
5268 * @class MuteToggle
5269 */
5270
5271var MuteToggle = (function (_Button) {
5272  _inherits(MuteToggle, _Button);
5273
5274  function MuteToggle(player, options) {
5275    _classCallCheck(this, MuteToggle);
5276
5277    _Button.call(this, player, options);
5278
5279    this.on(player, 'volumechange', this.update);
5280
5281    // hide mute toggle if the current tech doesn't support volume control
5282    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
5283      this.addClass('vjs-hidden');
5284    }
5285
5286    this.on(player, 'loadstart', function () {
5287      this.update(); // We need to update the button to account for a default muted state.
5288
5289      if (player.tech_['featuresVolumeControl'] === false) {
5290        this.addClass('vjs-hidden');
5291      } else {
5292        this.removeClass('vjs-hidden');
5293      }
5294    });
5295  }
5296
5297  /**
5298   * Allow sub components to stack CSS class names
5299   *
5300   * @return {String} The constructed class name
5301   * @method buildCSSClass
5302   */
5303
5304  MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
5305    return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
5306  };
5307
5308  /**
5309   * Handle click on mute
5310   *
5311   * @method handleClick
5312   */
5313
5314  MuteToggle.prototype.handleClick = function handleClick() {
5315    this.player_.muted(this.player_.muted() ? false : true);
5316  };
5317
5318  /**
5319   * Update volume
5320   *
5321   * @method update
5322   */
5323
5324  MuteToggle.prototype.update = function update() {
5325    var vol = this.player_.volume(),
5326        level = 3;
5327
5328    if (vol === 0 || this.player_.muted()) {
5329      level = 0;
5330    } else if (vol < 0.33) {
5331      level = 1;
5332    } else if (vol < 0.67) {
5333      level = 2;
5334    }
5335
5336    // Don't rewrite the button text if the actual text doesn't change.
5337    // This causes unnecessary and confusing information for screen reader users.
5338    // This check is needed because this function gets called every time the volume level is changed.
5339    var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
5340    if (this.controlText() !== toMute) {
5341      this.controlText(toMute);
5342    }
5343
5344    /* TODO improve muted icon classes */
5345    for (var i = 0; i < 4; i++) {
5346      Dom.removeElClass(this.el_, 'vjs-vol-' + i);
5347    }
5348    Dom.addElClass(this.el_, 'vjs-vol-' + level);
5349  };
5350
5351  return MuteToggle;
5352})(_button2['default']);
5353
5354MuteToggle.prototype.controlText_ = 'Mute';
5355
5356_component2['default'].registerComponent('MuteToggle', MuteToggle);
5357exports['default'] = MuteToggle;
5358module.exports = exports['default'];
5359
5360},{"../button":64,"../component":67,"../utils/dom.js":143}],74:[function(_dereq_,module,exports){
5361/**
5362 * @file play-toggle.js
5363 */
5364'use strict';
5365
5366exports.__esModule = true;
5367
5368function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5369
5370function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5371
5372function _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, { c
5372onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
5373
5374var _buttonJs = _dereq_('../button.js');
5375
5376var _buttonJs2 = _interopRequireDefault(_buttonJs);
5377
5378var _componentJs = _dereq_('../component.js');
5379
5380var _componentJs2 = _interopRequireDefault(_componentJs);
5381
5382/**
5383 * Button to toggle between play and pause
5384 *
5385 * @param {Player|Object} player
5386 * @param {Object=} options
5387 * @extends Button
5388 * @class PlayToggle
5389 */
5390
5391var PlayToggle = (function (_Button) {
5392  _inherits(PlayToggle, _Button);
5393
5394  function PlayToggle(player, options) {
5395    _classCallCheck(this, PlayToggle);
5396
5397    _Button.call(this, player, options);
5398
5399    this.on(player, 'play', this.handlePlay);
5400    this.on(player, 'pause', this.handlePause);
5401  }
5402
5403  /**
5404   * Allow sub components to stack CSS class names
5405   *
5406   * @return {String} The constructed class name
5407   * @method buildCSSClass
5408   */
5409
5410  PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
5411    return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
5412  };
5413
5414  /**
5415   * Handle click to toggle between play and pause
5416   *
5417   * @method handleClick
5418   */
5419
5420  PlayToggle.prototype.handleClick = function handleClick() {
5421    if (this.player_.paused()) {
5422      this.player_.play();
5423    } else {
5424      this.player_.pause();
5425    }
5426  };
5427
5428  /**
5429   * Add the vjs-playing class to the element so it can change appearance
5430   *
5431   * @method handlePlay
5432   */
5433
5434  PlayToggle.prototype.handlePlay = function handlePlay() {
5435    this.removeClass('vjs-paused');
5436    this.addClass('vjs-playing');
5437    this.controlText('Pause'); // change the button text to "Pause"
5438  };
5439
5440  /**
5441   * Add the vjs-paused class to the element so it can change appearance
5442   *
5443   * @method handlePause
5444   */
5445
5446  PlayToggle.prototype.handlePause = function handlePause() {
5447    this.removeClass('vjs-playing');
5448    this.addClass('vjs-paused');
5449    this.controlText('Play'); // change the button text to "Play"
5450  };
5451
5452  return PlayToggle;
5453})(_buttonJs2['default']);
5454
5455PlayToggle.prototype.controlText_ = 'Play';
5456
5457_componentJs2['default'].registerComponent('PlayToggle', PlayToggle);
5458exports['default'] = PlayToggle;
5459module.exports = exports['default'];
5460
5461},{"../button.js":64,"../component.js":67}],75:[function(_dereq_,module,exports){
5462/**
5463 * @file playback-rate-menu-button.js
5464 */
5465'use strict';
5466
5467exports.__esModule = true;
5468
5469function _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; } }
5470
5471function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5472
5473function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5474
5475function _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; }
5476
5477var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');
5478
5479var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
5480
5481var _menuMenuJs = _dereq_('../../menu/menu.js');
5482
5483var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
5484
5485var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js');
5486
5487var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs);
5488
5489var _componentJs = _dereq_('../../component.js');
5490
5491var _componentJs2 = _interopRequireDefault(_componentJs);
5492
5493var _utilsDomJs = _dereq_('../../utils/dom.js');
5494
5495var Dom = _interopRequireWildcard(_utilsDomJs);
5496
5497/**
5498 * The component for controlling the playback rate
5499 *
5500 * @param {Player|Object} player
5501 * @param {Object=} options
5502 * @extends MenuButton
5503 * @class PlaybackRateMenuButton
5504 */
5505
5506var PlaybackRateMenuButton = (function (_MenuButton) {
5507  _inherits(PlaybackRateMenuButton, _MenuButton);
5508
5509  function PlaybackRateMenuButton(player, options) {
5510    _classCallCheck(this, PlaybackRateMenuButton);
5511
5512    _MenuButton.call(this, player, options);
5513
5514    this.updateVisibility();
5515    this.updateLabel();
5516
5517    this.on(player, 'loadstart', this.updateVisibility);
5518    this.on(player, 'ratechange', this.updateLabel);
5519  }
5520
5521  /**
5522   * Create the component's DOM element
5523   *
5524   * @return {Element}
5525   * @method createEl
5526   */
5527
5528  PlaybackRateMenuButton.prototype.createEl = function createEl() {
5529    var el = _MenuButton.prototype.createEl.call(this);
5530
5531    this.labelEl_ = Dom.createEl('div', {
5532      className: 'vjs-playback-rate-value',
5533      innerHTML: 1.0
5534    });
5535
5536    el.appendChild(this.labelEl_);
5537
5538    return el;
5539  };
5540
5541  /**
5542   * Allow sub components to stack CSS class names
5543   *
5544   * @return {String} The constructed class name
5545   * @method buildCSSClass
5546   */
5547
5548  PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
5549    return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
5550  };
5551
5552  /**
5553   * Create the playback rate menu
5554   *
5555   * @return {Menu} Menu object populated with items
5556   * @method createMenu
5557   */
5558
5559  PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
5560    var menu = new _menuMenuJs2['default'](this.player());
5561    var rates = this.playbackRates();
5562
5563    if (rates) {
5564      for (var i = rates.length - 1; i >= 0; i--) {
5565        menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' }));
5566      }
5567    }
5568
5569    return menu;
5570  };
5571
5572  /**
5573   * Updates ARIA accessibility attributes
5574   *
5575   * @method updateARIAAttributes
5576   */
5577
5578  PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
5579    // Current playback rate
5580    this.el().setAttribute('aria-valuenow', this.player().playbackRate());
5581  };
5582
5583  /**
5584   * Handle menu item click
5585   *
5586   * @method handleClick
5587   */
5588
5589  PlaybackRateMenuButton.prototype.handleClick = function handleClick() {
5590    // select next rate option
5591    var currentRate = this.player().playbackRate();
5592    var rates = this.playbackRates();
5593
5594    // this will select first one if the last one currently selected
5595    var newRate = rates[0];
5596    for (var i = 0; i < rates.length; i++) {
5597      if (rates[i] > currentRate) {
5598        newRate = rates[i];
5599        break;
5600      }
5601    }
5602    this.player().playbackRate(newRate);
5603  };
5604
5605  /**
5606   * Get possible playback rates
5607   *
5608   * @return {Array} Possible playback rates
5609   * @method playbackRates
5610   */
5611
5612  PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
5613    return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates'];
5614  };
5615
5616  /**
5617   * Get whether playback rates is supported by the tech
5618   * and an array of playback rates exists
5619   *
5620   * @return {Boolean} Whether changing playback rate is supported
5621   * @method playbackRateSupported
5622   */
5623
5624  PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
5625    return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0;
5626  };
5627
5628  /**
5629   * Hide playback rate controls when they're no playback rate options to select
5630   *
5631   * @method updateVisibility
5632   */
5633
5634  PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() {
5635    if (this.playbackRateSupported()) {
5636      this.removeClass('vjs-hidden');
5637    } else {
5638      this.addClass('vjs-hidden');
5639    }
5640  };
5641
5642  /**
5643   * Update button label when rate changed
5644   *
5645   * @method updateLabel
5646   */
5647
5648  PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() {
5649    if (this.playbackRateSupported()) {
5650      this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
5651    }
5652  };
5653
5654  return PlaybackRateMenuButton;
5655}
5655)(_menuMenuButtonJs2['default']);
5656
5657PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
5658
5659_componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
5660exports['default'] = PlaybackRateMenuButton;
5661module.exports = exports['default'];
5662
5663},{"../../component.js":67,"../../menu/menu-button.js":109,"../../menu/menu.js":111,"../../utils/dom.js":143,"./playback-rate-menu-item.js":76}],76:[function(_dereq_,module,exports){
5664/**
5665 * @file playback-rate-menu-item.js
5666 */
5667'use strict';
5668
5669exports.__esModule = true;
5670
5671function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5672
5673function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5674
5675function _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; }
5676
5677var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
5678
5679var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
5680
5681var _componentJs = _dereq_('../../component.js');
5682
5683var _componentJs2 = _interopRequireDefault(_componentJs);
5684
5685/**
5686 * The specific menu item type for selecting a playback rate
5687 *
5688 * @param {Player|Object} player
5689 * @param {Object=} options
5690 * @extends MenuItem
5691 * @class PlaybackRateMenuItem
5692 */
5693
5694var PlaybackRateMenuItem = (function (_MenuItem) {
5695  _inherits(PlaybackRateMenuItem, _MenuItem);
5696
5697  function PlaybackRateMenuItem(player, options) {
5698    _classCallCheck(this, PlaybackRateMenuItem);
5699
5700    var label = options['rate'];
5701    var rate = parseFloat(label, 10);
5702
5703    // Modify options for parent MenuItem class's init.
5704    options['label'] = label;
5705    options['selected'] = rate === 1;
5706    _MenuItem.call(this, player, options);
5707
5708    this.label = label;
5709    this.rate = rate;
5710
5711    this.on(player, 'ratechange', this.update);
5712  }
5713
5714  /**
5715   * Handle click on menu item
5716   *
5717   * @method handleClick
5718   */
5719
5720  PlaybackRateMenuItem.prototype.handleClick = function handleClick() {
5721    _MenuItem.prototype.handleClick.call(this);
5722    this.player().playbackRate(this.rate);
5723  };
5724
5725  /**
5726   * Update playback rate with selected rate
5727   *
5728   * @method update
5729   */
5730
5731  PlaybackRateMenuItem.prototype.update = function update() {
5732    this.selected(this.player().playbackRate() === this.rate);
5733  };
5734
5735  return PlaybackRateMenuItem;
5736})(_menuMenuItemJs2['default']);
5737
5738PlaybackRateMenuItem.prototype.contentElType = 'button';
5739
5740_componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
5741exports['default'] = PlaybackRateMenuItem;
5742module.exports = exports['default'];
5743
5744},{"../../component.js":67,"../../menu/menu-item.js":110}],77:[function(_dereq_,module,exports){
5745/**
5746 * @file load-progress-bar.js
5747 */
5748'use strict';
5749
5750exports.__esModule = true;
5751
5752function _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; } }
5753
5754function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5755
5756function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5757
5758function _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; }
5759
5760var _componentJs = _dereq_('../../component.js');
5761
5762var _componentJs2 = _interopRequireDefault(_componentJs);
5763
5764var _utilsDomJs = _dereq_('../../utils/dom.js');
5765
5766var Dom = _interopRequireWildcard(_utilsDomJs);
5767
5768/**
5769 * Shows load progress
5770 *
5771 * @param {Player|Object} player
5772 * @param {Object=} options
5773 * @extends Component
5774 * @class LoadProgressBar
5775 */
5776
5777var LoadProgressBar = (function (_Component) {
5778  _inherits(LoadProgressBar, _Component);
5779
5780  function LoadProgressBar(player, options) {
5781    _classCallCheck(this, LoadProgressBar);
5782
5783    _Component.call(this, player, options);
5784    this.on(player, 'progress', this.update);
5785  }
5786
5787  /**
5788   * Create the component's DOM element
5789   *
5790   * @return {Element}
5791   * @method createEl
5792   */
5793
5794  LoadProgressBar.prototype.createEl = function createEl() {
5795    return _Component.prototype.createEl.call(this, 'div', {
5796      className: 'vjs-load-progress',
5797      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
5798    });
5799  };
5800
5801  /**
5802   * Update progress bar
5803   *
5804   * @method update
5805   */
5806
5807  LoadProgressBar.prototype.update = function update() {
5808    var buffered = this.player_.buffered();
5809    var duration = this.player_.duration();
5810    var bufferedEnd = this.player_.bufferedEnd();
5811    var children = this.el_.children;
5812
5813    // get the percent width of a time compared to the total end
5814    var percentify = function percentify(time, end) {
5815      var percent = time / end || 0; // no NaN
5816      return (percent >= 1 ? 1 : percent) * 100 + '%';
5817    };
5818
5819    // update the width of the progress bar
5820    this.el_.style.width = percentify(bufferedEnd, duration);
5821
5822    // add child elements to represent the individual buffered time ranges
5823    for (var i = 0; i < buffered.length; i++) {
5824      var start = buffered.start(i);
5825      var end = buffered.end(i);
5826      var part = children[i];
5827
5828      if (!part) {
5829        part = this.el_.appendChild(Dom.createEl());
5830      }
5831
5832      // set the percent based on the width of the progress bar (bufferedEnd)
5833      part.style.left = percentify(start, bufferedEnd);
5834      part.style.width = percentify(end - start, bufferedEnd);
5835    }
5836
5837    // remove unused buffered range elements
5838    for (var i = children.length; i > buffered.length; i--) {
5839      this.el_.removeChild(children[i - 1]);
5840    }
5841  };
5842
5843  return LoadProgressBar;
5844})(_componentJs2['default']);
5845
5846_componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
5847exports['default'] = LoadProgressBar;
5848module.exports = exports['default'];
5849
5850},{"../../component.js":67,"../../utils/dom.js":143}],78:[function(_dereq_,module,exports){
5851/**
5852 * @file mouse-time-display.js
5853 */
5854'use strict';
5855
5856exports.__esModule = true;
5857
5858function _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; } }
5859
5860function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5861
5862function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5863
5864function _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; }
5865
5866var _globalWindow = _dereq_('global/window');
5867
5868var _globalWindow2 = _interopRequireDefault(_globalWindow);
5869
5870var _componentJs = _dereq_('../../component.js');
5871
5872var _componentJs2 = _interopRequireDefault(_componentJs);
5873
5874var _utilsDomJs = _dereq_('../../utils/dom.js');
5875
5876var Dom = _interopRequireWildcard(_utilsDomJs);
5877
5878var _utilsFnJs = _dereq_('../../utils/fn.js');
5879
5880var Fn = _interopRequireWildcard(_utilsFnJs);
5881
5882var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
5883
5884var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
5885
5886var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle');
5887
5888var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle);
5889
5890/**
5891 * The Mouse Time Display component shows the time you will seek to
5892 * when hovering over the progress bar
5893 *
5894 * @param {Player|Object} player
5895 * @param {Object=} options
5896 * @extends Component
5897 * @class MouseTimeDisplay
5898 */
5899
5900var MouseTimeDisplay = (function (_Component) {
5901  _inherits(MouseTimeDisplay, _Component);
5902
5903  function MouseTimeDisplay(player, options) {
5904    var _this = this;
5905
5906    _classCallCheck(this, MouseTimeDisplay);
5907
5908    _Component.call(this, player, options);
5909
5910    if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
5911      this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
5912    }
5913
5914    if (this.keepTooltipsInside) {
5915      this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
5916      this.el().appendChild(this.tooltip);
5917      this.addClass('vjs-keep-tooltips-inside');
5918    }
5919
5920    this.update(0, 0);
5921
5922    player.on('ready', function () {
5923      _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25));
5924    });
5925  }
5926
5927  /**
5928   * Create the component's DOM element
5929   *
5930   * @return {Element}
5931   * @method createEl
5932   */
5933
5934  MouseTimeDisplay.prototype.createEl = function createEl() {
5935    return _Component.prototype.createEl.call(this, 'div', {
5936      className: 'vjs-mouse-display'
5937    });
5938  };
5939
5940  MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
5941    var duration = this.player_.duration();
5942    var newTime = this.calculateDistance(event) * duration;
5943    var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
5944
5945    this.update(newTime, position);
5946  };
5947
5948  MouseTimeDisplay.prototype.update = function update(newTime, position) {
5949    var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration());
5950
5951    this.el().style.left = position + 'px';
5952    this.el().setAttribute('data-current-time', time);
5953
5954    if (this.keepTooltipsInside) {
5955      var clampedPosition = this.clampPosition_(position);
5956      var difference = position - clampedPosition + 1;
5957      var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width);
5958      var tooltipWidthHalf = tooltipWidth / 2;
5959
5960      this.tooltip.innerHTML = time;
5961      this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
5962    }
5963  };
5964
5965  MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
5966    return Dom.getPointerPosition(this.el().parentNode, event).x;
5967  };
5968
5969  /**
5970   * This takes in a horizontal position for the bar and returns a clamped position.
5971   * Clamped position means that it will keep the position greater than half the width
5972   * of the tooltip and smaller than the player width minus half the width o the tooltip.
5973   * It will only clamp the position if `keepTooltipsInside` option is set.
5974   *
5975   * @param {Number} position the position the bar wants to be
5976   * @return {Number} newPosition the (potentially) clamped position
5977   * @method clampPosition_
5978   */
5979
5980  MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
5981    if (!this.keepTooltipsInside) {
5982      return position;
5983    }
5984
5985    var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width);
5986    var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width);
5987    var tooltipWidthHalf = tooltipWidth / 2;
5988    var actualPosition = position;
5989
5990    if (position < tooltipWidthHalf) {
5991      actualPosition = Math.ceil(tooltipWidthHalf);
5992    } else if (position > playerWidth - tooltipWidthHalf) {
5993      actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
5994    }
5995
5996    return actualPosition;
5997  };
5998
5999  return MouseTimeDisplay;
6000})(_componentJs2['default']);
6001
6002_componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
6003exports['default'] = MouseTimeDisplay;
6004module.exports = exports['default'];
6005
6006},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146,"global/window":2,"lodash-compat/function/throttle":7}],79:[function(_dereq_,module,exports){
6007/**
6008 * @file play-progress-bar.js
6009 */
6010'use strict';
6011
6012exports.__esModule = true;
6013
6014function _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; } }
6015
6016function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6017
6018function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6019
6020function _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, { c
6020onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6021
6022var _componentJs = _dereq_('../../component.js');
6023
6024var _componentJs2 = _interopRequireDefault(_componentJs);
6025
6026var _utilsFnJs = _dereq_('../../utils/fn.js');
6027
6028var Fn = _interopRequireWildcard(_utilsFnJs);
6029
6030var _utilsDomJs = _dereq_('../../utils/dom.js');
6031
6032var Dom = _interopRequireWildcard(_utilsDomJs);
6033
6034var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
6035
6036var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
6037
6038/**
6039 * Shows play progress
6040 *
6041 * @param {Player|Object} player
6042 * @param {Object=} options
6043 * @extends Component
6044 * @class PlayProgressBar
6045 */
6046
6047var PlayProgressBar = (function (_Component) {
6048  _inherits(PlayProgressBar, _Component);
6049
6050  function PlayProgressBar(player, options) {
6051    _classCallCheck(this, PlayProgressBar);
6052
6053    _Component.call(this, player, options);
6054    this.updateDataAttr();
6055    this.on(player, 'timeupdate', this.updateDataAttr);
6056    player.ready(Fn.bind(this, this.updateDataAttr));
6057
6058    if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
6059      this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
6060    }
6061
6062    if (this.keepTooltipsInside) {
6063      this.addClass('vjs-keep-tooltips-inside');
6064    }
6065  }
6066
6067  /**
6068   * Create the component's DOM element
6069   *
6070   * @return {Element}
6071   * @method createEl
6072   */
6073
6074  PlayProgressBar.prototype.createEl = function createEl() {
6075    return _Component.prototype.createEl.call(this, 'div', {
6076      className: 'vjs-play-progress vjs-slider-bar',
6077      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
6078    });
6079  };
6080
6081  PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() {
6082    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
6083    this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration()));
6084  };
6085
6086  return PlayProgressBar;
6087})(_componentJs2['default']);
6088
6089_componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
6090exports['default'] = PlayProgressBar;
6091module.exports = exports['default'];
6092
6093},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146}],80:[function(_dereq_,module,exports){
6094/**
6095 * @file progress-control.js
6096 */
6097'use strict';
6098
6099exports.__esModule = true;
6100
6101function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6102
6103function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6104
6105function _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; }
6106
6107var _componentJs = _dereq_('../../component.js');
6108
6109var _componentJs2 = _interopRequireDefault(_componentJs);
6110
6111var _seekBarJs = _dereq_('./seek-bar.js');
6112
6113var _seekBarJs2 = _interopRequireDefault(_seekBarJs);
6114
6115var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js');
6116
6117var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs);
6118
6119/**
6120 * The Progress Control component contains the seek bar, load progress,
6121 * and play progress
6122 *
6123 * @param {Player|Object} player
6124 * @param {Object=} options
6125 * @extends Component
6126 * @class ProgressControl
6127 */
6128
6129var ProgressControl = (function (_Component) {
6130  _inherits(ProgressControl, _Component);
6131
6132  function ProgressControl() {
6133    _classCallCheck(this, ProgressControl);
6134
6135    _Component.apply(this, arguments);
6136  }
6137
6138  /**
6139   * Create the component's DOM element
6140   *
6141   * @return {Element}
6142   * @method createEl
6143   */
6144
6145  ProgressControl.prototype.createEl = function createEl() {
6146    return _Component.prototype.createEl.call(this, 'div', {
6147      className: 'vjs-progress-control vjs-control'
6148    });
6149  };
6150
6151  return ProgressControl;
6152})(_componentJs2['default']);
6153
6154ProgressControl.prototype.options_ = {
6155  children: ['seekBar']
6156};
6157
6158_componentJs2['default'].registerComponent('ProgressControl', ProgressControl);
6159exports['default'] = ProgressControl;
6160module.exports = exports['default'];
6161
6162},{"../../component.js":67,"./mouse-time-display.js":78,"./seek-bar.js":81}],81:[function(_dereq_,module,exports){
6163/**
6164 * @file seek-bar.js
6165 */
6166'use strict';
6167
6168exports.__esModule = true;
6169
6170function _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; } }
6171
6172function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6173
6174function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6175
6176function _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, { c
6176onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6177
6178var _globalWindow = _dereq_('global/window');
6179
6180var _globalWindow2 = _interopRequireDefault(_globalWindow);
6181
6182var _sliderSliderJs = _dereq_('../../slider/slider.js');
6183
6184var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
6185
6186var _componentJs = _dereq_('../../component.js');
6187
6188var _componentJs2 = _interopRequireDefault(_componentJs);
6189
6190var _loadProgressBarJs = _dereq_('./load-progress-bar.js');
6191
6192var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs);
6193
6194var _playProgressBarJs = _dereq_('./play-progress-bar.js');
6195
6196var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs);
6197
6198var _tooltipProgressBarJs = _dereq_('./tooltip-progress-bar.js');
6199
6200var _tooltipProgressBarJs2 = _interopRequireDefault(_tooltipProgressBarJs);
6201
6202var _utilsFnJs = _dereq_('../../utils/fn.js');
6203
6204var Fn = _interopRequireWildcard(_utilsFnJs);
6205
6206var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
6207
6208var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
6209
6210var _objectAssign = _dereq_('object.assign');
6211
6212var _objectAssign2 = _interopRequireDefault(_objectAssign);
6213
6214/**
6215 * Seek Bar and holder for the progress bars
6216 *
6217 * @param {Player|Object} player
6218 * @param {Object=} options
6219 * @extends Slider
6220 * @class SeekBar
6221 */
6222
6223var SeekBar = (function (_Slider) {
6224  _inherits(SeekBar, _Slider);
6225
6226  function SeekBar(player, options) {
6227    _classCallCheck(this, SeekBar);
6228
6229    _Slider.call(this, player, options);
6230    this.on(player, 'timeupdate', this.updateProgress);
6231    this.on(player, 'ended', this.updateProgress);
6232    player.ready(Fn.bind(this, this.updateProgress));
6233
6234    if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
6235      this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
6236    }
6237
6238    if (this.keepTooltipsInside) {
6239      this.tooltipProgressBar = this.addChild('TooltipProgressBar');
6240    }
6241  }
6242
6243  /**
6244   * Create the component's DOM element
6245   *
6246   * @return {Element}
6247   * @method createEl
6248   */
6249
6250  SeekBar.prototype.createEl = function createEl() {
6251    return _Slider.prototype.createEl.call(this, 'div', {
6252      className: 'vjs-progress-holder'
6253    }, {
6254      'aria-label': 'progress bar'
6255    });
6256  };
6257
6258  /**
6259   * Update ARIA accessibility attributes
6260   *
6261   * @method updateARIAAttributes
6262   */
6263
6264  SeekBar.prototype.updateProgress = function updateProgress() {
6265    this.updateAriaAttributes(this.el_);
6266
6267    if (this.keepTooltipsInside) {
6268      this.updateAriaAttributes(this.tooltipProgressBar.el_);
6269      this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
6270
6271      var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width);
6272      var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltipProgressBar.tooltip).width);
6273      var tooltipStyle = this.tooltipProgressBar.el().style;
6274      tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
6275      tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
6276      tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
6277    }
6278  };
6279
6280  SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
6281    // Allows for smooth scrubbing, when player can't keep up.
6282    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
6283    el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete)
6284    el.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete)
6285  };
6286
6287  /**
6288   * Get percentage of video played
6289   *
6290   * @return {Number} Percentage played
6291   * @method getPercent
6292   */
6293
6294  SeekBar.prototype.getPercent = function getPercent() {
6295    var percent = this.player_.currentTime() / this.player_.duration();
6296    return percent >= 1 ? 1 : percent;
6297  };
6298
6299  /**
6300   * Handle mouse down on seek bar
6301   *
6302   * @method handleMouseDown
6303   */
6304
6305  SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
6306    _Slider.prototype.handleMouseDown.call(this, event);
6307
6308    this.player_.scrubbing(true);
6309
6310    this.videoWasPlaying = !this.player_.paused();
6311    this.player_.pause();
6312  };
6313
6314  /**
6315   * Handle mouse move on seek bar
6316   *
6317   * @method handleMouseMove
6318   */
6319
6320  SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
6321    var newTime = this.calculateDistance(event) * this.player_.duration();
6322
6323    // Don't let video end while scrubbing.
6324    if (newTime === this.player_.duration()) {
6325      newTime = newTime - 0.1;
6326    }
6327
6328    // Set new time (tell player to seek to new time)
6329    this.player_.currentTime(newTime);
6330  };
6331
6332  /**
6333   * Handle mouse up on seek bar
6334   *
6335   * @method handleMouseUp
6336   */
6337
6338  SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
6339    _Slider.prototype.handleMouseUp.call(this, event);
6340
6341    this.player_.scrubbing(false);
6342    if (this.videoWasPlaying) {
6343      this.player_.play();
6344    }
6345  };
6346
6347  /**
6348   * Move more quickly fast forward for keyboard-only users
6349   *
6350   * @method stepForward
6351   */
6352
6353  SeekBar.prototype.stepForward = function stepForward() {
6354    this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
6355  };
6356
6357  /**
6358   * Move more quickly rewind for keyboard-only users
6359   *
6360   * @method stepBack
6361   */
6362
6363  SeekBar.prototype.stepBack = function stepBack() {
6364    this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
6365  };
6366
6367  return SeekBar;
6368})(_sliderSliderJs2['default']);
6369
6370SeekBar.prototype.options_ = {
6371  children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
6372  'barName': 'playProgressBar'
6373};
6374
6375SeekBar.prototype.playerEvent = 'timeupdate';
6376
6377_componentJs2['default'].registerComponent('SeekBar', SeekBar);
6378exports['default'] = SeekBar;
6379module.exports = exports['default'];
6380
6381},{"../../component.js":67,"../../slider/slider.js":119,"../../utils/fn.js":145,"../../utils/format-time.js":146,"./load-progress-bar.js":77,"./play-progress-bar.js":79,"./tooltip-progress-bar.js":82,"global/window":2,"object.assign":45}],82:[function(_dereq_,module,exports){
6382/**
6383 * @file play-progress-bar.js
6384 */
6385'use strict';
6386
6387exports.__esModule = true;
6388
6389function _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; } }
6390
6391function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6392
6393function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6394
6395function _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, { c
6395onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6396
6397var _componentJs = _dereq_('../../component.js');
6398
6399var _componentJs2 = _interopRequireDefault(_componentJs);
6400
6401var _utilsFnJs = _dereq_('../../utils/fn.js');
6402
6403var Fn = _interopRequireWildcard(_utilsFnJs);
6404
6405var _utilsDomJs = _dereq_('../../utils/dom.js');
6406
6407var Dom = _interopRequireWildcard(_utilsDomJs);
6408
6409var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
6410
6411var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
6412
6413/**
6414 * Shows play progress
6415 *
6416 * @param {Player|Object} player
6417 * @param {Object=} options
6418 * @extends Component
6419 * @class PlayProgressBar
6420 */
6421
6422var TooltipProgressBar = (function (_Component) {
6423  _inherits(TooltipProgressBar, _Component);
6424
6425  function TooltipProgressBar(player, options) {
6426    _classCallCheck(this, TooltipProgressBar);
6427
6428    _Component.call(this, player, options);
6429    this.updateDataAttr();
6430    this.on(player, 'timeupdate', this.updateDataAttr);
6431    player.ready(Fn.bind(this, this.updateDataAttr));
6432  }
6433
6434  /**
6435   * Create the component's DOM element
6436   *
6437   * @return {Element}
6438   * @method createEl
6439   */
6440
6441  TooltipProgressBar.prototype.createEl = function createEl() {
6442    var el = _Component.prototype.createEl.call(this, 'div', {
6443      className: 'vjs-tooltip-progress-bar vjs-slider-bar',
6444      innerHTML: '<div class="vjs-time-tooltip"></div>\n        <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
6445    });
6446
6447    this.tooltip = el.querySelector('.vjs-time-tooltip');
6448
6449    return el;
6450  };
6451
6452  TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr() {
6453    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
6454    var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
6455    this.el_.setAttribute('data-current-time', formattedTime);
6456    this.tooltip.innerHTML = formattedTime;
6457  };
6458
6459  return TooltipProgressBar;
6460})(_componentJs2['default']);
6461
6462_componentJs2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
6463exports['default'] = TooltipProgressBar;
6464module.exports = exports['default'];
6465
6466},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/format-time.js":146}],83:[function(_dereq_,module,exports){
6467/**
6468 * @file custom-control-spacer.js
6469 */
6470'use strict';
6471
6472exports.__esModule = true;
6473
6474function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6475
6476function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6477
6478function _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; }
6479
6480var _spacerJs = _dereq_('./spacer.js');
6481
6482var _spacerJs2 = _interopRequireDefault(_spacerJs);
6483
6484var _componentJs = _dereq_('../../component.js');
6485
6486var _componentJs2 = _interopRequireDefault(_componentJs);
6487
6488/**
6489 * Spacer specifically meant to be used as an insertion point for new plugins, etc.
6490 *
6491 * @extends Spacer
6492 * @class CustomControlSpacer
6493 */
6494
6495var CustomControlSpacer = (function (_Spacer) {
6496  _inherits(CustomControlSpacer, _Spacer);
6497
6498  function CustomControlSpacer() {
6499    _classCallCheck(this, CustomControlSpacer);
6500
6501    _Spacer.apply(this, arguments);
6502  }
6503
6504  /**
6505   * Allow sub components to stack CSS class names
6506   *
6507   * @return {String} The constructed class name
6508   * @method buildCSSClass
6509   */
6510
6511  CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
6512    return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
6513  };
6514
6515  /**
6516   * Create the component's DOM element
6517   *
6518   * @return {Element}
6519   * @method createEl
6520   */
6521
6522  CustomControlSpacer.prototype.createEl = function createEl() {
6523    var el = _Spacer.prototype.createEl.call(this, {
6524      className: this.buildCSSClass()
6525    });
6526
6527    // No-flex/table-cell mode requires there be some content
6528    // in the cell to fill the remaining space of the table.
6529    el.innerHTML = '&nbsp;';
6530    return el;
6531  };
6532
6533  return CustomControlSpacer;
6534})(_spacerJs2['default']);
6535
6536_componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
6537exports['default'] = CustomControlSpacer;
6538module.exports = exports['default'];
6539
6540},{"../../component.js":67,"./spacer.js":84}],84:[function(_dereq_,module,exports){
6541/**
6542 * @file spacer.js
6543 */
6544'use strict';
6545
6546exports.__esModule = true;
6547
6548function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6549
6550function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6551
6552function _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, { c
6552onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6553
6554var _componentJs = _dereq_('../../component.js');
6555
6556var _componentJs2 = _interopRequireDefault(_componentJs);
6557
6558/**
6559 * Just an empty spacer element that can be used as an append point for plugins, etc.
6560 * Also can be used to create space between elements when necessary.
6561 *
6562 * @extends Component
6563 * @class Spacer
6564 */
6565
6566var Spacer = (function (_Component) {
6567  _inherits(Spacer, _Component);
6568
6569  function Spacer() {
6570    _classCallCheck(this, Spacer);
6571
6572    _Component.apply(this, arguments);
6573  }
6574
6575  /**
6576   * Allow sub components to stack CSS class names
6577   *
6578   * @return {String} The constructed class name
6579   * @method buildCSSClass
6580   */
6581
6582  Spacer.prototype.buildCSSClass = function buildCSSClass() {
6583    return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
6584  };
6585
6586  /**
6587   * Create the component's DOM element
6588   *
6589   * @return {Element}
6590   * @method createEl
6591   */
6592
6593  Spacer.prototype.createEl = function createEl() {
6594    return _Component.prototype.createEl.call(this, 'div', {
6595      className: this.buildCSSClass()
6596    });
6597  };
6598
6599  return Spacer;
6600})(_componentJs2['default']);
6601
6602_componentJs2['default'].registerComponent('Spacer', Spacer);
6603
6604exports['default'] = Spacer;
6605module.exports = exports['default'];
6606
6607},{"../../component.js":67}],85:[function(_dereq_,module,exports){
6608/**
6609 * @file caption-settings-menu-item.js
6610 */
6611'use strict';
6612
6613exports.__esModule = true;
6614
6615function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6616
6617function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6618
6619function _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; }
6620
6621var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6622
6623var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6624
6625var _componentJs = _dereq_('../../component.js');
6626
6627var _componentJs2 = _interopRequireDefault(_componentJs);
6628
6629/**
6630 * The menu item for caption track settings menu
6631 *
6632 * @param {Player|Object} player
6633 * @param {Object=} options
6634 * @extends TextTrackMenuItem
6635 * @class CaptionSettingsMenuItem
6636 */
6637
6638var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) {
6639  _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
6640
6641  function CaptionSettingsMenuItem(player, options) {
6642    _classCallCheck(this, CaptionSettingsMenuItem);
6643
6644    options['track'] = {
6645      'kind': options['kind'],
6646      'player': player,
6647      'label': options['kind'] + ' settings',
6648      'selectable': false,
6649      'default': false,
6650      mode: 'disabled'
6651    };
6652
6653    // CaptionSettingsMenuItem has no concept of 'selected'
6654    options['selectable'] = false;
6655
6656    _TextTrackMenuItem.call(this, player, options);
6657    this.addClass('vjs-texttrack-settings');
6658    this.controlText(', opens ' + options['kind'] + ' settings dialog');
6659  }
6660
6661  /**
6662   * Handle click on menu item
6663   *
6664   * @method handleClick
6665   */
6666
6667  CaptionSettingsMenuItem.prototype.handleClick = function handleClick() {
6668    this.player().getChild('textTrackSettings').show();
6669    this.player().getChild('textTrackSettings').el_.focus();
6670  };
6671
6672  return CaptionSettingsMenuItem;
6673})(_textTrackMenuItemJs2['default']);
6674
6675_componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
6676exports['default'] = CaptionSettingsMenuItem;
6677module.exports = exports['default'];
6678
6679},{"../../component.js":67,"./text-track-menu-item.js":93}],86:[function(_dereq_,module,exports){
6680/**
6681 * @file captions-button.js
6682 */
6683'use strict';
6684
6685exports.__esModule = true;
6686
6687function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6688
6689function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6690
6691function _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, { c
6691onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6692
6693var _textTrackButtonJs = _dereq_('./text-track-button.js');
6694
6695var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
6696
6697var _componentJs = _dereq_('../../component.js');
6698
6699var _componentJs2 = _interopRequireDefault(_componentJs);
6700
6701var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js');
6702
6703var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs);
6704
6705/**
6706 * The button component for toggling and selecting captions
6707 *
6708 * @param {Object} player  Player object
6709 * @param {Object=} options Object of option names and values
6710 * @param {Function=} ready    Ready callback function
6711 * @extends TextTrackButton
6712 * @class CaptionsButton
6713 */
6714
6715var CaptionsButton = (function (_TextTrackButton) {
6716  _inherits(CaptionsButton, _TextTrackButton);
6717
6718  function CaptionsButton(player, options, ready) {
6719    _classCallCheck(this, CaptionsButton);
6720
6721    _TextTrackButton.call(this, player, options, ready);
6722    this.el_.setAttribute('aria-label', 'Captions Menu');
6723  }
6724
6725  /**
6726   * Allow sub components to stack CSS class names
6727   *
6728   * @return {String} The constructed class name
6729   * @method buildCSSClass
6730   */
6731
6732  CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
6733    return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
6734  };
6735
6736  /**
6737   * Update caption menu items
6738   *
6739   * @method update
6740   */
6741
6742  CaptionsButton.prototype.update = function update() {
6743    var threshold = 2;
6744    _TextTrackButton.prototype.update.call(this);
6745
6746    // if native, then threshold is 1 because no settings button
6747    if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) {
6748      threshold = 1;
6749    }
6750
6751    if (this.items && this.items.length > threshold) {
6752      this.show();
6753    } else {
6754      this.hide();
6755    }
6756  };
6757
6758  /**
6759   * Create caption menu items
6760   *
6761   * @return {Array} Array of menu items
6762   * @method createItems
6763   */
6764
6765  CaptionsButton.prototype.createItems = function createItems() {
6766    var items = [];
6767
6768    if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) {
6769      items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
6770    }
6771
6772    return _TextTrackButton.prototype.createItems.call(this, items);
6773  };
6774
6775  return CaptionsButton;
6776})(_textTrackButtonJs2['default']);
6777
6778CaptionsButton.prototype.kind_ = 'captions';
6779CaptionsButton.prototype.controlText_ = 'Captions';
6780
6781_componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton);
6782exports['default'] = CaptionsButton;
6783module.exports = exports['default'];
6784
6785},{"../../component.js":67,"./caption-settings-menu-item.js":85,"./text-track-button.js":92}],87:[function(_dereq_,module,exports){
6786/**
6787 * @file chapters-button.js
6788 */
6789'use strict';
6790
6791exports.__esModule = true;
6792
6793function _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; } }
6794
6795function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6796
6797function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6798
6799function _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; }
6800
6801var _textTrackButtonJs = _dereq_('./text-track-button.js');
6802
6803var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
6804
6805var _componentJs = _dereq_('../../component.js');
6806
6807var _componentJs2 = _interopRequireDefault(_componentJs);
6808
6809var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6810
6811var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6812
6813var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js');
6814
6815var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs);
6816
6817var _menuMenuJs = _dereq_('../../menu/menu.js');
6818
6819var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
6820
6821var _utilsDomJs = _dereq_('../../utils/dom.js');
6822
6823var Dom = _interopRequireWildcard(_utilsDomJs);
6824
6825var _utilsFnJs = _dereq_('../../utils/fn.js');
6826
6827var Fn = _interopRequireWildcard(_utilsFnJs);
6828
6829var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js');
6830
6831var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
6832
6833var _globalWindow = _dereq_('global/window');
6834
6835var _globalWindow2 = _interopRequireDefault(_globalWindow);
6836
6837/**
6838 * The button component for toggling and selecting chapters
6839 * Chapters act much differently than other text tracks
6840 * Cues are navigation vs. other tracks of alternative languages
6841 *
6842 * @param {Object} player  Player object
6843 * @param {Object=} options Object of option names and values
6844 * @param {Function=} ready    Ready callback function
6845 * @extends TextTrackButton
6846 * @class ChaptersButton
6847 */
6848
6849var ChaptersButton = (function (_TextTrackButton) {
6850  _inherits(ChaptersButton, _TextTrackButton);
6851
6852  function ChaptersButton(player, options, ready) {
6853    _classCallCheck(this, ChaptersButton);
6854
6855    _TextTrackButton.call(this, player, options, ready);
6856    this.el_.setAttribute('aria-label', 'Chapters Menu');
6857  }
6858
6859  /**
6860   * Allow sub components to stack CSS class names
6861   *
6862   * @return {String} The constructed class name
6863   * @method buildCSSClass
6864   */
6865
6866  ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
6867    return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
6868  };
6869
6870  /**
6871   * Create a menu item for each text track
6872   *
6873   * @return {Array} Array of menu items
6874   * @method createItems
6875   */
6876
6877  ChaptersButton.prototype.createItems = function createItems() {
6878    var items = [];
6879
6880    var tracks = this.player_.textTracks();
6881
6882    if (!tracks) {
6883      return items;
6884    }
6885
6886    for (var i = 0; i < tracks.length; i++) {
6887      var track = tracks[i];
6888      if (track['kind'] === this.kind_) {
6889        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
6890          'track': track
6891        }));
6892      }
6893    }
6894
6895    return items;
6896  };
6897
6898  /**
6899   * Create menu from chapter buttons
6900   *
6901   * @return {Menu} Menu of chapter buttons
6902   * @method createMenu
6903   */
6904
6905  ChaptersButton.prototype.createMenu = function createMenu() {
6906    var _this = this;
6907
6908    var tracks = this.player_.textTracks() || [];
6909    var chaptersTrack = undefined;
6910    var items = this.items = [];
6911
6912    for (var i = 0, _length = tracks.length; i < _length; i++) {
6913      var track = tracks[i];
6914
6915      if (track['kind'] === this.kind_) {
6916        chaptersTrack = track;
6917
6918        break;
6919      }
6920    }
6921
6922    var menu = this.menu;
6923    if (menu === undefined) {
6924      menu = new _menuMenuJs2['default'](this.player_);
6925      var title = Dom.createEl('li', {
6926        className: 'vjs-menu-title',
6927        innerHTML: _utilsToTitleCaseJs2['default'](this.kind_),
6928        tabIndex: -1
6929      });
6930      menu.children_.unshift(title);
6931      Dom.insertElFirst(title, menu.contentEl());
6932    }
6933
6934    if (chaptersTrack && chaptersTrack.cues == null) {
6935      chaptersTrack['mode'] = 'hidden';
6936
6937      var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
6938
6939      if (remoteTextTrackEl) {
6940        remoteTextTrackEl.addEventListener('load', function (event) {
6941          return _this.update();
6942        });
6943      }
6944    }
6945
6946    if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
6947      var cues = chaptersTrack['cues'],
6948          cue = undefined;
6949
6950      for (var i = 0, l = cues.length; i < l; i++) {
6951        cue = cues[i];
6952
6953        var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, {
6954          'track': chaptersTrack,
6955          'cue': cue
6956        });
6957
6958        items.push(mi);
6959
6960        menu.addChild(mi);
6961      }
6962
6963      this.addChild(menu);
6964    }
6965
6966    if (this.items.length > 0) {
6967      this.show();
6968    }
6969
6970    return menu;
6971  };
6972
6973  return ChaptersButton;
6974})(_textTrackButtonJs2['default']);
6975
6976ChaptersButton.prototype.kind_ = 'chapters';
6977ChaptersButton.prototype.controlText_ = 'Chapters';
6978
6979_componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton);
6980exports['default'] = ChaptersButton;
6981module.exports = exports['default'];
6982
6983},{"../../component.js":67,"../../menu/menu.js":111,"../../utils/dom.js":143,"../../utils/fn.js":145,"../../utils/to-title-case.js":152,"./chapters-track-menu-item.js":88,"./text-track-button.js":92,"./text-track-menu-item.js":93,"global/window":2}],88:[function(_dereq_,module,exports){
6984/**
6985 * @file chapters-track-menu-item.js
6986 */
6987'use strict';
6988
6989exports.__esModule = true;
6990
6991function _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; } }
6992
6993function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6994
6995function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6996
6997function _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; }
6998
6999var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
7000
7001var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
7002
7003var _componentJs = _dereq_('../../component.js');
7004
7005var _componentJs2 = _interopRequireDefault(_componentJs);
7006
7007var _utilsFnJs = _dereq_('../../utils/fn.js');
7008
7009var Fn = _interopRequireWildcard(_utilsFnJs);
7010
7011/**
7012 * The chapter track menu item
7013 *
7014 * @param {Player|Object} player
7015 * @param {Object=} options
7016 * @extends MenuItem
7017 * @class ChaptersTrackMenuItem
7018 */
7019
7020var ChaptersTrackMenuItem = (function (_MenuItem) {
7021  _inherits(ChaptersTrackMenuItem, _MenuItem);
7022
7023  function ChaptersTrackMenuItem(player, options) {
7024    _classCallCheck(this, ChaptersTrackMenuItem);
7025
7026    var track = options['track'];
7027    var cue = options['cue'];
7028    var currentTime = player.currentTime();
7029
7030    // Modify options for parent MenuItem class's init.
7031    options['label'] = cue.text;
7032    options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime'];
7033    _MenuItem.call(this, player, options);
7034
7035    this.track = track;
7036    this.cue = cue;
7037    track.addEventListener('cuechange', Fn.bind(this, this.update));
7038  }
7039
7040  /**
7041   * Handle click on menu item
7042   *
7043   * @method handleClick
7044   */
7045
7046  ChaptersTrackMenuItem.prototype.handleClick = function handleClick() {
7047    _MenuItem.prototype.handleClick.call(this);
7048    this.player_.currentTime(this.cue.startTime);
7049    this.update(this.cue.startTime);
7050  };
7051
7052  /**
7053   * Update chapter menu item
7054   *
7055   * @method update
7056   */
7057
7058  ChaptersTrackMenuItem.prototype.update = function update() {
7059    var cue = this.cue;
7060    var currentTime = this.player_.currentTime();
7061
7062    // vjs.log(currentTime, cue.startTime);
7063    this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']);
7064  };
7065
7066  return ChaptersTrackMenuItem;
7067})(_menuMenuItemJs2['default']);
7068
7069_componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
7070exports['default'] = ChaptersTrackMenuItem;
7071module.exports = exports['default'];
7072
7073},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145}],89:[function(_dereq_,module,exports){
7074/**
7075 * @file descriptions-button.js
7076 */
7077'use strict';
7078
7079exports.__esModule = true;
7080
7081function _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; } }
7082
7083function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7084
7085function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7086
7087function _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; }
7088
7089var _textTrackButtonJs = _dereq_('./text-track-button.js');
7090
7091var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
7092
7093var _componentJs = _dereq_('../../component.js');
7094
7095var _componentJs2 = _interopRequireDefault(_componentJs);
7096
7097var _utilsFnJs = _dereq_('../../utils/fn.js');
7098
7099var Fn = _interopRequireWildcard(_utilsFnJs);
7100
7101/**
7102 * The button component for toggling and selecting descriptions
7103 *
7104 * @param {Object} player  Player object
7105 * @param {Object=} options Object of option names and values
7106 * @param {Function=} ready    Ready callback function
7107 * @extends TextTrackButton
7108 * @class DescriptionsButton
7109 */
7110
7111var DescriptionsButton = (function (_TextTrackButton) {
7112  _inherits(DescriptionsButton, _TextTrackButton);
7113
7114  function DescriptionsButton(player, options, ready) {
7115    var _this = this;
7116
7117    _classCallCheck(this, DescriptionsButton);
7118
7119    _TextTrackButton.call(this, player, options, ready);
7120    this.el_.setAttribute('aria-label', 'Descriptions Menu');
7121
7122    var tracks = player.textTracks();
7123
7124    if (tracks) {
7125      (function () {
7126        var changeHandler = Fn.bind(_this, _this.handleTracksChange);
7127
7128        tracks.addEventListener('change', changeHandler);
7129        _this.on('dispose', function () {
7130          tracks.removeEventListener('change', changeHandler);
7131        });
7132      })();
7133    }
7134  }
7135
7136  /**
7137   * Handle text track change
7138   *
7139   * @method handleTracksChange
7140   */
7141
7142  DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
7143    var tracks = this.player().textTracks();
7144    var disabled = false;
7145
7146    // Check whether a track of a different kind is showing
7147    for (var i = 0, l = tracks.length; i < l; i++) {
7148      var track = tracks[i];
7149      if (track['kind'] !== this.kind_ && track['mode'] === 'showing') {
7150        disabled = true;
7151        break;
7152      }
7153    }
7154
7155    // If another track is showing, disable this menu button
7156    if (disabled) {
7157      this.disable();
7158    } else {
7159      this.enable();
7160    }
7161  };
7162
7163  /**
7164   * Allow sub components to stack CSS class names
7165   *
7166   * @return {String} The constructed class name
7167   * @method buildCSSClass
7168   */
7169
7170  DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
7171    return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
7172  };
7173
7174  return DescriptionsButton;
7175})(_textTrackButtonJs2['default']);
7176
7177DescriptionsButton.prototype.kind_ = 'descriptions';
7178DescriptionsButton.prototype.controlText_ = 'Descriptions';
7179
7180_componentJs2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
7181exports['default'] = DescriptionsButton;
7182module.exports = exports['default'];
7183
7184},{"../../component.js":67,"../../utils/fn.js":145,"./text-track-button.js":92}],90:[function(_dereq_,module,exports){
7185/**
7186 * @file off-text-track-menu-item.js
7187 */
7188'use strict';
7189
7190exports.__esModule = true;
7191
7192function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7193
7194function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7195
7196function _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, { c
7196onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7197
7198var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
7199
7200var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
7201
7202var _componentJs = _dereq_('../../component.js');
7203
7204var _componentJs2 = _interopRequireDefault(_componentJs);
7205
7206/**
7207 * A special menu item for turning of a specific type of text track
7208 *
7209 * @param {Player|Object} player
7210 * @param {Object=} options
7211 * @extends TextTrackMenuItem
7212 * @class OffTextTrackMenuItem
7213 */
7214
7215var OffTextTrackMenuItem = (function (_TextTrackMenuItem) {
7216  _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
7217
7218  function OffTextTrackMenuItem(player, options) {
7219    _classCallCheck(this, OffTextTrackMenuItem);
7220
7221    // Create pseudo track info
7222    // Requires options['kind']
7223    options['track'] = {
7224      'kind': options['kind'],
7225      'player': player,
7226      'label': options['kind'] + ' off',
7227      'default': false,
7228      'mode': 'disabled'
7229    };
7230
7231    // MenuItem is selectable
7232    options['selectable'] = true;
7233
7234    _TextTrackMenuItem.call(this, player, options);
7235    this.selected(true);
7236  }
7237
7238  /**
7239   * Handle text track change
7240   *
7241   * @param {Object} event Event object
7242   * @method handleTracksChange
7243   */
7244
7245  OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
7246    var tracks = this.player().textTracks();
7247    var selected = true;
7248
7249    for (var i = 0, l = tracks.length; i < l; i++) {
7250      var track = tracks[i];
7251      if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') {
7252        selected = false;
7253        break;
7254      }
7255    }
7256
7257    this.selected(selected);
7258  };
7259
7260  return OffTextTrackMenuItem;
7261})(_textTrackMenuItemJs2['default']);
7262
7263_componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
7264exports['default'] = OffTextTrackMenuItem;
7265module.exports = exports['default'];
7266
7267},{"../../component.js":67,"./text-track-menu-item.js":93}],91:[function(_dereq_,module,exports){
7268/**
7269 * @file subtitles-button.js
7270 */
7271'use strict';
7272
7273exports.__esModule = true;
7274
7275function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7276
7277function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7278
7279function _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; }
7280
7281var _textTrackButtonJs = _dereq_('./text-track-button.js');
7282
7283var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
7284
7285var _componentJs = _dereq_('../../component.js');
7286
7287var _componentJs2 = _interopRequireDefault(_componentJs);
7288
7289/**
7290 * The button component for toggling and selecting subtitles
7291 *
7292 * @param {Object} player  Player object
7293 * @param {Object=} options Object of option names and values
7294 * @param {Function=} ready    Ready callback function
7295 * @extends TextTrackButton
7296 * @class SubtitlesButton
7297 */
7298
7299var SubtitlesButton = (function (_TextTrackButton) {
7300  _inherits(SubtitlesButton, _TextTrackButton);
7301
7302  function SubtitlesButton(player, options, ready) {
7303    _classCallCheck(this, SubtitlesButton);
7304
7305    _TextTrackButton.call(this, player, options, ready);
7306    this.el_.setAttribute('aria-label', 'Subtitles Menu');
7307  }
7308
7309  /**
7310   * Allow sub components to stack CSS class names
7311   *
7312   * @return {String} The constructed class name
7313   * @method buildCSSClass
7314   */
7315
7316  SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
7317    return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
7318  };
7319
7320  return SubtitlesButton;
7321})(_textTrackButtonJs2['default']);
7322
7323SubtitlesButton.prototype.kind_ = 'subtitles';
7324SubtitlesButton.prototype.controlText_ = 'Subtitles';
7325
7326_componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
7327exports['default'] = SubtitlesButton;
7328module.exports = exports['default'];
7329
7330},{"../../component.js":67,"./text-track-button.js":92}],92:[function(_dereq_,module,exports){
7331/**
7332 * @file text-track-button.js
7333 */
7334'use strict';
7335
7336exports.__esModule = true;
7337
7338function _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; } }
7339
7340function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7341
7342function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7343
7344function _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, { c
7344onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7345
7346var _trackButtonJs = _dereq_('../track-button.js');
7347
7348var _trackButtonJs2 = _interopRequireDefault(_trackButtonJs);
7349
7350var _componentJs = _dereq_('../../component.js');
7351
7352var _componentJs2 = _interopRequireDefault(_componentJs);
7353
7354var _utilsFnJs = _dereq_('../../utils/fn.js');
7355
7356var Fn = _interopRequireWildcard(_utilsFnJs);
7357
7358var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
7359
7360var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
7361
7362var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js');
7363
7364var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs);
7365
7366/**
7367 * The base class for buttons that toggle specific text track types (e.g. subtitles)
7368 *
7369 * @param {Player|Object} player
7370 * @param {Object=} options
7371 * @extends MenuButton
7372 * @class TextTrackButton
7373 */
7374
7375var TextTrackButton = (function (_TrackButton) {
7376  _inherits(TextTrackButton, _TrackButton);
7377
7378  function TextTrackButton(player) {
7379    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7380
7381    _classCallCheck(this, TextTrackButton);
7382
7383    options.tracks = player.textTracks();
7384
7385    _TrackButton.call(this, player, options);
7386  }
7387
7388  /**
7389   * Create a menu item for each text track
7390   *
7391   * @return {Array} Array of menu items
7392   * @method createItems
7393   */
7394
7395  TextTrackButton.prototype.createItems = function createItems() {
7396    var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
7397
7398    // Add an OFF menu item to turn all tracks off
7399    items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
7400
7401    var tracks = this.player_.textTracks();
7402
7403    if (!tracks) {
7404      return items;
7405    }
7406
7407    for (var i = 0; i < tracks.length; i++) {
7408      var track = tracks[i];
7409
7410      // only add tracks that are of the appropriate kind and have a label
7411      if (track['kind'] === this.kind_) {
7412        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
7413          // MenuItem is selectable
7414          'selectable': true,
7415          'track': track
7416        }));
7417      }
7418    }
7419
7420    return items;
7421  };
7422
7423  return TextTrackButton;
7424})(_trackButtonJs2['default']);
7425
7426_componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton);
7427exports['default'] = TextTrackButton;
7428module.exports = exports['default'];
7429
7430},{"../../component.js":67,"../../utils/fn.js":145,"../track-button.js":98,"./off-text-track-menu-item.js":90,"./text-track-menu-item.js":93}],93:[function(_dereq_,module,exports){
7431/**
7432 * @file text-track-menu-item.js
7433 */
7434'use strict';
7435
7436exports.__esModule = true;
7437
7438function _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; } }
7439
7440function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7441
7442function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7443
7444function _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; }
7445
7446var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
7447
7448var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
7449
7450var _componentJs = _dereq_('../../component.js');
7451
7452var _componentJs2 = _interopRequireDefault(_componentJs);
7453
7454var _utilsFnJs = _dereq_('../../utils/fn.js');
7455
7456var Fn = _interopRequireWildcard(_utilsFnJs);
7457
7458var _globalWindow = _dereq_('global/window');
7459
7460var _globalWindow2 = _interopRequireDefault(_globalWindow);
7461
7462var _globalDocument = _dereq_('global/document');
7463
7464var _globalDocument2 = _interopRequireDefault(_globalDocument);
7465
7466/**
7467 * The specific menu item type for selecting a language within a text track kind
7468 *
7469 * @param {Player|Object} player
7470 * @param {Object=} options
7471 * @extends MenuItem
7472 * @class TextTrackMenuItem
7473 */
7474
7475var TextTrackMenuItem = (function (_MenuItem) {
7476  _inherits(TextTrackMenuItem, _MenuItem);
7477
7478  function TextTrackMenuItem(player, options) {
7479    var _this = this;
7480
7481    _classCallCheck(this, TextTrackMenuItem);
7482
7483    var track = options['track'];
7484    var tracks = player.textTracks();
7485
7486    // Modify options for parent MenuItem class's init.
7487    options['label'] = track['label'] || track['language'] || 'Unknown';
7488    options['selected'] = track['default'] || track['mode'] === 'showing';
7489
7490    _MenuItem.call(this, player, options);
7491
7492    this.track = track;
7493
7494    if (tracks) {
7495      (function () {
7496        var changeHandler = Fn.bind(_this, _this.handleTracksChange);
7497
7498        tracks.addEventListener('change', changeHandler);
7499        _this.on('dispose', function () {
7500          tracks.removeEventListener('change', changeHandler);
7501        });
7502      })();
7503    }
7504
7505    // iOS7 doesn't dispatch change events to TextTrackLists when an
7506    // associated track's mode changes. Without something like
7507    // Object.observe() (also not present on iOS7), it's not
7508    // possible to detect changes to the mode attribute and polyfill
7509    // the change event. As a poor substitute, we manually dispatch
7510    // change events whenever the controls modify the mode.
7511    if (tracks && tracks.onchange === undefined) {
7512      (function () {
7513        var event = undefined;
7514
7515        _this.on(['tap', 'click'], function () {
7516          if (typeof _globalWindow2['default'].Event !== 'object') {
7517            // Android 2.3 throws an Illegal Constructor error for window.Event
7518            try {
7519              event = new _globalWindow2['default'].Event('change');
7520            } catch (err) {}
7521          }
7522
7523          if (!event) {
7524            event = _globalDocument2['default'].createEvent('Event');
7525            event.initEvent('change', true, true);
7526          }
7527
7528          tracks.dispatchEvent(event);
7529        });
7530      })();
7531    }
7532  }
7533
7534  /**
7535   * Handle click on text track
7536   *
7537   * @method handleClick
7538   */
7539
7540  TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
7541    var kind = this.track['kind'];
7542    var tracks = this.player_.textTracks();
7543
7544    _MenuItem.prototype.handleClick.call(this, event);
7545
7546    if (!tracks) return;
7547
7548    for (var i = 0; i < tracks.length; i++) {
7549      var track = tracks[i];
7550
7551      if (track['kind'] !== kind) {
7552        continue;
7553      }
7554
7555      if (track === this.track) {
7556        track['mode'] = 'showing';
7557      } else {
7558        track['mode'] = 'disabled';
7559      }
7560    }
7561  };
7562
7563  /**
7564   * Handle text track change
7565   *
7566   * @method handleTracksChange
7567   */
7568
7569  TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
7570    this.selected(this.track['mode'] === 'showing');
7571  };
7572
7573  return TextTrackMenuItem;
7574}
7574)(_menuMenuItemJs2['default']);
7575
7576_componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
7577exports['default'] = TextTrackMenuItem;
7578module.exports = exports['default'];
7579
7580},{"../../component.js":67,"../../menu/menu-item.js":110,"../../utils/fn.js":145,"global/document":1,"global/window":2}],94:[function(_dereq_,module,exports){
7581/**
7582 * @file current-time-display.js
7583 */
7584'use strict';
7585
7586exports.__esModule = true;
7587
7588function _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; } }
7589
7590function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7591
7592function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7593
7594function _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; }
7595
7596var _componentJs = _dereq_('../../component.js');
7597
7598var _componentJs2 = _interopRequireDefault(_componentJs);
7599
7600var _utilsDomJs = _dereq_('../../utils/dom.js');
7601
7602var Dom = _interopRequireWildcard(_utilsDomJs);
7603
7604var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
7605
7606var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
7607
7608/**
7609 * Displays the current time
7610 *
7611 * @param {Player|Object} player
7612 * @param {Object=} options
7613 * @extends Component
7614 * @class CurrentTimeDisplay
7615 */
7616
7617var CurrentTimeDisplay = (function (_Component) {
7618  _inherits(CurrentTimeDisplay, _Component);
7619
7620  function CurrentTimeDisplay(player, options) {
7621    _classCallCheck(this, CurrentTimeDisplay);
7622
7623    _Component.call(this, player, options);
7624
7625    this.on(player, 'timeupdate', this.updateContent);
7626  }
7627
7628  /**
7629   * Create the component's DOM element
7630   *
7631   * @return {Element}
7632   * @method createEl
7633   */
7634
7635  CurrentTimeDisplay.prototype.createEl = function createEl() {
7636    var el = _Component.prototype.createEl.call(this, 'div', {
7637      className: 'vjs-current-time vjs-time-control vjs-control'
7638    });
7639
7640    this.contentEl_ = Dom.createEl('div', {
7641      className: 'vjs-current-time-display',
7642      // label the current time for screen reader users
7643      innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
7644    }, {
7645      // tell screen readers not to automatically read the time as it changes
7646      'aria-live': 'off'
7647    });
7648
7649    el.appendChild(this.contentEl_);
7650    return el;
7651  };
7652
7653  /**
7654   * Update current time display
7655   *
7656   * @method updateContent
7657   */
7658
7659  CurrentTimeDisplay.prototype.updateContent = function updateContent() {
7660    // Allows for smooth scrubbing, when player can't keep up.
7661    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
7662    var localizedText = this.localize('Current Time');
7663    var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
7664    if (formattedTime !== this.formattedTime_) {
7665      this.formattedTime_ = formattedTime;
7666      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
7667    }
7668  };
7669
7670  return CurrentTimeDisplay;
7671})(_componentJs2['default']);
7672
7673_componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
7674exports['default'] = CurrentTimeDisplay;
7675module.exports = exports['default'];
7676
7677},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],95:[function(_dereq_,module,exports){
7678/**
7679 * @file duration-display.js
7680 */
7681'use strict';
7682
7683exports.__esModule = true;
7684
7685function _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; } }
7686
7687function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7688
7689function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7690
7691function _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, { c
7691onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7692
7693var _componentJs = _dereq_('../../component.js');
7694
7695var _componentJs2 = _interopRequireDefault(_componentJs);
7696
7697var _utilsDomJs = _dereq_('../../utils/dom.js');
7698
7699var Dom = _interopRequireWildcard(_utilsDomJs);
7700
7701var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
7702
7703var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
7704
7705/**
7706 * Displays the duration
7707 *
7708 * @param {Player|Object} player
7709 * @param {Object=} options
7710 * @extends Component
7711 * @class DurationDisplay
7712 */
7713
7714var DurationDisplay = (function (_Component) {
7715  _inherits(DurationDisplay, _Component);
7716
7717  function DurationDisplay(player, options) {
7718    _classCallCheck(this, DurationDisplay);
7719
7720    _Component.call(this, player, options);
7721
7722    // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually,
7723    // however the durationchange event fires before this.player_.duration() is set,
7724    // so the value cannot be written out using this method.
7725    // Once the order of durationchange and this.player_.duration() being set is figured out,
7726    // this can be updated.
7727    this.on(player, 'timeupdate', this.updateContent);
7728    this.on(player, 'loadedmetadata', this.updateContent);
7729  }
7730
7731  /**
7732   * Create the component's DOM element
7733   *
7734   * @return {Element}
7735   * @method createEl
7736   */
7737
7738  DurationDisplay.prototype.createEl = function createEl() {
7739    var el = _Component.prototype.createEl.call(this, 'div', {
7740      className: 'vjs-duration vjs-time-control vjs-control'
7741    });
7742
7743    this.contentEl_ = Dom.createEl('div', {
7744      className: 'vjs-duration-display',
7745      // label the duration time for screen reader users
7746      innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
7747    }, {
7748      // tell screen readers not to automatically read the time as it changes
7749      'aria-live': 'off'
7750    });
7751
7752    el.appendChild(this.contentEl_);
7753    return el;
7754  };
7755
7756  /**
7757   * Update duration time display
7758   *
7759   * @method updateContent
7760   */
7761
7762  DurationDisplay.prototype.updateContent = function updateContent() {
7763    var duration = this.player_.duration();
7764    if (duration && this.duration_ !== duration) {
7765      this.duration_ = duration;
7766      var localizedText = this.localize('Duration Time');
7767      var formattedTime = _utilsFormatTimeJs2['default'](duration);
7768      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users
7769    }
7770  };
7771
7772  return DurationDisplay;
7773})(_componentJs2['default']);
7774
7775_componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay);
7776exports['default'] = DurationDisplay;
7777module.exports = exports['default'];
7778
7779},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],96:[function(_dereq_,module,exports){
7780/**
7781 * @file remaining-time-display.js
7782 */
7783'use strict';
7784
7785exports.__esModule = true;
7786
7787function _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; } }
7788
7789function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7790
7791function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7792
7793function _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; }
7794
7795var _componentJs = _dereq_('../../component.js');
7796
7797var _componentJs2 = _interopRequireDefault(_componentJs);
7798
7799var _utilsDomJs = _dereq_('../../utils/dom.js');
7800
7801var Dom = _interopRequireWildcard(_utilsDomJs);
7802
7803var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
7804
7805var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
7806
7807/**
7808 * Displays the time left in the video
7809 *
7810 * @param {Player|Object} player
7811 * @param {Object=} options
7812 * @extends Component
7813 * @class RemainingTimeDisplay
7814 */
7815
7816var RemainingTimeDisplay = (function (_Component) {
7817  _inherits(RemainingTimeDisplay, _Component);
7818
7819  function RemainingTimeDisplay(player, options) {
7820    _classCallCheck(this, RemainingTimeDisplay);
7821
7822    _Component.call(this, player, options);
7823
7824    this.on(player, 'timeupdate', this.updateContent);
7825  }
7826
7827  /**
7828   * Create the component's DOM element
7829   *
7830   * @return {Element}
7831   * @method createEl
7832   */
7833
7834  RemainingTimeDisplay.prototype.createEl = function createEl() {
7835    var el = _Component.prototype.createEl.call(this, 'div', {
7836      className: 'vjs-remaining-time vjs-time-control vjs-control'
7837    });
7838
7839    this.contentEl_ = Dom.createEl('div', {
7840      className: 'vjs-remaining-time-display',
7841      // label the remaining time for screen reader users
7842      innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
7843    }, {
7844      // tell screen readers not to automatically read the time as it changes
7845      'aria-live': 'off'
7846    });
7847
7848    el.appendChild(this.contentEl_);
7849    return el;
7850  };
7851
7852  /**
7853   * Update remaining time display
7854   *
7855   * @method updateContent
7856   */
7857
7858  RemainingTimeDisplay.prototype.updateContent = function updateContent() {
7859    if (this.player_.duration()) {
7860      var localizedText = this.localize('Remaining Time');
7861      var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime());
7862      if (formattedTime !== this.formattedTime_) {
7863        this.formattedTime_ = formattedTime;
7864        this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
7865      }
7866    }
7867
7868    // Allows for smooth scrubbing, when player can't keep up.
7869    // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
7870    // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
7871  };
7872
7873  return RemainingTimeDisplay;
7874})(_componentJs2['default']);
7875
7876_componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
7877exports['default'] = RemainingTimeDisplay;
7878module.exports = exports['default'];
7879
7880},{"../../component.js":67,"../../utils/dom.js":143,"../../utils/format-time.js":146}],97:[function(_dereq_,module,exports){
7881/**
7882 * @file time-divider.js
7883 */
7884'use strict';
7885
7886exports.__esModule = true;
7887
7888function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7889
7890function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7891
7892function _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; }
7893
7894var _componentJs = _dereq_('../../component.js');
7895
7896var _componentJs2 = _interopRequireDefault(_componentJs);
7897
7898/**
7899 * The separator between the current time and duration.
7900 * Can be hidden if it's not needed in the design.
7901 *
7902 * @param {Player|Object} player
7903 * @param {Object=} options
7904 * @extends Component
7905 * @class TimeDivider
7906 */
7907
7908var TimeDivider = (function (_Component) {
7909  _inherits(TimeDivider, _Component);
7910
7911  function TimeDivider() {
7912    _classCallCheck(this, TimeDivider);
7913
7914    _Component.apply(this, arguments);
7915  }
7916
7917  /**
7918   * Create the component's DOM element
7919   *
7920   * @return {Element}
7921   * @method createEl
7922   */
7923
7924  TimeDivider.prototype.createEl = function createEl() {
7925    return _Component.prototype.createEl.call(this, 'div', {
7926      className: 'vjs-time-control vjs-time-divider',
7927      innerHTML: '<div><span>/</span></div>'
7928    });
7929  };
7930
7931  return TimeDivider;
7932})(_componentJs2['default']);
7933
7934_componentJs2['default'].registerComponent('TimeDivider', TimeDivider);
7935exports['default'] = TimeDivider;
7936module.exports = exports['default'];
7937
7938},{"../../component.js":67}],98:[function(_dereq_,module,exports){
7939/**
7940 * @file track-button.js
7941 */
7942'use strict';
7943
7944exports.__esModule = true;
7945
7946function _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; } }
7947
7948function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7949
7950function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7951
7952function _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, { c
7952onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7953
7954var _menuMenuButtonJs = _dereq_('../menu/menu-button.js');
7955
7956var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
7957
7958var _componentJs = _dereq_('../component.js');
7959
7960var _componentJs2 = _interopRequireDefault(_componentJs);
7961
7962var _utilsFnJs = _dereq_('../utils/fn.js');
7963
7964var Fn = _interopRequireWildcard(_utilsFnJs);
7965
7966/**
7967 * The base class for buttons that toggle specific text track types (e.g. subtitles)
7968 *
7969 * @param {Player|Object} player
7970 * @param {Object=} options
7971 * @extends MenuButton
7972 * @class TrackButton
7973 */
7974
7975var TrackButton = (function (_MenuButton) {
7976  _inherits(TrackButton, _MenuButton);
7977
7978  function TrackButton(player, options) {
7979    _classCallCheck(this, TrackButton);
7980
7981    var tracks = options.tracks;
7982
7983    _MenuButton.call(this, player, options);
7984
7985    if (this.items.length <= 1) {
7986      this.hide();
7987    }
7988
7989    if (!tracks) {
7990      return;
7991    }
7992
7993    var updateHandler = Fn.bind(this, this.update);
7994    tracks.addEventListener('removetrack', updateHandler);
7995    tracks.addEventListener('addtrack', updateHandler);
7996
7997    this.player_.on('dispose', function () {
7998      tracks.removeEventListener('removetrack', updateHandler);
7999      tracks.removeEventListener('addtrack', updateHandler);
8000    });
8001  }
8002
8003  return TrackButton;
8004}
8004)(_menuMenuButtonJs2['default']);
8005
8006_componentJs2['default'].registerComponent('TrackButton', TrackButton);
8007exports['default'] = TrackButton;
8008module.exports = exports['default'];
8009
8010},{"../component.js":67,"../menu/menu-button.js":109,"../utils/fn.js":145}],99:[function(_dereq_,module,exports){
8011/**
8012 * @file volume-bar.js
8013 */
8014'use strict';
8015
8016exports.__esModule = true;
8017
8018function _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; } }
8019
8020function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8021
8022function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8023
8024function _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; }
8025
8026var _sliderSliderJs = _dereq_('../../slider/slider.js');
8027
8028var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
8029
8030var _componentJs = _dereq_('../../component.js');
8031
8032var _componentJs2 = _interopRequireDefault(_componentJs);
8033
8034var _utilsFnJs = _dereq_('../../utils/fn.js');
8035
8036var Fn = _interopRequireWildcard(_utilsFnJs);
8037
8038// Required children
8039
8040var _volumeLevelJs = _dereq_('./volume-level.js');
8041
8042var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs);
8043
8044/**
8045 * The bar that contains the volume level and can be clicked on to adjust the level
8046 *
8047 * @param {Player|Object} player
8048 * @param {Object=} options
8049 * @extends Slider
8050 * @class VolumeBar
8051 */
8052
8053var VolumeBar = (function (_Slider) {
8054  _inherits(VolumeBar, _Slider);
8055
8056  function VolumeBar(player, options) {
8057    _classCallCheck(this, VolumeBar);
8058
8059    _Slider.call(this, player, options);
8060    this.on(player, 'volumechange', this.updateARIAAttributes);
8061    player.ready(Fn.bind(this, this.updateARIAAttributes));
8062  }
8063
8064  /**
8065   * Create the component's DOM element
8066   *
8067   * @return {Element}
8068   * @method createEl
8069   */
8070
8071  VolumeBar.prototype.createEl = function createEl() {
8072    return _Slider.prototype.createEl.call(this, 'div', {
8073      className: 'vjs-volume-bar vjs-slider-bar'
8074    }, {
8075      'aria-label': 'volume level'
8076    });
8077  };
8078
8079  /**
8080   * Handle mouse move on volume bar
8081   *
8082   * @method handleMouseMove
8083   */
8084
8085  VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
8086    this.checkMuted();
8087    this.player_.volume(this.calculateDistance(event));
8088  };
8089
8090  VolumeBar.prototype.checkMuted = function checkMuted() {
8091    if (this.player_.muted()) {
8092      this.player_.muted(false);
8093    }
8094  };
8095
8096  /**
8097   * Get percent of volume level
8098   *
8099   * @retun {Number} Volume level percent
8100   * @method getPercent
8101   */
8102
8103  VolumeBar.prototype.getPercent = function getPercent() {
8104    if (this.player_.muted()) {
8105      return 0;
8106    } else {
8107      return this.player_.volume();
8108    }
8109  };
8110
8111  /**
8112   * Increase volume level for keyboard users
8113   *
8114   * @method stepForward
8115   */
8116
8117  VolumeBar.prototype.stepForward = function stepForward() {
8118    this.checkMuted();
8119    this.player_.volume(this.player_.volume() + 0.1);
8120  };
8121
8122  /**
8123   * Decrease volume level for keyboard users
8124   *
8125   * @method stepBack
8126   */
8127
8128  VolumeBar.prototype.stepBack = function stepBack() {
8129    this.checkMuted();
8130    this.player_.volume(this.player_.volume() - 0.1);
8131  };
8132
8133  /**
8134   * Update ARIA accessibility attributes
8135   *
8136   * @method updateARIAAttributes
8137   */
8138
8139  VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
8140    // Current value of volume bar as a percentage
8141    var volume = (this.player_.volume() * 100).toFixed(2);
8142    this.el_.setAttribute('aria-valuenow', volume);
8143    this.el_.setAttribute('aria-valuetext', volume + '%');
8144  };
8145
8146  return VolumeBar;
8147})(_sliderSliderJs2['default']);
8148
8149VolumeBar.prototype.options_ = {
8150  children: ['volumeLevel'],
8151  'barName': 'volumeLevel'
8152};
8153
8154VolumeBar.prototype.playerEvent = 'volumechange';
8155
8156_componentJs2['default'].registerComponent('VolumeBar', VolumeBar);
8157exports['default'] = VolumeBar;
8158module.exports = exports['default'];
8159
8160},{"../../component.js":67,"../../slider/slider.js":119,"../../utils/fn.js":145,"./volume-level.js":101}],100:[function(_dereq_,module,exports){
8161/**
8162 * @file volume-control.js
8163 */
8164'use strict';
8165
8166exports.__esModule = true;
8167
8168function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8169
8170function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8171
8172function _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; }
8173
8174var _componentJs = _dereq_('../../component.js');
8175
8176var _componentJs2 = _interopRequireDefault(_componentJs);
8177
8178// Required children
8179
8180var _volumeBarJs = _dereq_('./volume-bar.js');
8181
8182var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs);
8183
8184/**
8185 * The component for controlling the volume level
8186 *
8187 * @param {Player|Object} player
8188 * @param {Object=} options
8189 * @extends Component
8190 * @class VolumeControl
8191 */
8192
8193var VolumeControl = (function (_Component) {
8194  _inherits(VolumeControl, _Component);
8195
8196  function VolumeControl(player, options) {
8197    _classCallCheck(this, VolumeControl);
8198
8199    _Component.call(this, player, options);
8200
8201    // hide volume controls when they're not supported by the current tech
8202    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
8203      this.addClass('vjs-hidden');
8204    }
8205    this.on(player, 'loadstart', function () {
8206      if (player.tech_['featuresVolumeControl'] === false) {
8207        this.addClass('vjs-hidden');
8208      } else {
8209        this.removeClass('vjs-hidden');
8210      }
8211    });
8212  }
8213
8214  /**
8215   * Create the component's DOM element
8216   *
8217   * @return {Element}
8218   * @method createEl
8219   */
8220
8221  VolumeControl.prototype.createEl = function createEl() {
8222    return _Component.prototype.createEl.call(this, 'div', {
8223      className: 'vjs-volume-control vjs-control'
8224    });
8225  };
8226
8227  return VolumeControl;
8228})(_componentJs2['default']);
8229
8230VolumeControl.prototype.options_ = {
8231  children: ['volumeBar']
8232};
8233
8234_componentJs2['default'].registerComponent('VolumeControl', VolumeControl);
8235exports['default'] = VolumeControl;
8236module.exports = exports['default'];
8237
8238},{"../../component.js":67,"./volume-bar.js":99}],101:[function(_dereq_,module,exports){
8239/**
8240 * @file volume-level.js
8241 */
8242'use strict';
8243
8244exports.__esModule = true;
8245
8246function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8247
8248function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8249
8250function _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; }
8251
8252var _componentJs = _dereq_('../../component.js');
8253
8254var _componentJs2 = _interopRequireDefault(_componentJs);
8255
8256/**
8257 * Shows volume level
8258 *
8259 * @param {Player|Object} player
8260 * @param {Object=} options
8261 * @extends Component
8262 * @class VolumeLevel
8263 */
8264
8265var VolumeLevel = (function (_Component) {
8266  _inherits(VolumeLevel, _Component);
8267
8268  function VolumeLevel() {
8269    _classCallCheck(this, VolumeLevel);
8270
8271    _Component.apply(this, arguments);
8272  }
8273
8274  /**
8275   * Create the component's DOM element
8276   *
8277   * @return {Element}
8278   * @method createEl
8279   */
8280
8281  VolumeLevel.prototype.createEl = function createEl() {
8282    return _Component.prototype.createEl.call(this, 'div', {
8283      className: 'vjs-volume-level',
8284      innerHTML: '<span class="vjs-control-text"></span>'
8285    });
8286  };
8287
8288  return VolumeLevel;
8289})(_componentJs2['default']);
8290
8291_componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel);
8292exports['default'] = VolumeLevel;
8293module.exports = exports['default'];
8294
8295},{"../../component.js":67}],102:[function(_dereq_,module,exports){
8296/**
8297 * @file volume-menu-button.js
8298 */
8299'use strict';
8300
8301exports.__esModule = true;
8302
8303function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8304
8305function _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; } }
8306
8307function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8308
8309function _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, { c
8309onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8310
8311var _utilsFnJs = _dereq_('../utils/fn.js');
8312
8313var Fn = _interopRequireWildcard(_utilsFnJs);
8314
8315var _componentJs = _dereq_('../component.js');
8316
8317var _componentJs2 = _interopRequireDefault(_componentJs);
8318
8319var _popupPopupJs = _dereq_('../popup/popup.js');
8320
8321var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs);
8322
8323var _popupPopupButtonJs = _dereq_('../popup/popup-button.js');
8324
8325var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs);
8326
8327var _muteToggleJs = _dereq_('./mute-toggle.js');
8328
8329var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
8330
8331var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js');
8332
8333var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs);
8334
8335/**
8336 * Button for volume popup
8337 *
8338 * @param {Player|Object} player
8339 * @param {Object=} options
8340 * @extends PopupButton
8341 * @class VolumeMenuButton
8342 */
8343
8344var VolumeMenuButton = (function (_PopupButton) {
8345  _inherits(VolumeMenuButton, _PopupButton);
8346
8347  function VolumeMenuButton(player) {
8348    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8349
8350    _classCallCheck(this, VolumeMenuButton);
8351
8352    // Default to inline
8353    if (options.inline === undefined) {
8354      options.inline = true;
8355    }
8356
8357    // If the vertical option isn't passed at all, default to true.
8358    if (options.vertical === undefined) {
8359      // If an inline volumeMenuButton is used, we should default to using
8360      // a horizontal slider for obvious reasons.
8361      if (options.inline) {
8362        options.vertical = false;
8363      } else {
8364        options.vertical = true;
8365      }
8366    }
8367
8368    // The vertical option needs to be set on the volumeBar as well,
8369    // since that will need to be passed along to the VolumeBar constructor
8370    options.volumeBar = options.volumeBar || {};
8371    options.volumeBar.vertical = !!options.vertical;
8372
8373    _PopupButton.call(this, player, options);
8374
8375    // Same listeners as MuteToggle
8376    this.on(player, 'volumechange', this.volumeUpdate);
8377    this.on(player, 'loadstart', this.volumeUpdate);
8378
8379    // hide mute toggle if the current tech doesn't support volume control
8380    function updateVisibility() {
8381      if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
8382        this.addClass('vjs-hidden');
8383      } else {
8384        this.removeClass('vjs-hidden');
8385      }
8386    }
8387
8388    updateVisibility.call(this);
8389    this.on(player, 'loadstart', updateVisibility);
8390
8391    this.on(this.volumeBar, ['slideractive', 'focus'], function () {
8392      this.addClass('vjs-slider-active');
8393    });
8394
8395    this.on(this.volumeBar, ['sliderinactive', 'blur'], function () {
8396      this.removeClass('vjs-slider-active');
8397    });
8398
8399    this.on(this.volumeBar, ['focus'], function () {
8400      this.addClass('vjs-lock-showing');
8401    });
8402
8403    this.on(this.volumeBar, ['blur'], function () {
8404      this.removeClass('vjs-lock-showing');
8405    });
8406  }
8407
8408  /**
8409   * Allow sub components to stack CSS class names
8410   *
8411   * @return {String} The constructed class name
8412   * @method buildCSSClass
8413   */
8414
8415  VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
8416    var orientationClass = '';
8417    if (!!this.options_.vertical) {
8418      orientationClass = 'vjs-volume-menu-button-vertical';
8419    } else {
8420      orientationClass = 'vjs-volume-menu-button-horizontal';
8421    }
8422
8423    return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
8424  };
8425
8426  /**
8427   * Allow sub components to stack CSS class names
8428   *
8429   * @return {Popup} The volume popup button
8430   * @method createPopup
8431   */
8432
8433  VolumeMenuButton.prototype.createPopup = function createPopup() {
8434    var popup = new _popupPopupJs2['default'](this.player_, {
8435      contentElType: 'div'
8436    });
8437
8438    var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar);
8439
8440    popup.addChild(vb);
8441
8442    this.menuContent = popup;
8443    this.volumeBar = vb;
8444
8445    this.attachVolumeBarEvents();
8446
8447    return popup;
8448  };
8449
8450  /**
8451   * Handle click on volume popup and calls super
8452   *
8453   * @method handleClick
8454   */
8455
8456  VolumeMenuButton.prototype.handleClick = function handleClick() {
8457    _muteToggleJs2['default'].prototype.handleClick.call(this);
8458    _PopupButton.prototype.handleClick.call(this);
8459  };
8460
8461  VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
8462    this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
8463  };
8464
8465  VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
8466    this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
8467    this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
8468  };
8469
8470  VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
8471    this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
8472  };
8473
8474  return VolumeMenuButton;
8475})(_popupPopupButtonJs2['default']);
8476
8477VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update;
8478VolumeMenuButton.prototype.controlText_ = 'Mute';
8479
8480_componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
8481exports['default'] = VolumeMenuButton;
8482module.exports = exports['default'];
8483
8484},{"../component.js":67,"../popup/popup-button.js":115,"../popup/popup.js":116,"../utils/fn.js":145,"./mute-toggle.js":73,"./volume-control/volume-bar.js":99}],103:[function(_dereq_,module,exports){
8485/**
8486 * @file error-display.js
8487 */
8488'use strict';
8489
8490exports.__esModule = true;
8491
8492function _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; } }
8493
8494function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8495
8496function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8497
8498function _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, { c
8498onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8499
8500var _component = _dereq_('./component');
8501
8502var _component2 = _interopRequireDefault(_component);
8503
8504var _modalDialog = _dereq_('./modal-dialog');
8505
8506var _modalDialog2 = _interopRequireDefault(_modalDialog);
8507
8508var _utilsDom = _dereq_('./utils/dom');
8509
8510var Dom = _interopRequireWildcard(_utilsDom);
8511
8512var _utilsMergeOptions = _dereq_('./utils/merge-options');
8513
8514var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
8515
8516/**
8517 * Display that an error has occurred making the video unplayable.
8518 *
8519 * @extends ModalDialog
8520 * @class ErrorDisplay
8521 */
8522
8523var ErrorDisplay = (function (_ModalDialog) {
8524  _inherits(ErrorDisplay, _ModalDialog);
8525
8526  /**
8527   * Constructor for error display modal.
8528   *
8529   * @param  {Player} player
8530   * @param  {Object} [options]
8531   */
8532
8533  function ErrorDisplay(player, options) {
8534    _classCallCheck(this, ErrorDisplay);
8535
8536    _ModalDialog.call(this, player, options);
8537    this.on(player, 'error', this.open);
8538  }
8539
8540  /**
8541   * Include the old class for backward-compatibility.
8542   *
8543   * This can be removed in 6.0.
8544   *
8545   * @method buildCSSClass
8546   * @deprecated
8547   * @return {String}
8548   */
8549
8550  ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
8551    return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
8552  };
8553
8554  /**
8555   * Generates the modal content based on the player error.
8556   *
8557   * @return {String|Null}
8558   */
8559
8560  ErrorDisplay.prototype.content = function content() {
8561    var error = this.player().error();
8562    return error ? this.localize(error.message) : '';
8563  };
8564
8565  return ErrorDisplay;
8566})(_modalDialog2['default']);
8567
8568ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, {
8569  fillAlways: true,
8570  temporary: false,
8571  uncloseable: true
8572});
8573
8574_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
8575exports['default'] = ErrorDisplay;
8576module.exports = exports['default'];
8577
8578},{"./component":67,"./modal-dialog":112,"./utils/dom":143,"./utils/merge-options":149}],104:[function(_dereq_,module,exports){
8579/**
8580 * @file event-target.js
8581 */
8582'use strict';
8583
8584exports.__esModule = true;
8585
8586function _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; } }
8587
8588var _utilsEventsJs = _dereq_('./utils/events.js');
8589
8590var Events = _interopRequireWildcard(_utilsEventsJs);
8591
8592var EventTarget = function EventTarget() {};
8593
8594EventTarget.prototype.allowedEvents_ = {};
8595
8596EventTarget.prototype.on = function (type, fn) {
8597  // Remove the addEventListener alias before calling Events.on
8598  // so we don't get into an infinite type loop
8599  var ael = this.addEventListener;
8600  this.addEventListener = function () {};
8601  Events.on(this, type, fn);
8602  this.addEventListener = ael;
8603};
8604EventTarget.prototype.addEventListener = EventTarget.prototype.on;
8605
8606EventTarget.prototype.off = function (type, fn) {
8607  Events.off(this, type, fn);
8608};
8609EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
8610
8611EventTarget.prototype.one = function (type, fn) {
8612  // Remove the addEventListener alias before calling Events.on
8613  // so we don't get into an infinite type loop
8614  var ael = this.addEventListener;
8615  this.addEventListener = function () {};
8616  Events.one(this, type, fn);
8617  this.addEventListener = ael;
8618};
8619
8620EventTarget.prototype.trigger = function (event) {
8621  var type = event.type || event;
8622
8623  if (typeof event === 'string') {
8624    event = {
8625      type: type
8626    };
8627  }
8628  event = Events.fixEvent(event);
8629
8630  if (this.allowedEvents_[type] && this['on' + type]) {
8631    this['on' + type](event);
8632  }
8633
8634  Events.trigger(this, event);
8635};
8636// The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
8637EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
8638
8639exports['default'] = EventTarget;
8640module.exports = exports['default'];
8641
8642},{"./utils/events.js":144}],105:[function(_dereq_,module,exports){
8643'use strict';
8644
8645exports.__esModule = true;
8646
8647function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8648
8649var _utilsLog = _dereq_('./utils/log');
8650
8651var _utilsLog2 = _interopRequireDefault(_utilsLog);
8652
8653/*
8654 * @file extend.js
8655 *
8656 * A combination of node inherits and babel's inherits (after transpile).
8657 * Both work the same but node adds `super_` to the subClass
8658 * and Bable adds the superClass as __proto__. Both seem useful.
8659 */
8660var _inherits = function _inherits(subClass, superClass) {
8661  if (typeof superClass !== 'function' && superClass !== null) {
8662    throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
8663  }
8664
8665  subClass.prototype = Object.create(superClass && superClass.prototype, {
8666    constructor: {
8667      value: subClass,
8668      enumerable: false,
8669      writable: true,
8670      configurable: true
8671    }
8672  });
8673
8674  if (superClass) {
8675    // node
8676    subClass.super_ = superClass;
8677  }
8678};
8679
8680/*
8681 * Function for subclassing using the same inheritance that
8682 * videojs uses internally
8683 * ```js
8684 * var Button = videojs.getComponent('Button');
8685 * ```
8686 * ```js
8687 * var MyButton = videojs.extend(Button, {
8688 *   constructor: function(player, options) {
8689 *     Button.call(this, player, options);
8690 *   },
8691 *   onClick: function() {
8692 *     // doSomething
8693 *   }
8694 * });
8695 * ```
8696 */
8697var extendFn = function extendFn(superClass) {
8698  var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8699
8700  var subClass = function subClass() {
8701    superClass.apply(this, arguments);
8702  };
8703  var methods = {};
8704
8705  if (typeof subClassMethods === 'object') {
8706    if (typeof subClassMethods.init === 'function') {
8707      _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
8708      subClassMethods.constructor = subClassMethods.init;
8709    }
8710    if (subClassMethods.constructor !== Object.prototype.constructor) {
8711      subClass = subClassMethods.constructor;
8712    }
8713    methods = subClassMethods;
8714  } else if (typeof subClassMethods === 'function') {
8715    subClass = subClassMethods;
8716  }
8717
8718  _inherits(subClass, superClass);
8719
8720  // Extend subObj's prototype with functions and other properties from props
8721  for (var name in methods) {
8722    if (methods.hasOwnProperty(name)) {
8723      subClass.prototype[name] = methods[name];
8724    }
8725  }
8726
8727  return subClass;
8728};
8729
8730exports['default'] = extendFn;
8731module.exports = exports['default'];
8732
8733},{"./utils/log":148}],106:[function(_dereq_,module,exports){
8734/**
8735 * @file fullscreen-api.js
8736 */
8737'use strict';
8738
8739exports.__esModule = true;
8740
8741function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8742
8743var _globalDocument = _dereq_('global/document');
8744
8745var _globalDocument2 = _interopRequireDefault(_globalDocument);
8746
8747/*
8748 * Store the browser-specific methods for the fullscreen API
8749 * @type {Object|undefined}
8750 * @private
8751 */
8752var FullscreenApi = {};
8753
8754// browser API methods
8755// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
8756var apiMap = [
8757// Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
8758['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
8759// WebKit
8760['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
8761// Old WebKit (Safari 5.1)
8762['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
8763// Mozilla
8764['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
8765// Microsoft
8766['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
8767
8768var specApi = apiMap[0];
8769var browserApi = undefined;
8770
8771// determine the supported set of functions
8772for (var i = 0; i < apiMap.length; i++) {
8773  // check for exitFullscreen function
8774  if (apiMap[i][1] in _globalDocument2['default']) {
8775    browserApi = apiMap[i];
8776    break;
8777  }
8778}
8779
8780// map the browser API names to the spec API names
8781if (browserApi) {
8782  for (var i = 0; i < browserApi.length; i++) {
8783    FullscreenApi[specApi[i]] = browserApi[i];
8784  }
8785}
8786
8787exports['default'] = FullscreenApi;
8788module.exports = exports['default'];
8789
8790},{"global/document":1}],107:[function(_dereq_,module,exports){
8791/**
8792 * @file loading-spinner.js
8793 */
8794'use strict';
8795
8796exports.__esModule = true;
8797
8798function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8799
8800function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8801
8802function _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, { c
8802onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8803
8804var _component = _dereq_('./component');
8805
8806var _component2 = _interopRequireDefault(_component);
8807
8808/* Loading Spinner
8809================================================================================ */
8810/**
8811 * Loading spinner for waiting events
8812 *
8813 * @extends Component
8814 * @class LoadingSpinner
8815 */
8816
8817var LoadingSpinner = (function (_Component) {
8818  _inherits(LoadingSpinner, _Component);
8819
8820  function LoadingSpinner() {
8821    _classCallCheck(this, LoadingSpinner);
8822
8823    _Component.apply(this, arguments);
8824  }
8825
8826  /**
8827   * Create the component's DOM element
8828   *
8829   * @method createEl
8830   */
8831
8832  LoadingSpinner.prototype.createEl = function createEl() {
8833    return _Component.prototype.createEl.call(this, 'div', {
8834      className: 'vjs-loading-spinner',
8835      dir: 'ltr'
8836    });
8837  };
8838
8839  return LoadingSpinner;
8840})(_component2['default']);
8841
8842_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
8843exports['default'] = LoadingSpinner;
8844module.exports = exports['default'];
8845
8846},{"./component":67}],108:[function(_dereq_,module,exports){
8847/**
8848 * @file media-error.js
8849 */
8850'use strict';
8851
8852exports.__esModule = true;
8853
8854function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8855
8856var _objectAssign = _dereq_('object.assign');
8857
8858var _objectAssign2 = _interopRequireDefault(_objectAssign);
8859
8860/*
8861 * Custom MediaError to mimic the HTML5 MediaError
8862 *
8863 * @param {Number} code The media error code
8864 */
8865var MediaError = function MediaError(code) {
8866  if (typeof code === 'number') {
8867    this.code = code;
8868  } else if (typeof code === 'string') {
8869    // default code is zero, so this is a custom error
8870    this.message = code;
8871  } else if (typeof code === 'object') {
8872    // object
8873    _objectAssign2['default'](this, code);
8874  }
8875
8876  if (!this.message) {
8877    this.message = MediaError.defaultMessages[this.code] || '';
8878  }
8879};
8880
8881/*
8882 * The error code that refers two one of the defined
8883 * MediaError types
8884 *
8885 * @type {Number}
8886 */
8887MediaError.prototype.code = 0;
8888
8889/*
8890 * An optional message to be shown with the error.
8891 * Message is not part of the HTML5 video spec
8892 * but allows for more informative custom errors.
8893 *
8894 * @type {String}
8895 */
8896MediaError.prototype.message = '';
8897
8898/*
8899 * An optional status code that can be set by plugins
8900 * to allow even more detail about the error.
8901 * For example the HLS plugin might provide the specific
8902 * HTTP status code that was returned when the error
8903 * occurred, then allowing a custom error overlay
8904 * to display more information.
8905 *
8906 * @type {Array}
8907 */
8908MediaError.prototype.status = null;
8909
8910MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0
8911'MEDIA_ERR_ABORTED', // = 1
8912'MEDIA_ERR_NETWORK', // = 2
8913'MEDIA_ERR_DECODE', // = 3
8914'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4
8915'MEDIA_ERR_ENCRYPTED' // = 5
8916];
8917
8918MediaError.defaultMessages = {
8919  1: 'You aborted the media playback',
8920  2: 'A network error caused the media download to fail part-way.',
8921  3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
8922  4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
8923  5: 'The media is encrypted and we do not have the keys to decrypt it.'
8924};
8925
8926// Add types as properties on MediaError
8927// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
8928for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
8929  MediaError[MediaError.errorTypes[errNum]] = errNum;
8930  // values should be accessible on both the class and instance
8931  MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
8932}
8933
8934exports['default'] = MediaError;
8935module.exports = exports['default'];
8936
8937},{"object.assign":45}],109:[function(_dereq_,module,exports){
8938/**
8939 * @file menu-button.js
8940 */
8941'use strict';
8942
8943exports.__esModule = true;
8944
8945function _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; } }
8946
8947function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8948
8949function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8950
8951function _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; }
8952
8953var _clickableComponentJs = _dereq_('../clickable-component.js');
8954
8955var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
8956
8957var _componentJs = _dereq_('../component.js');
8958
8959var _componentJs2 = _interopRequireDefault(_componentJs);
8960
8961var _menuJs = _dereq_('./menu.js');
8962
8963var _menuJs2 = _interopRequireDefault(_menuJs);
8964
8965var _utilsDomJs = _dereq_('../utils/dom.js');
8966
8967var Dom = _interopRequireWildcard(_utilsDomJs);
8968
8969var _utilsFnJs = _dereq_('../utils/fn.js');
8970
8971var Fn = _interopRequireWildcard(_utilsFnJs);
8972
8973var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
8974
8975var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
8976
8977/**
8978 * A button class with a popup menu
8979 *
8980 * @param {Player|Object} player
8981 * @param {Object=} options
8982 * @extends Button
8983 * @class MenuButton
8984 */
8985
8986var MenuButton = (function (_ClickableComponent) {
8987  _inherits(MenuButton, _ClickableComponent);
8988
8989  function MenuButton(player) {
8990    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8991
8992    _classCallCheck(this, MenuButton);
8993
8994    _ClickableComponent.call(this, player, options);
8995
8996    this.update();
8997
8998    this.enabled_ = true;
8999
9000    this.el_.setAttribute('aria-haspopup', 'true');
9001    this.el_.setAttribute('role', 'menuitem');
9002    this.on('keydown', this.handleSubmenuKeyPress);
9003  }
9004
9005  /**
9006   * Update menu
9007   *
9008   * @method update
9009   */
9010
9011  MenuButton.prototype.update = function update() {
9012    var menu = this.createMenu();
9013
9014    if (this.menu) {
9015      this.removeChild(this.menu);
9016    }
9017
9018    this.menu = menu;
9019    this.addChild(menu);
9020
9021    /**
9022     * Track the state of the menu button
9023     *
9024     * @type {Boolean}
9025     * @private
9026     */
9027    this.buttonPressed_ = false;
9028    this.el_.setAttribute('aria-expanded', 'false');
9029
9030    if (this.items && this.items.length === 0) {
9031      this.hide();
9032    } else if (this.items && this.items.length > 1) {
9033      this.show();
9034    }
9035  };
9036
9037  /**
9038   * Create menu
9039   *
9040   * @return {Menu} The constructed menu
9041   * @method createMenu
9042   */
9043
9044  MenuButton.prototype.createMenu = function createMenu() {
9045    var menu = new _menuJs2['default'](this.player_);
9046
9047    // Add a title list item to the top
9048    if (this.options_.title) {
9049      var title = Dom.createEl('li', {
9050        className: 'vjs-menu-title',
9051        innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title),
9052        tabIndex: -1
9053      });
9054      menu.children_.unshift(title);
9055      Dom.insertElFirst(title, menu.contentEl());
9056    }
9057
9058    this.items = this['createItems']();
9059
9060    if (this.items) {
9061      // Add menu items to the menu
9062      for (var i = 0; i < this.items.length; i++) {
9063        menu.addItem(this.items[i]);
9064      }
9065    }
9066
9067    return menu;
9068  };
9069
9070  /**
9071   * Create the list of menu items. Specific to each subclass.
9072   *
9073   * @method createItems
9074   */
9075
9076  MenuButton.prototype.createItems = function createItems() {};
9077
9078  /**
9079   * Create the component's DOM element
9080   *
9081   * @return {Element}
9082   * @method createEl
9083   */
9084
9085  MenuButton.prototype.createEl = function createEl() {
9086    return _ClickableComponent.prototype.createEl.call(this, 'div', {
9087      className: this.buildCSSClass()
9088    });
9089  };
9090
9091  /**
9092   * Allow sub components to stack CSS class names
9093   *
9094   * @return {String} The constructed class name
9095   * @method buildCSSClass
9096   */
9097
9098  MenuButton.prototype.buildCSSClass = function buildCSSClass() {
9099    var menuButtonClass = 'vjs-menu-button';
9100
9101    // If the inline option is passed, we want to use different styles altogether.
9102    if (this.options_.inline === true) {
9103      menuButtonClass += '-inline';
9104    } else {
9105      menuButtonClass += '-popup';
9106    }
9107
9108    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
9109  };
9110
9111  /**
9112   * When you click the button it adds focus, which
9113   * will show the menu indefinitely.
9114   * So we'll remove focus when the mouse leaves the button.
9115   * Focus is needed for tab navigation.
9116   * Allow sub components to stack CSS class names
9117   *
9118   * @method handleClick
9119   */
9120
9121  MenuButton.prototype.handleClick = function handleClick() {
9122    this.one('mouseout', Fn.bind(this, function () {
9123      this.menu.unlockShowing();
9124      this.el_.blur();
9125    }));
9126    if (this.buttonPressed_) {
9127      this.unpressButton();
9128    } else {
9129      this.pressButton();
9130    }
9131  };
9132
9133  /**
9134   * Handle key press on menu
9135   *
9136   * @param {Object} event Key press event
9137   * @method handleKeyPress
9138   */
9139
9140  MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
9141
9142    // Escape (27) key or Tab (9) key unpress the 'button'
9143    if (event.which === 27 || event.which === 9) {
9144      if (this.buttonPressed_) {
9145        this.unpressButton();
9146      }
9147      // Don't preventDefault for Tab key - we still want to lose focus
9148      if (event.which !== 9) {
9149        event.preventDefault();
9150      }
9151      // Up (38) key or Down (40) key press the 'button'
9152    } else if (event.which === 38 || event.which === 40) {
9153        if (!this.buttonPressed_) {
9154          this.pressButton();
9155          event.preventDefault();
9156        }
9157      } else {
9158        _ClickableComponent.prototype.handleKeyPress.call(this, event);
9159      }
9160  };
9161
9162  /**
9163   * Handle key press on submenu
9164   *
9165   * @param {Object} event Key press event
9166   * @method handleSubmenuKeyPress
9167   */
9168
9169  MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
9170
9171    // Escape (27) key or Tab (9) key unpress the 'button'
9172    if (event.which === 27 || event.which === 9) {
9173      if (this.buttonPressed_) {
9174        this.unpressButton();
9175      }
9176      // Don't preventDefault for Tab key - we still want to lose focus
9177      if (event.which !== 9) {
9178        event.preventDefault();
9179      }
9180    }
9181  };
9182
9183  /**
9184   * Makes changes based on button pressed
9185   *
9186   * @method pressButton
9187   */
9188
9189  MenuButton.prototype.pressButton = function pressButton() {
9190    if (this.enabled_) {
9191      this.buttonPressed_ = true;
9192      this.menu.lockShowing();
9193      this.el_.setAttribute('aria-expanded', 'true');
9194      this.menu.focus(); // set the focus into the submenu
9195    }
9196  };
9197
9198  /**
9199   * Makes changes based on button unpressed
9200   *
9201   * @method unpressButton
9202   */
9203
9204  MenuButton.prototype.unpressButton = function unpressButton() {
9205    if (this.enabled_) {
9206      this.buttonPressed_ = false;
9207      this.menu.unlockShowing();
9208      this.el_.setAttribute('aria-expanded', 'false');
9209      this.el_.focus(); // Set focus back to this menu button
9210    }
9211  };
9212
9213  /**
9214   * Disable the menu button
9215   *
9216   * @return {Component}
9217   * @method disable
9218   */
9219
9220  MenuButton.prototype.disable = function disable() {
9221    // Unpress, but don't force focus on this button
9222    this.buttonPressed_ = false;
9223    this.menu.unlockShowing();
9224    this.el_.setAttribute('aria-expanded', 'false');
9225
9226    this.enabled_ = false;
9227
9228    return _ClickableComponent.prototype.disable.call(this);
9229  };
9230
9231  /**
9232   * Enable the menu button
9233   *
9234   * @return {Component}
9235   * @method disable
9236   */
9237
9238  MenuButton.prototype.enable = function enable() {
9239    this.enabled_ = true;
9240
9241    return _ClickableComponent.prototype.enable.call(this);
9242  };
9243
9244  return MenuButton;
9245})(_clickableComponentJs2['default']);
9246
9247_componentJs2['default'].registerComponent('MenuButton', MenuButton);
9248exports['default'] = MenuButton;
9249module.exports = exports['default'];
9250
9251},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/to-title-case.js":152,"./menu.js":111}],110:[function(_dereq_,module,exports){
9252/**
9253 * @file menu-item.js
9254 */
9255'use strict';
9256
9257exports.__esModule = true;
9258
9259function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
9260
9261function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
9262
9263function _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; }
9264
9265var _clickableComponentJs = _dereq_('../clickable-component.js');
9266
9267var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
9268
9269var _componentJs = _dereq_('../component.js');
9270
9271var _componentJs2 = _interopRequireDefault(_componentJs);
9272
9273var _objectAssign = _dereq_('object.assign');
9274
9275var _objectAssign2 = _interopRequireDefault(_objectAssign);
9276
9277/**
9278 * The component for a menu item. `<li>`
9279 *
9280 * @param {Player|Object} player
9281 * @param {Object=} options
9282 * @extends Button
9283 * @class MenuItem
9284 */
9285
9286var MenuItem = (function (_ClickableComponent) {
9287  _inherits(MenuItem, _ClickableComponent);
9288
9289  function MenuItem(player, options) {
9290    _classCallCheck(this, MenuItem);
9291
9292    _ClickableComponent.call(this, player, options);
9293
9294    this.selectable = options['selectable'];
9295
9296    this.selected(options['selected']);
9297
9298    if (this.selectable) {
9299      // TODO: May need to be either menuitemcheckbox or menuitemradio,
9300      //       and may need logical grouping of menu items.
9301      this.el_.setAttribute('role', 'menuitemcheckbox');
9302    } else {
9303      this.el_.setAttribute('role', 'menuitem');
9304    }
9305  }
9306
9307  /**
9308   * Create the component's DOM element
9309   *
9310   * @param {String=} type Desc
9311   * @param {Object=} props Desc
9312   * @return {Element}
9313   * @method createEl
9314   */
9315
9316  MenuItem.prototype.createEl = function createEl(type, props, attrs) {
9317    return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({
9318      className: 'vjs-menu-item',
9319      innerHTML: this.localize(this.options_['label']),
9320      tabIndex: -1
9321    }, props), attrs);
9322  };
9323
9324  /**
9325   * Handle a click on the menu item, and set it to selected
9326   *
9327   * @method handleClick
9328   */
9329
9330  MenuItem.prototype.handleClick = function handleClick() {
9331    this.selected(true);
9332  };
9333
9334  /**
9335   * Set this menu item as selected or not
9336   *
9337   * @param  {Boolean} selected
9338   * @method selected
9339   */
9340
9341  MenuItem.prototype.selected = function selected(_selected) {
9342    if (this.selectable) {
9343      if (_selected) {
9344        this.addClass('vjs-selected');
9345        this.el_.setAttribute('aria-checked', 'true');
9346        // aria-checked isn't fully supported by browsers/screen readers,
9347        // so indicate selected state to screen reader in the control text.
9348        this.controlText(', selected');
9349      } else {
9350        this.removeClass('vjs-selected');
9351        this.el_.setAttribute('aria-checked', 'false');
9352        // Indicate un-selected state to screen reader
9353        // Note that a space clears out the selected state text
9354        this.controlText(' ');
9355      }
9356    }
9357  };
9358
9359  return MenuItem;
9360})(_clickableComponentJs2['default']);
9361
9362_componentJs2['default'].registerComponent('MenuItem', MenuItem);
9363exports['default'] = MenuItem;
9364module.exports = exports['default'];
9365
9366},{"../clickable-component.js":65,"../component.js":67,"object.assign":45}],111:[function(_dereq_,module,exports){
9367/**
9368 * @file menu.js
9369 */
9370'use strict';
9371
9372exports.__esModule = true;
9373
9374function _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; } }
9375
9376function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
9377
9378function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
9379
9380function _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; }
9381
9382var _componentJs = _dereq_('../component.js');
9383
9384var _componentJs2 = _interopRequireDefault(_componentJs);
9385
9386var _utilsDomJs = _dereq_('../utils/dom.js');
9387
9388var Dom = _interopRequireWildcard(_utilsDomJs);
9389
9390var _utilsFnJs = _dereq_('../utils/fn.js');
9391
9392var Fn = _interopRequireWildcard(_utilsFnJs);
9393
9394var _utilsEventsJs = _dereq_('../utils/events.js');
9395
9396var Events = _interopRequireWildcard(_utilsEventsJs);
9397
9398/**
9399 * The Menu component is used to build pop up menus, including subtitle and
9400 * captions selection menus.
9401 *
9402 * @extends Component
9403 * @class Menu
9404 */
9405
9406var Menu = (function (_Component) {
9407  _inherits(Menu, _Component);
9408
9409  function Menu(player, options) {
9410    _classCallCheck(this, Menu);
9411
9412    _Component.call(this, player, options);
9413
9414    this.focusedChild_ = -1;
9415
9416    this.on('keydown', this.handleKeyPress);
9417  }
9418
9419  /**
9420   * Add a menu item to the menu
9421   *
9422   * @param {Object|String} component Component or component type to add
9423   * @method addItem
9424   */
9425
9426  Menu.prototype.addItem = function addItem(component) {
9427    this.addChild(component);
9428    component.on('click', Fn.bind(this, function () {
9429      this.unlockShowing();
9430      //TODO: Need to set keyboard focus back to the menuButton
9431    }));
9432  };
9433
9434  /**
9435   * Create the component's DOM element
9436   *
9437   * @return {Element}
9438   * @method createEl
9439   */
9440
9441  Menu.prototype.createEl = function createEl() {
9442    var contentElType = this.options_.contentElType || 'ul';
9443    this.contentEl_ = Dom.createEl(contentElType, {
9444      className: 'vjs-menu-content'
9445    });
9446    this.contentEl_.setAttribute('role', 'menu');
9447    var el = _Component.prototype.createEl.call(this, 'div', {
9448      append: this.contentEl_,
9449      className: 'vjs-menu'
9450    });
9451    el.setAttribute('role', 'presentation');
9452    el.appendChild(this.contentEl_);
9453
9454    // Prevent clicks from bubbling up. Needed for Menu Buttons,
9455    // where a click on the parent is significant
9456    Events.on(el, 'click', function (event) {
9457      event.preventDefault();
9458      event.stopImmediatePropagation();
9459    });
9460
9461    return el;
9462  };
9463
9464  /**
9465   * Handle key press for menu
9466   *
9467   * @param {Object} event Event object
9468   * @method handleKeyPress
9469   */
9470
9471  Menu.prototype.handleKeyPress = function handleKeyPress(event) {
9472    if (event.which === 37 || event.which === 40) {
9473      // Left and Down Arrows
9474      event.preventDefault();
9475      this.stepForward();
9476    } else if (event.which === 38 || event.which === 39) {
9477      // Up and Right Arrows
9478      event.preventDefault();
9479      this.stepBack();
9480    }
9481  };
9482
9483  /**
9484   * Move to next (lower) menu item for keyboard users
9485   *
9486   * @method stepForward
9487   */
9488
9489  Menu.prototype.stepForward = function stepForward() {
9490    var stepChild = 0;
9491
9492    if (this.focusedChild_ !== undefined) {
9493      stepChild = this.focusedChild_ + 1;
9494    }
9495    this.focus(stepChild);
9496  };
9497
9498  /**
9499   * Move to previous (higher) menu item for keyboard users
9500   *
9501   * @method stepBack
9502   */
9503
9504  Menu.prototype.stepBack = function stepBack() {
9505    var stepChild = 0;
9506
9507    if (this.focusedChild_ !== undefined) {
9508      stepChild = this.focusedChild_ - 1;
9509    }
9510    this.focus(stepChild);
9511  };
9512
9513  /**
9514   * Set focus on a menu item in the menu
9515   *
9516   * @param {Object|String} item Index of child item set focus on
9517   * @method focus
9518   */
9519
9520  Menu.prototype.focus = function focus() {
9521    var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
9522
9523    var children = this.children().slice();
9524    var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
9525
9526    if (haveTitle) {
9527      children.shift();
9528    }
9529
9530    if (children.length > 0) {
9531      if (item < 0) {
9532        item = 0;
9533      } else if (item >= children.length) {
9534        item = children.length - 1;
9535      }
9536
9537      this.focusedChild_ = item;
9538
9539      children[item].el_.focus();
9540    }
9541  };
9542
9543  return Menu;
9544})(_componentJs2['default']);
9545
9546_componentJs2['default'].registerComponent('Menu', Menu);
9547exports['default'] = Menu;
9548module.exports = exports['default'];
9549
9550},{"../component.js":67,"../utils/dom.js":143,"../utils/events.js":144,"../utils/fn.js":145}],112:[function(_dereq_,module,exports){
9551/**
9552 * @file modal-dialog.js
9553 */
9554'use strict';
9555
9556exports.__esModule = true;
9557
9558function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
9559
9560function _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; } }
9561
9562function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
9563
9564function _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; }
9565
9566var _utilsDom = _dereq_('./utils/dom');
9567
9568var Dom = _interopRequireWildcard(_utilsDom);
9569
9570var _utilsFn = _dereq_('./utils/fn');
9571
9572var Fn = _interopRequireWildcard(_utilsFn);
9573
9574var _utilsLog = _dereq_('./utils/log');
9575
9576var _utilsLog2 = _interopRequireDefault(_utilsLog);
9577
9578var _component = _dereq_('./component');
9579
9580var _component2 = _interopRequireDefault(_component);
9581
9582var _closeButton = _dereq_('./close-button');
9583
9584var _closeButton2 = _interopRequireDefault(_closeButton);
9585
9586var MODAL_CLASS_NAME = 'vjs-modal-dialog';
9587var ESC = 27;
9588
9589/**
9590 * The `ModalDialog` displays over the video and its controls, which blocks
9591 * interaction with the player until it is closed.
9592 *
9593 * Modal dialogs include a "Close" button and will close when that button
9594 * is activated - or when ESC is pressed anywhere.
9595 *
9596 * @extends Component
9597 * @class ModalDialog
9598 */
9599
9600var ModalDialog = (function (_Component) {
9601  _inherits(ModalDialog, _Component);
9602
9603  /**
9604   * Constructor for modals.
9605   *
9606   * @param  {Player} player
9607   * @param  {Object} [options]
9608   * @param  {Mixed} [options.content=undefined]
9609   *         Provide customized content for this modal.
9610   *
9611   * @param  {String} [options.description]
9612   *         A text description for the modal, primarily for accessibility.
9613   *
9614   * @param  {Boolean} [options.fillAlways=false]
9615   *         Normally, modals are automatically filled only the first time
9616   *         they open. This tells the modal to refresh its content
9617   *         every time it opens.
9618   *
9619   * @param  {String} [options.label]
9620   *         A text label for the modal, primarily for accessibility.
9621   *
9622   * @param  {Boolean} [options.temporary=true]
9623   *         If `true`, the modal can only be opened once; it will be
9624   *         disposed as soon as it's closed.
9625   *
9626   * @param  {Boolean} [options.uncloseable=false]
9627   *         If `true`, the user will not be able to close the modal
9628   *         through the UI in the normal ways. Programmatic closing is
9629   *         still possible.
9630   *
9631   */
9632
9633  function ModalDialog(player, options) {
9634    _classCallCheck(this, ModalDialog);
9635
9636    _Component.call(this, player, options);
9637    this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;
9638
9639    this.closeable(!this.options_.uncloseable);
9640    this.content(this.options_.content);
9641
9642    // Make sure the contentEl is defined AFTER any children are initialized
9643    // because we only want the contents of the modal in the contentEl
9644    // (not the UI elements like the close button).
9645    this.contentEl_ = Dom.createEl('div', {
9646      className: MODAL_CLASS_NAME + '-content'
9647    }, {
9648      role: 'document'
9649    });
9650
9651    this.descEl_ = Dom.createEl('p', {
9652      className: MODAL_CLASS_NAME + '-description vjs-offscreen',
9653      id: this.el().getAttribute('aria-describedby')
9654    });
9655
9656    Dom.textContent(this.descEl_, this.description());
9657    this.el_.appendChild(this.descEl_);
9658    this.el_.appendChild(this.contentEl_);
9659  }
9660
9661  /*
9662   * Modal dialog default options.
9663   *
9664   * @type {Object}
9665   * @private
9666   */
9667
9668  /**
9669   * Create the modal's DOM element
9670   *
9671   * @method createEl
9672   * @return {Element}
9673   */
9674
9675  ModalDialog.prototype.createEl = function createEl() {
9676    return _Component.prototype.createEl.call(this, 'div', {
9677      className: this.buildCSSClass(),
9678      tabIndex: -1
9679    }, {
9680      'aria-describedby': this.id() + '_description',
9681      'aria-hidden': 'true',
9682      'aria-label': this.label(),
9683      role: 'dialog'
9684    });
9685  };
9686
9687  /**
9688   * Build the modal's CSS class.
9689   *
9690   * @method buildCSSClass
9691   * @return {String}
9692   */
9693
9694  ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
9695    return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
9696  };
9697
9698  /**
9699   * Handles key presses on the document, looking for ESC, which closes
9700   * the modal.
9701   *
9702   * @method handleKeyPress
9703   * @param  {Event} e
9704   */
9705
9706  ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
9707    if (e.which === ESC && this.closeable()) {
9708      this.close();
9709    }
9710  };
9711
9712  /**
9713   * Returns the label string for this modal. Primarily used for accessibility.
9714   *
9715   * @return {String}
9716   */
9717
9718  ModalDialog.prototype.label = function label() {
9719    return this.options_.label || this.localize('Modal Window');
9720  };
9721
9722  /**
9723   * Returns the description string for this modal. Primarily used for
9724   * accessibility.
9725   *
9726   * @return {String}
9727   */
9728
9729  ModalDialog.prototype.description = function description() {
9730    var desc = this.options_.description || this.localize('This is a modal window.');
9731
9732    // Append a universal closeability message if the modal is closeable.
9733    if (this.closeable()) {
9734      desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
9735    }
9736
9737    return desc;
9738  };
9739
9740  /**
9741   * Opens the modal.
9742   *
9743   * @method open
9744   * @return {ModalDialog}
9745   */
9746
9747  ModalDialog.prototype.open = function open() {
9748    if (!this.opened_) {
9749      var player = this.player();
9750
9751      this.trigger('beforemodalopen');
9752      this.opened_ = true;
9753
9754      // Fill content if the modal has never opened before and
9755      // never been filled.
9756      if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
9757        this.fill();
9758      }
9759
9760      // If the player was playing, pause it and take note of its previously
9761      // playing state.
9762      this.wasPlaying_ = !player.paused();
9763
9764      if (this.wasPlaying_) {
9765        player.pause();
9766      }
9767
9768      if (this.closeable()) {
9769        this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
9770      }
9771
9772      player.controls(false);
9773      this.show();
9774      this.el().setAttribute('aria-hidden', 'false');
9775      this.trigger('modalopen');
9776      this.hasBeenOpened_ = true;
9777    }
9778    return this;
9779  };
9780
9781  /**
9782   * Whether or not the modal is opened currently.
9783   *
9784   * @method opened
9785   * @param  {Boolean} [value]
9786   *         If given, it will open (`true`) or close (`false`) the modal.
9787   *
9788   * @return {Boolean}
9789   */
9790
9791  ModalDialog.prototype.opened = function opened(value) {
9792    if (typeof value === 'boolean') {
9793      this[value ? 'open' : 'close']();
9794    }
9795    return this.opened_;
9796  };
9797
9798  /**
9799   * Closes the modal.
9800   *
9801   * @method close
9802   * @return {ModalDialog}
9803   */
9804
9805  ModalDialog.prototype.close = function close() {
9806    if (this.opened_) {
9807      var player = this.player();
9808
9809      this.trigger('beforemodalclose');
9810      this.opened_ = false;
9811
9812      if (this.wasPlaying_) {
9813        player.play();
9814      }
9815
9816      if (this.closeable()) {
9817        this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
9818      }
9819
9820      player.controls(true);
9821      this.hide();
9822      this.el().setAttribute('aria-hidden', 'true');
9823      this.trigger('modalclose');
9824
9825      if (this.options_.temporary) {
9826        this.dispose();
9827      }
9828    }
9829    return this;
9830  };
9831
9832  /**
9833   * Whether or not the modal is closeable via the UI.
9834   *
9835   * @method closeable
9836   * @param  {Boolean} [value]
9837   *         If given as a Boolean, it will set the `closeable` option.
9838   *
9839   * @return {Boolean}
9840   */
9841
9842  ModalDialog.prototype.closeable = function closeable(value) {
9843    if (typeof value === 'boolean') {
9844      var closeable = this.closeable_ = !!value;
9845      var _close = this.getChild('closeButton');
9846
9847      // If this is being made closeable and has no close button, add one.
9848      if (closeable && !_close) {
9849
9850        // The close button should be a child of the modal - not its
9851        // content element, so temporarily change the content element.
9852        var temp = this.contentEl_;
9853        this.contentEl_ = this.el_;
9854        _close = this.addChild('closeButton');
9855        this.contentEl_ = temp;
9856        this.on(_close, 'close', this.close);
9857      }
9858
9859      // If this is being made uncloseable and has a close button, remove it.
9860      if (!closeable && _close) {
9861        this.off(_close, 'close', this.close);
9862        this.removeChild(_close);
9863        _close.dispose();
9864      }
9865    }
9866    return this.closeable_;
9867  };
9868
9869  /**
9870   * Fill the modal's content element with the modal's "content" option.
9871   *
9872   * The content element will be emptied before this change takes place.
9873   *
9874   * @method fill
9875   * @return {ModalDialog}
9876   */
9877
9878  ModalDialog.prototype.fill = function fill() {
9879    return this.fillWith(this.content());
9880  };
9881
9882  /**
9883   * Fill the modal's content element with arbitrary content.
9884   *
9885   * The content element will be emptied before this change takes place.
9886   *
9887   * @method fillWith
9888   * @param  {Mixed} [content]
9889   *         The same rules apply to this as apply to the `content` option.
9890   *
9891   * @return {ModalDialog}
9892   */
9893
9894  ModalDialog.prototype.fillWith = function fillWith(content) {
9895    var contentEl = this.contentEl();
9896    var parentEl = contentEl.parentNode;
9897    var nextSiblingEl = contentEl.nextSibling;
9898
9899    this.trigger('beforemodalfill');
9900    this.hasBeenFilled_ = true;
9901
9902    // Detach the content element from the DOM before performing
9903    // manipulation to avoid modifying the live DOM multiple times.
9904    parentEl.removeChild(contentEl);
9905    this.empty();
9906    Dom.insertContent(contentEl, content);
9907    this.trigger('modalfill');
9908
9909    // Re-inject the re-filled content element.
9910    if (nextSiblingEl) {
9911      parentEl.insertBefore(contentEl, nextSiblingEl);
9912    } else {
9913      parentEl.appendChild(contentEl);
9914    }
9915
9916    return this;
9917  };
9918
9919  /**
9920   * Empties the content element.
9921   *
9922   * This happens automatically anytime the modal is filled.
9923   *
9924   * @method empty
9925   * @return {ModalDialog}
9926   */
9927
9928  ModalDialog.prototype.empty = function empty() {
9929    this.trigger('beforemodalempty');
9930    Dom.emptyEl(this.contentEl());
9931    this.trigger('modalempty');
9932    return this;
9933  };
9934
9935  /**
9936   * Gets or sets the modal content, which gets normalized before being
9937   * rendered into the DOM.
9938   *
9939   * This does not update the DOM or fill the modal, but it is called during
9940   * that process.
9941   *
9942   * @method content
9943   * @param  {Mixed} [value]
9944   *         If defined, sets the internal content value to be used on the
9945   *         next call(s) to `fill`. This value is normalized before being
9946   *         inserted. To "clear" the internal content value, pass `null`.
9947   *
9948   * @return {Mixed}
9949   */
9950
9951  ModalDialog.prototype.content = function content(value) {
9952    if (typeof value !== 'undefined') {
9953      this.content_ = value;
9954    }
9955    return this.content_;
9956  };
9957
9958  return ModalDialog;
9959})(_component2['default']);
9960
9961ModalDialog.prototype.options_ = {
9962  temporary: true
9963};
9964
9965_component2['default'].registerComponent('ModalDialog', ModalDialog);
9966exports['default'] = ModalDialog;
9967module.exports = exports['default'];
9968
9969},{"./close-button":66,"./component":67,"./utils/dom":143,"./utils/fn":145,"./utils/log":148}],113:[function(_dereq_,module,exports){
9970/**
9971 * @file player.js
9972 */
9973// Subclasses Component
9974'use strict';
9975
9976exports.__esModule = true;
9977
9978function _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; } }
9979
9980function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
9981
9982function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
9983
9984function _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; }
9985
9986var _componentJs = _dereq_('./component.js');
9987
9988var _componentJs2 = _interopRequireDefault(_componentJs);
9989
9990var _globalDocument = _dereq_('global/document');
9991
9992var _globalDocument2 = _interopRequireDefault(_globalDocument);
9993
9994var _globalWindow = _dereq_('global/window');
9995
9996var _globalWindow2 = _interopRequireDefault(_globalWindow);
9997
9998var _utilsEventsJs = _dereq_('./utils/events.js');
9999
10000var Events = _interopRequireWildcard(_utilsEventsJs);
10001
10002var _utilsDomJs = _dereq_('./utils/dom.js');
10003
10004var Dom = _interopRequireWildcard(_utilsDomJs);
10005
10006var _utilsFnJs = _dereq_('./utils/fn.js');
10007
10008var Fn = _interopRequireWildcard(_utilsFnJs);
10009
10010var _utilsGuidJs = _dereq_('./utils/guid.js');
10011
10012var Guid = _interopRequireWildcard(_utilsGuidJs);
10013
10014var _utilsBrowserJs = _dereq_('./utils/browser.js');
10015
10016var browser = _interopRequireWildcard(_utilsBrowserJs);
10017
10018var _utilsLogJs = _dereq_('./utils/log.js');
10019
10020var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
10021
10022var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
10023
10024var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
10025
10026var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
10027
10028var _utilsBufferJs = _dereq_('./utils/buffer.js');
10029
10030var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
10031
10032var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
10033
10034var _fullscreenApiJs = _dereq_('./fullscreen-api.js');
10035
10036var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs);
10037
10038var _mediaErrorJs = _dereq_('./media-error.js');
10039
10040var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
10041
10042var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
10043
10044var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
10045
10046var _objectAssign = _dereq_('object.assign');
10047
10048var _objectAssign2 = _interopRequireDefault(_objectAssign);
10049
10050var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
10051
10052var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
10053
10054var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js');
10055
10056var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs);
10057
10058var _tracksAudioTrackListJs = _dereq_('./tracks/audio-track-list.js');
10059
10060var _tracksAudioTrackListJs2 = _interopRequireDefault(_tracksAudioTrackListJs);
10061
10062var _tracksVideoTrackListJs = _dereq_('./tracks/video-track-list.js');
10063
10064var _tracksVideoTrackListJs2 = _interopRequireDefault(_tracksVideoTrackListJs);
10065
10066// Include required child components (importing also registers them)
10067
10068var _techLoaderJs = _dereq_('./tech/loader.js');
10069
10070var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs);
10071
10072var _posterImageJs = _dereq_('./poster-image.js');
10073
10074var _posterImageJs2 = _interopRequireDefault(_posterImageJs);
10075
10076var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js');
10077
10078var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs);
10079
10080var _loadingSpinnerJs = _dereq_('./loading-spinner.js');
10081
10082var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs);
10083
10084var _bigPlayButtonJs = _dereq_('./big-play-button.js');
10085
10086var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs);
10087
10088var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js');
10089
10090var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs);
10091
10092var _errorDisplayJs = _dereq_('./error-display.js');
10093
10094var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs);
10095
10096var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js');
10097
10098var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs);
10099
10100var _modalDialog = _dereq_('./modal-dialog');
10101
10102var _modalDialog2 = _interopRequireDefault(_modalDialog);
10103
10104// Require html5 tech, at least for disposing the original video tag
10105
10106var _techTechJs = _dereq_('./tech/tech.js');
10107
10108var _techTechJs2 = _interopRequireDefault(_techTechJs);
10109
10110var _techHtml5Js = _dereq_('./tech/html5.js');
10111
10112var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
10113
10114/**
10115 * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video.
10116 * ```js
10117 * var myPlayer = videojs('example_video_1');
10118 * ```
10119 * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready.
10120 * ```html
10121 * <video id="example_video_1" data-setup='{}' controls>
10122 *   <source src="my-source.mp4" type="video/mp4">
10123 * </video>
10124 * ```
10125 * After an instance has been created it can be accessed globally using `Video('example_video_1')`.
10126 *
10127 * @param {Element}
10127 tag        The original video tag used for configuring options
10128 * @param {Object=} options    Object of option names and values
10129 * @param {Function=} ready    Ready callback function
10130 * @extends Component
10131 * @class Player
10132 */
10133
10134var Player = (function (_Component) {
10135  _inherits(Player, _Component);
10136
10137  /**
10138   * player's constructor function
10139   *
10140   * @constructs
10141   * @method init
10142   * @param {Element} tag        The original video tag used for configuring options
10143   * @param {Object=} options    Player options
10144   * @param {Function=} ready    Ready callback function
10145   */
10146
10147  function Player(tag, options, ready) {
10148    var _this = this;
10149
10150    _classCallCheck(this, Player);
10151
10152    // Make sure tag ID exists
10153    tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
10154
10155    // Set Options
10156    // The options argument overrides options set in the video tag
10157    // which overrides globally set options.
10158    // This latter part coincides with the load order
10159    // (tag must exist before Player)
10160    options = _objectAssign2['default'](Player.getTagSettings(tag), options);
10161
10162    // Delay the initialization of children because we need to set up
10163    // player properties first, and can't use `this` before `super()`
10164    options.initChildren = false;
10165
10166    // Same with creating the element
10167    options.createEl = false;
10168
10169    // we don't want the player to report touch activity on itself
10170    // see enableTouchActivity in Component
10171    options.reportTouchActivity = false;
10172
10173    // Run base component initializing with new options
10174    _Component.call(this, null, options, ready);
10175
10176    // if the global option object was accidentally blown away by
10177    // someone, bail early with an informative error
10178    if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) {
10179      throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
10180    }
10181
10182    this.tag = tag; // Store the original tag used to set options
10183
10184    // Store the tag attributes used to restore html5 element
10185    this.tagAttributes = tag && Dom.getElAttributes(tag);
10186
10187    // Update current language
10188    this.language(this.options_.language);
10189
10190    // Update Supported Languages
10191    if (options.languages) {
10192      (function () {
10193        // Normalise player option languages to lowercase
10194        var languagesToLower = {};
10195
10196        Object.getOwnPropertyNames(options.languages).forEach(function (name) {
10197          languagesToLower[name.toLowerCase()] = options.languages[name];
10198        });
10199        _this.languages_ = languagesToLower;
10200      })();
10201    } else {
10202      this.languages_ = Player.prototype.options_.languages;
10203    }
10204
10205    // Cache for video property values.
10206    this.cache_ = {};
10207
10208    // Set poster
10209    this.poster_ = options.poster || '';
10210
10211    // Set controls
10212    this.controls_ = !!options.controls;
10213
10214    // Original tag settings stored in options
10215    // now remove immediately so native controls don't flash.
10216    // May be turned back on by HTML5 tech if nativeControlsForTouch is true
10217    tag.controls = false;
10218
10219    /*
10220     * Store the internal state of scrubbing
10221     *
10222     * @private
10223     * @return {Boolean} True if the user is scrubbing
10224     */
10225    this.scrubbing_ = false;
10226
10227    this.el_ = this.createEl();
10228
10229    // We also want to pass the original player options to each component and plugin
10230    // as well so they don't need to reach back into the player for options later.
10231    // We also need to do another copy of this.options_ so we don't end up with
10232    // an infinite loop.
10233    var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_);
10234
10235    // Load plugins
10236    if (options.plugins) {
10237      (function () {
10238        var plugins = options.plugins;
10239
10240        Object.getOwnPropertyNames(plugins).forEach(function (name) {
10241          if (typeof this[name] === 'function') {
10242            this[name](plugins[name]);
10243          } else {
10244            _utilsLogJs2['default'].error('Unable to find plugin:', name);
10245          }
10246        }, _this);
10247      })();
10248    }
10249
10250    this.options_.playerOptions = playerOptionsCopy;
10251
10252    this.initChildren();
10253
10254    // Set isAudio based on whether or not an audio tag was used
10255    this.isAudio(tag.nodeName.toLowerCase() === 'audio');
10256
10257    // Update controls className. Can't do this when the controls are initially
10258    // set because the element doesn't exist yet.
10259    if (this.controls()) {
10260      this.addClass('vjs-controls-enabled');
10261    } else {
10262      this.addClass('vjs-controls-disabled');
10263    }
10264
10265    // Set ARIA label and region role depending on player type
10266    this.el_.setAttribute('role', 'region');
10267    if (this.isAudio()) {
10268      this.el_.setAttribute('aria-label', 'audio player');
10269    } else {
10270      this.el_.setAttribute('aria-label', 'video player');
10271    }
10272
10273    if (this.isAudio()) {
10274      this.addClass('vjs-audio');
10275    }
10276
10277    if (this.flexNotSupported_()) {
10278      this.addClass('vjs-no-flex');
10279    }
10280
10281    // TODO: Make this smarter. Toggle user state between touching/mousing
10282    // using events, since devices can have both touch and mouse events.
10283    // if (browser.TOUCH_ENABLED) {
10284    //   this.addClass('vjs-touch-enabled');
10285    // }
10286
10287    // iOS Safari has broken hover handling
10288    if (!browser.IS_IOS) {
10289      this.addClass('vjs-workinghover');
10290    }
10291
10292    // Make player easily findable by ID
10293    Player.players[this.id_] = this;
10294
10295    // When the player is first initialized, trigger activity so components
10296    // like the control bar show themselves if needed
10297    this.userActive(true);
10298    this.reportUserActivity();
10299    this.listenForUserActivity_();
10300
10301    this.on('fullscreenchange', this.handleFullscreenChange_);
10302    this.on('stageclick', this.handleStageClick_);
10303  }
10304
10305  /*
10306   * Global player list
10307   *
10308   * @type {Object}
10309   */
10310
10311  /**
10312   * Destroys the video player and does any necessary cleanup
10313   * ```js
10314   *     myPlayer.dispose();
10315   * ```
10316   * This is especially helpful if you are dynamically adding and removing videos
10317   * to/from the DOM.
10318   *
10319   * @method dispose
10320   */
10321
10322  Player.prototype.dispose = function dispose() {
10323    this.trigger('dispose');
10324    // prevent dispose from being called twice
10325    this.off('dispose');
10326
10327    if (this.styleEl_ && this.styleEl_.parentNode) {
10328      this.styleEl_.parentNode.removeChild(this.styleEl_);
10329    }
10330
10331    // Kill reference to this player
10332    Player.players[this.id_] = null;
10333    if (this.tag && this.tag.player) {
10334      this.tag.player = null;
10335    }
10336    if (this.el_ && this.el_.player) {
10337      this.el_.player = null;
10338    }
10339
10340    if (this.tech_) {
10341      this.tech_.dispose();
10342    }
10343
10344    _Component.prototype.dispose.call(this);
10345  };
10346
10347  /**
10348   * Create the component's DOM element
10349   *
10350   * @return {Element}
10351   * @method createEl
10352   */
10353
10354  Player.prototype.createEl = function createEl() {
10355    var el = this.el_ = _Component.prototype.createEl.call(this, 'div');
10356    var tag = this.tag;
10357
10358    // Remove width/height attrs from tag so CSS can make it 100% width/height
10359    tag.removeAttribute('width');
10360    tag.removeAttribute('height');
10361
10362    // Copy over all the attributes from the tag, including ID and class
10363    // ID will now reference player box, not the video tag
10364    var attrs = Dom.getElAttributes(tag);
10365
10366    Object.getOwnPropertyNames(attrs).forEach(function (attr) {
10367      // workaround so we don't totally break IE7
10368      // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
10369      if (attr === 'class') {
10370        el.className = attrs[attr];
10371      } else {
10372        el.setAttribute(attr, attrs[attr]);
10373      }
10374    });
10375
10376    // Update tag id/class for use as HTML5 playback tech
10377    // Might think we should do this after embedding in container so .vjs-tech class
10378    // doesn't flash 100% width/height, but class only applies with .video-js parent
10379    tag.playerId = tag.id;
10380    tag.id += '_html5_api';
10381    tag.className = 'vjs-tech';
10382
10383    // Make player findable on elements
10384    tag.player = el.player = this;
10385    // Default state of video is paused
10386    this.addClass('vjs-paused');
10387
10388    // Add a style element in the player that we'll use to set the width/height
10389    // of the player in a way that's still overrideable by CSS, just like the
10390    // video element
10391    if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
10392      this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
10393      var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
10394      var head = Dom.$('head');
10395      head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
10396    }
10397
10398    // Pass in the width/height/aspectRatio options which will update the style el
10399    this.width(this.options_.width);
10400    this.height(this.options_.height);
10401    this.fluid(this.options_.fluid);
10402    this.aspectRatio(this.options_.aspectRatio);
10403
10404    // Hide any links within the video/audio tag, because IE doesn't hide them completely.
10405    var links = tag.getElementsByTagName('a');
10406    for (var i = 0; i < links.length; i++) {
10407      var linkEl = links.item(i);
10408      Dom.addElClass(linkEl, 'vjs-hidden');
10409      linkEl.setAttribute('hidden', 'hidden');
10410    }
10411
10412    // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
10413    // keep track of the original for later so we can know if the source originally failed
10414    tag.initNetworkState_ = tag.networkState;
10415
10416    // Wrap video tag in div (el/box) container
10417    if (tag.parentNode) {
10418      tag.parentNode.insertBefore(el, tag);
10419    }
10420
10421    // insert the tag as the first child of the player element
10422    // then manually add it to the children array so that this.addChild
10423    // will work properly for other components
10424    Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.
10425    this.children_.unshift(tag);
10426
10427    this.el_ = el;
10428
10429    return el;
10430  };
10431
10432  /**
10433   * Get/set player width
10434   *
10435   * @param {Number=} value Value for width
10436   * @return {Number} Width when getting
10437   * @method width
10438   */
10439
10440  Player.prototype.width = function width(value) {
10441    return this.dimension('width', value);
10442  };
10443
10444  /**
10445   * Get/set player height
10446   *
10447   * @param {Number=} value Value for height
10448   * @return {Number} Height when getting
10449   * @method height
10450   */
10451
10452  Player.prototype.height = function height(value) {
10453    return this.dimension('height', value);
10454  };
10455
10456  /**
10457   * Get/set dimension for player
10458   *
10459   * @param {String} dimension Either width or height
10460   * @param {Number=} value Value for dimension
10461   * @return {Component}
10462   * @method dimension
10463   */
10464
10465  Player.prototype.dimension = function dimension(_dimension, value) {
10466    var privDimension = _dimension + '_';
10467
10468    if (value === undefined) {
10469      return this[privDimension] || 0;
10470    }
10471
10472    if (value === '') {
10473      // If an empty string is given, reset the dimension to be automatic
10474      this[privDimension] = undefined;
10475    } else {
10476      var parsedVal = parseFloat(value);
10477
10478      if (isNaN(parsedVal)) {
10479        _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
10480        return this;
10481      }
10482
10483      this[privDimension] = parsedVal;
10484    }
10485
10486    this.updateStyleEl_();
10487    return this;
10488  };
10489
10490  /**
10491   * Add/remove the vjs-fluid class
10492   *
10493   * @param {Boolean} bool Value of true adds the class, value of false removes the class
10494   * @method fluid
10495   */
10496
10497  Player.prototype.fluid = function fluid(bool) {
10498    if (bool === undefined) {
10499      return !!this.fluid_;
10500    }
10501
10502    this.fluid_ = !!bool;
10503
10504    if (bool) {
10505      this.addClass('vjs-fluid');
10506    } else {
10507      this.removeClass('vjs-fluid');
10508    }
10509  };
10510
10511  /**
10512   * Get/Set the aspect ratio
10513   *
10514   * @param {String=} ratio Aspect ratio for player
10515   * @return aspectRatio
10516   * @method aspectRatio
10517   */
10518
10519  Player.prototype.aspectRatio = function aspectRatio(ratio) {
10520    if (ratio === undefined) {
10521      return this.aspectRatio_;
10522    }
10523
10524    // Check for width:height format
10525    if (!/^\d+\:\d+$/.test(ratio)) {
10526      throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
10527    }
10528    this.aspectRatio_ = ratio;
10529
10530    // We're assuming if you set an aspect ratio you want fluid mode,
10531    // because in fixed mode you could calculate width and height yourself.
10532    this.fluid(true);
10533
10534    this.updateStyleEl_();
10535  };
10536
10537  /**
10538   * Update styles of the player element (height, width and aspect ratio)
10539   *
10540   * @method updateStyleEl_
10541   */
10542
10543  Player.prototype.updateStyleEl_ = function updateStyleEl_() {
10544    if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
10545      var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
10546      var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
10547      var techEl = this.tech_ && this.tech_.el();
10548
10549      if (techEl) {
10550        if (_width >= 0) {
10551          techEl.width = _width;
10552        }
10553        if (_height >= 0) {
10554          techEl.height = _height;
10555        }
10556      }
10557
10558      return;
10559    }
10560
10561    var width = undefined;
10562    var height = undefined;
10563    var aspectRatio = undefined;
10564    var idClass = undefined;
10565
10566    // The aspect ratio is either used directly or to calculate width and height.
10567    if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
10568      // Use any aspectRatio that's been specifically set
10569      aspectRatio = this.aspectRatio_;
10570    } else if (this.videoWidth()) {
10571      // Otherwise try to get the aspect ratio from the video metadata
10572      aspectRatio = this.videoWidth() + ':' + this.videoHeight();
10573    } else {
10574      // Or use a default. The video element's is 2:1, but 16:9 is more common.
10575      aspectRatio = '16:9';
10576    }
10577
10578    // Get the ratio as a decimal we can use to calculate dimensions
10579    var ratioParts = aspectRatio.split(':');
10580    var ratioMultiplier = ratioParts[1] / ratioParts[0];
10581
10582    if (this.width_ !== undefined) {
10583      // Use any width that's been specifically set
10584      width = this.width_;
10585    } else if (this.height_ !== undefined) {
10586      // Or calulate the width from the aspect ratio if a height has been set
10587      width = this.height_ / ratioMultiplier;
10588    } else {
10589      // Or use the video's metadata, or use the video el's default of 300
10590      width = this.videoWidth() || 300;
10591    }
10592
10593    if (this.height_ !== undefined) {
10594      // Use any height that's been specifically set
10595      height = this.height_;
10596    } else {
10597      // Otherwise calculate the height from the ratio and the width
10598      height = width * ratioMultiplier;
10599    }
10600
10601    // Ensure the CSS class is valid by starting with an alpha character
10602    if (/^[^a-zA-Z]/.test(this.id())) {
10603      idClass = 'dimensions-' + this.id();
10604    } else {
10605      idClass = this.id() + '-dimensions';
10606    }
10607
10608    // Ensure the right class is still on the player for the style element
10609    this.addClass(idClass);
10610
10611    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    ');
10612  };
10613
10614  /**
10615   * Load the Media Playback Technology (tech)
10616   * Load/Create an instance of playback technology including element and API methods
10617   * And append playback element in player div.
10618   *
10619   * @param {String} techName Name of the playback technology
10620   * @param {String} source Video source
10621   * @method loadTech_
10622   * @private
10623   */
10624
10625  Player.prototype.loadTech_ = function loadTech_(techName, source) {
10626
10627    // Pause and remove current playback technology
10628    if (this.tech_) {
10629      this.unloadTech_();
10630    }
10631
10632    // get rid of the HTML5 video tag as soon as we are using another tech
10633    if (techName !== 'Html5' && this.tag) {
10634      _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag);
10635      this.tag.player = null;
10636      this.tag = null;
10637    }
10638
10639    this.techName_ = techName;
10640
10641    // Turn off API access because we're loading a new tech that might load asynchronously
10642    this.isReady_ = false;
10643
10644    // Grab tech-specific options from player options and add source and parent element to use.
10645    var techOptions = _objectAssign2['default']({
10646      'nativeControlsForTouch': this.options_.nativeControlsForTouch,
10647      'source': source,
10648      'playerId': this.id(),
10649      'techId': this.id() + '_' + techName + '_api',
10650      'videoTracks': this.videoTracks_,
10651      'textTracks': this.textTracks_,
10652      'audioTracks': this.audioTracks_,
10653      'autoplay': this.options_.autoplay,
10654      'preload': this.options_.preload,
10655      'loop': this.options_.loop,
10656      'muted': this.options_.muted,
10657      'poster': this.poster(),
10658      'language': this.language(),
10659      'vtt.js': this.options_['vtt.js']
10660    }, this.options_[techName.toLowerCase()]);
10661
10662    if (this.tag) {
10663      techOptions.tag = this.tag;
10664    }
10665
10666    if (source) {
10667      this.currentType_ = source.type;
10668      if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
10669        techOptions.startTime = this.cache_.currentTime;
10670      }
10671
10672      this.cache_.src = source.src;
10673    }
10674
10675    // Initialize tech instance
10676    var techComponent = _techTechJs2['default'].getTech(techName);
10677    // Support old behavior of techs being registered as components.
10678    // Remove once that deprecated behavior is removed.
10679    if (!techComponent) {
10680      techComponent = _componentJs2['default'].getComponent(techName);
10681    }
10682    this.tech_ = new techComponent(techOptions);
10683
10684    // player.triggerReady is always async, so don't need this to be async
10685    this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
10686
10687    _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
10688
10689    // Listen to all HTML5-defined events and trigger them on the player
10690    this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
10691    this.on(this.tech_, 'waiting', this.handleTechWaiting_);
10692    this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
10693    this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
10694    this.on(this.tech_, 'playing', this.handleTechPlaying_);
10695    this.on(this.tech_, 'ended', this.handleTechEnded_);
10696    this.on(this.tech_, 'seeking', this.handleTechSeeking_);
10697    this.on(this.tech_, 'seeked', this.handleTechSeeked_);
10698    this.on(this.tech_, 'play', this.handleTechPlay_);
10699    this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
10700    this.on(this.tech_, 'pause', this.handleTechPause_);
10701    this.on(this.tech_, 'progress', this.handleTechProgress_);
10702    this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
10703    this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
10704    this.on(this.tech_, 'error', this.handleTechError_);
10705    this.on(this.tech_, 'suspend', this.handleTechSuspend_);
10706    this.on(this.tech_, 'abort', this.handleTechAbort_);
10707    this.on(this.tech_, 'emptied', this.handleTechEmptied_);
10708    this.on(this.tech_, 'stalled', this.handleTechStalled_);
10709    this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_);
10710    this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_);
10711    this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_);
10712    this.on(this.tech_, 'ratechange', this.handleTechRateChange_);
10713    this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_);
10714    this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_);
10715    this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
10716    this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
10717
10718    this.usingNativeControls(this.techGet_('controls'));
10719
10720    if (this.controls() && !this.usingNativeControls()) {
10721      this.addTechControlsListeners_();
10722    }
10723
10724    // Add the tech element in the DOM if it was not already there
10725    // Make sure to not insert the original video element if using Html5
10726    if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
10727      Dom.insertElFirst(this.tech_.el(), this.el());
10728    }
10729
10730    // Get rid of the original video tag reference after the first tech is loaded
10731    if (this.tag) {
10732      this.tag.player = null;
10733      this.tag = null;
10734    }
10735  };
10736
10737  /**
10738   * Unload playback technology
10739   *
10740   * @method unloadTech_
10741   * @private
10742   */
10743
10744  Player.prototype.unloadTech_ = function unloadTech_() {
10745    // Save the current text tracks so that we can reuse the same text tracks with the next tech
10746    this.videoTracks_ = this.videoTracks();
10747    this.textTracks_ = this.textTracks();
10748    this.audioTracks_ = this.audioTracks();
10749    this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_);
10750
10751    this.isReady_ = false;
10752
10753    this.tech_.dispose();
10754
10755    this.tech_ = false;
10756  };
10757
10758  /**
10759   * Return a reference to the current tech.
10760   * It will only return a reference to the tech if given an object with the
10761   * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse
10762   * of techs by plugins.
10763   *
10764   * @param {Object}
10765   * @return {Object} The Tech
10766   * @method tech
10767   */
10768
10769  Player.prototype.tech = function tech(safety) {
10770    if (safety && safety.IWillNotUseThisInPlugins) {
10771      return this.tech_;
10772    }
10773    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    ';
10774    _globalWindow2['default'].alert(errorText);
10775    throw new Error(errorText);
10776  };
10777
10778  /**
10779   * Set up click and touch listeners for the playback element
10780   *
10781   * On desktops, a click on the video itself will toggle playback,
10782   * on a mobile device a click on the video toggles controls.
10783   * (toggling controls is done by toggling the user state between active and
10784   * inactive)
10785   * A tap can signal that a user has become active, or has become inactive
10786   * e.g. a quick tap on an iPhone movie should reveal the controls. Another
10787   * quick tap should hide them again (signaling the user is in an inactive
10788   * viewing state)
10789   * In addition to this, we still want the user to be considered inactive after
10790   * a few seconds of inactivity.
10791   * Note: the only part of iOS interaction we can't mimic with this setup
10792   * is a touch and hold on the video element counting as activity in order to
10793   * keep the controls showing, but that shouldn't be an issue. A touch and hold
10794   * on any controls will still keep the user active
10795   *
10796   * @private
10797   * @method addTechControlsListeners_
10798   */
10799
10800  Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
10801    // Make sure to remove all the previous listeners in case we are called multiple times.
10802    this.removeTechControlsListeners_();
10803
10804    // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
10805    // trigger mousedown/up.
10806    // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
10807    // Any touch events are set to block the mousedown event from happening
10808    this.on(this.tech_, 'mousedown', this.handleTechClick_);
10809
10810    // If the controls were hidden we don't want that to change without a tap event
10811    // so we'll check if the controls were already showing before reporting user
10812    // activity
10813    this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
10814    this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
10815    this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
10816
10817    // The tap listener needs to come after the touchend listener because the tap
10818    // listener cancels out any reportedUserActivity when setting userActive(false)
10819    this.on(this.tech_, 'tap', this.handleTechTap_);
10820  };
10821
10822  /**
10823   * Remove the listeners used for click and tap controls. This is needed for
10824   * toggling to controls disabled, where a tap/touch should do nothing.
10825   *
10826   * @method removeTechControlsListeners_
10827   * @private
10828   */
10829
10830  Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
10831    // We don't want to just use `this.off()` because there might be other needed
10832    // listeners added by techs that extend this.
10833    this.off(this.tech_, 'tap', this.handleTechTap_);
10834    this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
10835    this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
10836    this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
10837    this.off(this.tech_, 'mousedown', this.handleTechClick_);
10838  };
10839
10840  /**
10841   * Player waits for the tech to be ready
10842   *
10843   * @method handleTechReady_
10844   * @private
10845   */
10846
10847  Player.prototype.handleTechReady_ = function handleTechReady_() {
10848    this.triggerReady();
10849
10850    // Keep the same volume as before
10851    if (this.cache_.volume) {
10852      this.techCall_('setVolume', this.cache_.volume);
10853    }
10854
10855    // Look if the tech found a higher resolution poster while loading
10856    this.handleTechPosterChange_();
10857
10858    // Update the duration if available
10859    this.handleTechDurationChange_();
10860
10861    // Chrome and Safari both have issues with autoplay.
10862    // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
10863    // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
10864    // This fixes both issues. Need to wait for API, so it updates displays correctly
10865    if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
vendor: 12,738 bytes, lines 10866-11391
10866      try {
10867        delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
10868      } catch (e) {
10869        _utilsLogJs2['default']('deleting tag.poster throws in some browsers', e);
10870      }
10871      this.play();
10872    }
10873  };
10874
10875  /**
10876   * Fired when the user agent begins looking for media data
10877   *
10878   * @private
10879   * @method handleTechLoadStart_
10880   */
10881
10882  Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
10883    // TODO: Update to use `emptied` event instead. See #1277.
10884
10885    this.removeClass('vjs-ended');
10886
10887    // reset the error state
10888    this.error(null);
10889
10890    // If it's already playing we want to trigger a firstplay event now.
10891    // The firstplay event relies on both the play and loadstart events
10892    // which can happen in any order for a new source
10893    if (!this.paused()) {
10894      this.trigger('loadstart');
10895      this.trigger('firstplay');
10896    } else {
10897      // reset the hasStarted state
10898      this.hasStarted(false);
10899      this.trigger('loadstart');
10900    }
10901  };
10902
10903  /**
10904   * Add/remove the vjs-has-started class
10905   *
10906   * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class
10907   * @return {Boolean} Boolean value if has started
10908   * @private
10909   * @method hasStarted
10910   */
10911
10912  Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10913    if (_hasStarted !== undefined) {
10914      // only update if this is a new value
10915      if (this.hasStarted_ !== _hasStarted) {
10916        this.hasStarted_ = _hasStarted;
10917        if (_hasStarted) {
10918          this.addClass('vjs-has-started');
10919          // trigger the firstplay event if this newly has played
10920          this.trigger('firstplay');
10921        } else {
10922          this.removeClass('vjs-has-started');
10923        }
10924      }
10925      return this;
10926    }
10927    return !!this.hasStarted_;
10928  };
10929
10930  /**
10931   * Fired whenever the media begins or resumes playback
10932   *
10933   * @private
10934   * @method handleTechPlay_
10935   */
10936
10937  Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10938    this.removeClass('vjs-ended');
10939    this.removeClass('vjs-paused');
10940    this.addClass('vjs-playing');
10941
10942    // hide the poster when the user hits play
10943    // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
10944    this.hasStarted(true);
10945
10946    this.trigger('play');
10947  };
10948
10949  /**
10950   * Fired whenever the media begins waiting
10951   *
10952   * @private
10953   * @method handleTechWaiting_
10954   */
10955
10956  Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10957    var _this2 = this;
10958
10959    this.addClass('vjs-waiting');
10960    this.trigger('waiting');
10961    this.one('timeupdate', function () {
10962      return _this2.removeClass('vjs-waiting');
10963    });
10964  };
10965
10966  /**
10967   * A handler for events that signal that waiting has ended
10968   * which is not consistent between browsers. See #1351
10969   *
10970   * @private
10971   * @method handleTechCanPlay_
10972   */
10973
10974  Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10975    this.removeClass('vjs-waiting');
10976    this.trigger('canplay');
10977  };
10978
10979  /**
10980   * A handler for events that signal that waiting has ended
10981   * which is not consistent between browsers. See #1351
10982   *
10983   * @private
10984   * @method handleTechCanPlayThrough_
10985   */
10986
10987  Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10988    this.removeClass('vjs-waiting');
10989    this.trigger('canplaythrough');
10990  };
10991
10992  /**
10993   * A handler for events that signal that waiting has ended
10994   * which is not consistent between browsers. See #1351
10995   *
10996   * @private
10997   * @method handleTechPlaying_
10998   */
10999
11000  Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
11001    this.removeClass('vjs-waiting');
11002    this.trigger('playing');
11003  };
11004
11005  /**
11006   * Fired whenever the player is jumping to a new time
11007   *
11008   * @private
11009   * @method handleTechSeeking_
11010   */
11011
11012  Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
11013    this.addClass('vjs-seeking');
11014    this.trigger('seeking');
11015  };
11016
11017  /**
11018   * Fired when the player has finished jumping to a new time
11019   *
11020   * @private
11021   * @method handleTechSeeked_
11022   */
11023
11024  Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
11025    this.removeClass('vjs-seeking');
11026    this.trigger('seeked');
11027  };
11028
11029  /**
11030   * Fired the first time a video is played
11031   * Not part of the HLS spec, and we're not sure if this is the best
11032   * implementation yet, so use sparingly. If you don't have a reason to
11033   * prevent playback, use `myPlayer.one('play');` instead.
11034   *
11035   * @private
11036   * @method handleTechFirstPlay_
11037   */
11038
11039  Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
11040    //If the first starttime attribute is specified
11041    //then we will start at the given offset in seconds
11042    if (this.options_.starttime) {
11043      this.currentTime(this.options_.starttime);
11044    }
11045
11046    this.addClass('vjs-has-started');
11047    this.trigger('firstplay');
11048  };
11049
11050  /**
11051   * Fired whenever the media has been paused
11052   *
11053   * @private
11054   * @method handleTechPause_
11055   */
11056
11057  Player.prototype.handleTechPause_ = function handleTechPause_() {
11058    this.removeClass('vjs-playing');
11059    this.addClass('vjs-paused');
11060    this.trigger('pause');
11061  };
11062
11063  /**
11064   * Fired while the user agent is downloading media data
11065   *
11066   * @private
11067   * @method handleTechProgress_
11068   */
11069
11070  Player.prototype.handleTechProgress_ = function handleTechProgress_() {
11071    this.trigger('progress');
11072  };
11073
11074  /**
11075   * Fired when the end of the media resource is reached (currentTime == duration)
11076   *
11077   * @private
11078   * @method handleTechEnded_
11079   */
11080
11081  Player.prototype.handleTechEnded_ = function handleTechEnded_() {
11082    this.addClass('vjs-ended');
11083    if (this.options_.loop) {
11084      this.currentTime(0);
11085      this.play();
11086    } else if (!this.paused()) {
11087      this.pause();
11088    }
11089
11090    this.trigger('ended');
11091  };
11092
11093  /**
11094   * Fired when the duration of the media resource is first known or changed
11095   *
11096   * @private
11097   * @method handleTechDurationChange_
11098   */
11099
11100  Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
11101    this.duration(this.techGet_('duration'));
11102  };
11103
11104  /**
11105   * Handle a click on the media element to play/pause
11106   *
11107   * @param {Object=} event Event object
11108   * @private
11109   * @method handleTechClick_
11110   */
11111
11112  Player.prototype.handleTechClick_ = function handleTechClick_(event) {
11113    // We're using mousedown to detect clicks thanks to Flash, but mousedown
11114    // will also be triggered with right-clicks, so we need to prevent that
11115    if (event.button !== 0) return;
11116
11117    // When controls are disabled a click should not toggle playback because
11118    // the click is considered a control
11119    if (this.controls()) {
11120      if (this.paused()) {
11121        this.play();
11122      } else {
11123        this.pause();
11124      }
11125    }
11126  };
11127
11128  /**
11129   * Handle a tap on the media element. It will toggle the user
11130   * activity state, which hides and shows the controls.
11131   *
11132   * @private
11133   * @method handleTechTap_
11134   */
11135
11136  Player.prototype.handleTechTap_ = function handleTechTap_() {
11137    this.userActive(!this.userActive());
11138  };
11139
11140  /**
11141   * Handle touch to start
11142   *
11143   * @private
11144   * @method handleTechTouchStart_
11145   */
11146
11147  Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
11148    this.userWasActive = this.userActive();
11149  };
11150
11151  /**
11152   * Handle touch to move
11153   *
11154   * @private
11155   * @method handleTechTouchMove_
11156   */
11157
11158  Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
11159    if (this.userWasActive) {
11160      this.reportUserActivity();
11161    }
11162  };
11163
11164  /**
11165   * Handle touch to end
11166   *
11167   * @private
11168   * @method handleTechTouchEnd_
11169   */
11170
11171  Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
11172    // Stop the mouse events from also happening
11173    event.preventDefault();
11174  };
11175
11176  /**
11177   * Fired when the player switches in or out of fullscreen mode
11178   *
11179   * @private
11180   * @method handleFullscreenChange_
11181   */
11182
11183  Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
11184    if (this.isFullscreen()) {
11185      this.addClass('vjs-fullscreen');
11186    } else {
11187      this.removeClass('vjs-fullscreen');
11188    }
11189  };
11190
11191  /**
11192   * native click events on the SWF aren't triggered on IE11, Win8.1RT
11193   * use stageclick events triggered from inside the SWF instead
11194   *
11195   * @private
11196   * @method handleStageClick_
11197   */
11198
11199  Player.prototype.handleStageClick_ = function handleStageClick_() {
11200    this.reportUserActivity();
11201  };
11202
11203  /**
11204   * Handle Tech Fullscreen Change
11205   *
11206   * @private
11207   * @method handleTechFullscreenChange_
11208   */
11209
11210  Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
11211    if (data) {
11212      this.isFullscreen(data.isFullscreen);
11213    }
11214    this.trigger('fullscreenchange');
11215  };
11216
11217  /**
11218   * Fires when an error occurred during the loading of an audio/video
11219   *
11220   * @private
11221   * @method handleTechError_
11222   */
11223
11224  Player.prototype.handleTechError_ = function handleTechError_() {
11225    var error = this.tech_.error();
11226    this.error(error && error.code);
11227  };
11228
11229  /**
11230   * Fires when the browser is intentionally not getting media data
11231   *
11232   * @private
11233   * @method handleTechSuspend_
11234   */
11235
11236  Player.prototype.handleTechSuspend_ = function handleTechSuspend_() {
11237    this.trigger('suspend');
11238  };
11239
11240  /**
11241   * Fires when the loading of an audio/video is aborted
11242   *
11243   * @private
11244   * @method handleTechAbort_
11245   */
11246
11247  Player.prototype.handleTechAbort_ = function handleTechAbort_() {
11248    this.trigger('abort');
11249  };
11250
11251  /**
11252   * Fires when the current playlist is empty
11253   *
11254   * @private
11255   * @method handleTechEmptied_
11256   */
11257
11258  Player.prototype.handleTechEmptied_ = function handleTechEmptied_() {
11259    this.trigger('emptied');
11260  };
11261
11262  /**
11263   * Fires when the browser is trying to get media data, but data is not available
11264   *
11265   * @private
11266   * @method handleTechStalled_
11267   */
11268
11269  Player.prototype.handleTechStalled_ = function handleTechStalled_() {
11270    this.trigger('stalled');
11271  };
11272
11273  /**
11274   * Fires when the browser has loaded meta data for the audio/video
11275   *
11276   * @private
11277   * @method handleTechLoadedMetaData_
11278   */
11279
11280  Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() {
11281    this.trigger('loadedmetadata');
11282  };
11283
11284  /**
11285   * Fires when the browser has loaded the current frame of the audio/video
11286   *
11287   * @private
11288   * @method handleTechLoadedData_
11289   */
11290
11291  Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() {
11292    this.trigger('loadeddata');
11293  };
11294
11295  /**
11296   * Fires when the current playback position has changed
11297   *
11298   * @private
11299   * @method handleTechTimeUpdate_
11300   */
11301
11302  Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() {
11303    this.trigger('timeupdate');
11304  };
11305
11306  /**
11307   * Fires when the playing speed of the audio/video is changed
11308   *
11309   * @private
11310   * @method handleTechRateChange_
11311   */
11312
11313  Player.prototype.handleTechRateChange_ = function handleTechRateChange_() {
11314    this.trigger('ratechange');
11315  };
11316
11317  /**
11318   * Fires when the volume has been changed
11319   *
11320   * @private
11321   * @method handleTechVolumeChange_
11322   */
11323
11324  Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() {
11325    this.trigger('volumechange');
11326  };
11327
11328  /**
11329   * Fires when the text track has been changed
11330   *
11331   * @private
11332   * @method handleTechTextTrackChange_
11333   */
11334
11335  Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() {
11336    this.trigger('texttrackchange');
11337  };
11338
11339  /**
11340   * Get object for cached values.
11341   *
11342   * @return {Object}
11343   * @method getCache
11344   */
11345
11346  Player.prototype.getCache = function getCache() {
11347    return this.cache_;
11348  };
11349
11350  /**
11351   * Pass values to the playback tech
11352   *
11353   * @param {String=} method Method
11354   * @param {Object=} arg Argument
11355   * @private
11356   * @method techCall_
11357   */
11358
11359  Player.prototype.techCall_ = function techCall_(method, arg) {
11360    // If it's not ready yet, call method when it is
11361    if (this.tech_ && !this.tech_.isReady_) {
11362      this.tech_.ready(function () {
11363        this[method](arg);
11364      }, true);
11365
11366      // Otherwise call method now
11367    } else {
11368        try {
11369          this.tech_[method](arg);
11370        } catch (e) {
11371          _utilsLogJs2['default'](e);
11372          throw e;
11373        }
11374      }
11375  };
11376
11377  /**
11378   * Get calls can't wait for the tech, and sometimes don't need to.
11379   *
11380   * @param {String} method Tech method
11381   * @return {Method}
11382   * @private
11383   * @method techGet_
11384   */
11385
11386  Player.prototype.techGet_ = function techGet_(method) {
11387    if (this.tech_ && this.tech_.isReady_) {
11388
11389      // Flash likes to die and reload when you hide or reposition it.
11390      // In these cases the object methods go away and we get errors.
11391      // When that happens we'll catch the errors and inform tech that it's not ready any more.
11392      try {
11393        return this.tech_[method]();
11394      } catch (e) {
11395        // When building additional tech libs, an expected method may not be defined yet
11396        if (this.tech_[method] === undefined) {
11397          _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
11398        } else {
11399          // When a method isn't available on the object it throws a TypeError
11400          if (e.name === 'TypeError') {
11401            _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
11402            this.tech_.isReady_ = false;
11403          } else {
11404            _utilsLogJs2['default'](e);
11405          }
11406        }
11407        throw e;
11408      }
11409    }
11410
11411    return;
11412  };
11413
11414  /**
11415   * start media playback
11416   * ```js
11417   *     myPlayer.play();
11418   * ```
11419   *
11420   * @return {Player} self
11421   * @method play
11422   */
11423
11424  Player.prototype.play = function play() {
11425    this.techCall_('play');
11426    return this;
11427  };
11428
11429  /**
11430   * Pause the video playback
11431   * ```js
11432   *     myPlayer.pause();
11433   * ```
11434   *
11435   * @return {Player} self
11436   * @method pause
11437   */
11438
11439  Player.prototype.pause = function pause() {
11440    this.techCall_('pause');
11441    return this;
11442  };
11443
11444  /**
11445   * Check if the player is paused
11446   * ```js
11447   *     var isPaused = myPlayer.paused();
11448   *     var isPlaying = !myPlayer.paused();
11449   * ```
11450   *
11451   * @return {Boolean} false if the media is currently playing, or true otherwise
11452   * @method paused
11453   */
11454
11455  Player.prototype.paused = function paused() {
11456    // The initial state of paused should be true (in Safari it's actually false)
11457    return this.techGet_('paused') === false ? false : true;
11458  };
11459
11460  /**
11461   * Returns whether or not the user is "scrubbing". Scrubbing is when the user
11462   * has clicked the progress bar handle and is dragging it along the progress bar.
11463   *
11464   * @param  {Boolean} isScrubbing   True/false the user is scrubbing
11465   * @return {Boolean}               The scrubbing status when getting
11466   * @return {Object}                The player when setting
11467   * @method scrubbing
11468   */
11469
11470  Player.prototype.scrubbing = function scrubbing(isScrubbing) {
11471    if (isScrubbing !== undefined) {
11472      this.scrubbing_ = !!isScrubbing;
11473
11474      if (isScrubbing) {
11475        this.addClass('vjs-scrubbing');
11476      } else {
11477        this.removeClass('vjs-scrubbing');
11478      }
11479
11480      return this;
11481    }
11482
11483    return this.scrubbing_;
11484  };
11485
11486  /**
11487   * Get or set the current time (in seconds)
11488   * ```js
11489   *     // get
11490   *     var whereYouAt = myPlayer.currentTime();
11491   *     // set
11492   *     myPlayer.currentTime(120); // 2 minutes into the video
11493   * ```
11494   *
11495   * @param  {Number|String=} seconds The time to seek to
11496   * @return {Number}        The time in seconds, when not setting
11497   * @return {Player}    self, when the current time is set
11498   * @method currentTime
11499   */
11500
11501  Player.prototype.currentTime = function currentTime(seconds) {
11502    if (seconds !== undefined) {
11503
11504      this.techCall_('setCurrentTime', seconds);
11505
11506      return this;
11507    }
11508
11509    // cache last currentTime and return. default to 0 seconds
11510    //
11511    // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
11512    // currentTime when scrubbing, but may not provide much performance benefit afterall.
11513    // Should be tested. Also something has to read the actual current time or the cache will
11514    // never get updated.
11515    return this.cache_.currentTime = this.techGet_('currentTime') || 0;
11516  };
11517
11518  /**
11519   * Get the length in time of the video in seconds
11520   * ```js
11521   *     var lengthOfVideo = myPlayer.duration();
11522   * ```
11523   * **NOTE**: The video must have started loading before the duration can be
11524   * known, and in the case of Flash, may not be known until the video starts
11525   * playing.
11526   *
11527   * @param {Number} seconds Duration when setting
11528   * @return {Number} The duration of the video in seconds when getting
11529   * @method duration
11530   */
11531
11532  Player.prototype.duration = function duration(seconds) {
11533    if (seconds === undefined) {
11534      return this.cache_.duration || 0;
11535    }
11536
11537    seconds = parseFloat(seconds) || 0;
11538
11539    // Standardize on Inifity for signaling video is live
11540    if (seconds < 0) {
11541      seconds = Infinity;
11542    }
11543
11544    if (seconds !== this.cache_.duration) {
11545      // Cache the last set value for optimized scrubbing (esp. Flash)
11546      this.cache_.duration = seconds;
11547
11548      if (seconds === Infinity) {
11549        this.addClass('vjs-live');
11550      } else {
11551        this.removeClass('vjs-live');
11552      }
11553
11554      this.trigger('durationchange');
11555    }
11556
11557    return this;
11558  };
11559
11560  /**
11561   * Calculates how much time is left.
11562   * ```js
11563   *     var timeLeft = myPlayer.remainingTime();
11564   * ```
11565   * Not a native video element function, but useful
11566   *
11567   * @return {Number} The time remaining in seconds
11568   * @method remainingTime
11569   */
11570
11571  Player.prototype.remainingTime = function remainingTime() {
11572    return this.duration() - this.currentTime();
11573  };
11574
11575  // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
11576  // Buffered returns a timerange object.
11577  // Kind of like an array of portions of the video that have been downloaded.
vendor: 4,087 bytes, lines 11578-11715
11578
11579  /**
11580   * Get a TimeRange object with the times of the video that have been downloaded
11581   * If you just want the percent of the video that's been downloaded,
11582   * use bufferedPercent.
11583   * ```js
11584   *     // Number of different ranges of time have been buffered. Usually 1.
11585   *     numberOfRanges = bufferedTimeRange.length,
11586   *     // Time in seconds when the first range starts. Usually 0.
11587   *     firstRangeStart = bufferedTimeRange.start(0),
11588   *     // Time in seconds when the first range ends
11589   *     firstRangeEnd = bufferedTimeRange.end(0),
11590   *     // Length in seconds of the first time range
11591   *     firstRangeLength = firstRangeEnd - firstRangeStart;
11592   * ```
11593   *
11594   * @return {Object} A mock TimeRange object (following HTML spec)
11595   * @method buffered
11596   */
11597
11598  Player.prototype.buffered = function buffered() {
11599    var buffered = this.techGet_('buffered');
11600
11601    if (!buffered || !buffered.length) {
11602      buffered = _utilsTimeRangesJs.createTimeRange(0, 0);
11603    }
11604
11605    return buffered;
11606  };
11607
11608  /**
11609   * Get the percent (as a decimal) of the video that's been downloaded
11610   * ```js
11611   *     var howMuchIsDownloaded = myPlayer.bufferedPercent();
11612   * ```
11613   * 0 means none, 1 means all.
11614   * (This method isn't in the HTML5 spec, but it's very convenient)
11615   *
11616   * @return {Number} A decimal between 0 and 1 representing the percent
11617   * @method bufferedPercent
11618   */
11619
11620  Player.prototype.bufferedPercent = function bufferedPercent() {
11621    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration());
11622  };
11623
11624  /**
11625   * Get the ending time of the last buffered time range
11626   * This is used in the progress bar to encapsulate all time ranges.
11627   *
11628   * @return {Number} The end of the last buffered time range
11629   * @method bufferedEnd
11630   */
11631
11632  Player.prototype.bufferedEnd = function bufferedEnd() {
11633    var buffered = this.buffered(),
11634        duration = this.duration(),
11635        end = buffered.end(buffered.length - 1);
11636
11637    if (end > duration) {
11638      end = duration;
11639    }
11640
11641    return end;
11642  };
11643
11644  /**
11645   * Get or set the current volume of the media
11646   * ```js
11647   *     // get
11648   *     var howLoudIsIt = myPlayer.volume();
11649   *     // set
11650   *     myPlayer.volume(0.5); // Set volume to half
11651   * ```
11652   * 0 is off (muted), 1.0 is all the way up, 0.5 is half way.
11653   *
11654   * @param  {Number} percentAsDecimal The new volume as a decimal percent
11655   * @return {Number}              The current volume when getting
11656   * @return {Player}              self when setting
11657   * @method volume
11658   */
11659
11660  Player.prototype.volume = function volume(percentAsDecimal) {
11661    var vol = undefined;
11662
11663    if (percentAsDecimal !== undefined) {
11664      vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
11665      this.cache_.volume = vol;
11666      this.techCall_('setVolume', vol);
11667
11668      return this;
11669    }
11670
11671    // Default to 1 when returning current volume.
11672    vol = parseFloat(this.techGet_('volume'));
11673    return isNaN(vol) ? 1 : vol;
11674  };
11675
11676  /**
11677   * Get the current muted state, or turn mute on or off
11678   * ```js
11679   *     // get
11680   *     var isVolumeMuted = myPlayer.muted();
11681   *     // set
11682   *     myPlayer.muted(true); // mute the volume
11683   * ```
11684   *
11685   * @param  {Boolean=} muted True to mute, false to unmute
11686   * @return {Boolean} True if mute is on, false if not when getting
11687   * @return {Player} self when setting mute
11688   * @method muted
11689   */
11690
11691  Player.prototype.muted = function muted(_muted) {
11692    if (_muted !== undefined) {
11693      this.techCall_('setMuted', _muted);
11694      return this;
11695    }
11696    return this.techGet_('muted') || false; // Default to false
11697  };
11698
11699  // Check if current tech can support native fullscreen
11700  // (e.g. with built in controls like iOS, so not our flash swf)
11701  /**
11702   * Check to see if fullscreen is supported
11703   *
11704   * @return {Boolean}
11705   * @method supportsFullScreen
11706   */
11707
11708  Player.prototype.supportsFullScreen = function supportsFullScreen() {
11709    return this.techGet_('supportsFullScreen') || false;
11710  };
11711
11712  /**
11713   * Check if the player is in fullscreen mode
11714   * ```js
11715   *     // get
11716   *     var fullscreenOrNot = myPlayer.isFullscreen();
11717   *     // set
11718   *     myPlayer.isFullscreen(true); // tell the player it's in fullscreen
11719   * ```
11720   * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
11721   * property and instead document.fullscreenElement is used. But isFullscreen is
11722   * still a valuable property for internal player workings.
11723   *
11724   * @param  {Boolean=} isFS Update the player's fullscreen state
11725   * @return {Boolean} true if fullscreen false if not when getting
11726   * @return {Player} self when setting
11727   * @method isFullscreen
11728   */
11729
11730  Player.prototype.isFullscreen = function isFullscreen(isFS) {
11731    if (isFS !== undefined) {
11732      this.isFullscreen_ = !!isFS;
11733      return this;
11734    }
11735    return !!this.isFullscreen_;
11736  };
11737
11738  /**
11739   * Increase the size of the video to full screen
11740   * ```js
11741   *     myPlayer.requestFullscreen();
11742   * ```
11743   * In some browsers, full screen is not supported natively, so it enters
11744   * "full window mode", where the video fills the browser window.
11745   * In browsers and devices that support native full screen, sometimes the
11746   * browser's default controls will be shown, and not the Video.js custom skin.
11747   * This includes most mobile devices (iOS, Android) and older versions of
11748   * Safari.
11749   *
11750   * @return {Player} self
11751   * @method requestFullscreen
11752   */
11753
11754  Player.prototype.requestFullscreen = function requestFullscreen() {
11755    var fsApi = _fullscreenApiJs2['default'];
11756
11757    this.isFullscreen(true);
11758
11759    if (fsApi.requestFullscreen) {
11760      // the browser supports going fullscreen at the element level so we can
11761      // take the controls fullscreen as well as the video
11762
11763      // Trigger fullscreenchange event after change
11764      // We have to specifically add this each time, and remove
11765      // when canceling fullscreen. Otherwise if there's multiple
11766      // players on a page, they would all be reacting to the same fullscreen
11767      // events
11768      Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
11769        this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]);
11770
11771        // If cancelling fullscreen, remove event listener.
11772        if (this.isFullscreen() === false) {
11773          Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange);
11774        }
11775
11776        this.trigger('fullscreenchange');
11777      }));
11778
11779      this.el_[fsApi.requestFullscreen]();
11780    } else if (this.tech_.supportsFullScreen()) {
11781      // we can't take the video.js controls fullscreen but we can go fullscreen
11782      // with native controls
11783      this.techCall_('enterFullScreen');
11784    } else {
11785      // fullscreen isn't supported so we'll just stretch the video element to
11786      // fill the viewport
11787      this.enterFullWindow();
11788      this.trigger('fullscreenchange');
11789    }
11790
11791    return this;
11792  };
11793
11794  /**
11795   * Return the video to its normal size after having been in full screen mode
11796   * ```js
11797   *     myPlayer.exitFullscreen();
11798   * ```
11799   *
11800   * @return {Player} self
11801   * @method exitFullscreen
11802   */
11803
11804  Player.prototype.exitFullscreen = function exitFullscreen() {
11805    var fsApi = _fullscreenApiJs2['default'];
11806    this.isFullscreen(false);
11807
11808    // Check for browser element fullscreen support
11809    if (fsApi.requestFullscreen) {
11810      _globalDocument2['default'][fsApi.exitFullscreen]();
11811    } else if (this.tech_.supportsFullScreen()) {
11812      this.techCall_('exitFullScreen');
11813    } else {
11814      this.exitFullWindow();
11815      this.trigger('fullscreenchange');
11816    }
11817
11818    return this;
11819  };
11820
11821  /**
11822   * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
11823   *
11824   * @method enterFullWindow
11825   */
11826
11827  Player.prototype.enterFullWindow = function enterFullWindow() {
11828    this.isFullWindow = true;
11829
11830    // Storing original doc overflow value to return to when fullscreen is off
11831    this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow;
11832
11833    // Add listener for esc key to exit fullscreen
11834    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
11835
11836    // Hide any scroll bars
11837    _globalDocument2['default'].documentElement.style.overflow = 'hidden';
11838
11839    // Apply fullscreen styles
11840    Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window');
11841
11842    this.trigger('enterFullWindow');
11843  };
11844
11845  /**
11846   * Check for call to either exit full window or full screen on ESC key
11847   *
11848   * @param {String} event Event to check for key press
11849   * @method fullWindowOnEscKey
11850   */
11851
11852  Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11853    if (event.keyCode === 27) {
11854      if (this.isFullscreen() === true) {
11855        this.exitFullscreen();
11856      } else {
11857        this.exitFullWindow();
11858      }
11859    }
11860  };
11861
11862  /**
11863   * Exit full window
11864   *
11865   * @method exitFullWindow
11866   */
11867
11868  Player.prototype.exitFullWindow = function exitFullWindow() {
11869    this.isFullWindow = false;
11870    Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey);
11871
11872    // Unhide scroll bars.
11873    _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow;
11874
11875    // Remove fullscreen styles
11876    Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window');
11877
11878    // Resize the box, controller, and poster to original sizes
11879    // this.positionAll();
11880    this.trigger('exitFullWindow');
11881  };
11882
11883  /**
11884   * Check whether the player can play a given mimetype
11885   *
11886   * @param {String} type The mimetype to check
11887   * @return {String} 'probably', 'maybe', or '' (empty string)
11888   * @method canPlayType
11889   */
11890
11891  Player.prototype.canPlayType = function canPlayType(type) {
11892    var can = undefined;
11893
11894    // Loop through each playback technology in the options order
11895    for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11896      var techName = _utilsToTitleCaseJs2['default'](j[i]);
11897      var tech = _techTechJs2['default'].getTech(techName);
11898
11899      // Support old behavior of techs being registered as components.
11900      // Remove once that deprecated behavior is removed.
11901      if (!tech) {
11902        tech = _componentJs2['default'].getComponent(techName);
11903      }
11904
11905      // Check if the current tech is defined before continuing
11906      if (!tech) {
11907        _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11908        continue;
11909      }
11910
11911      // Check if the browser supports this technology
11912      if (tech.isSupported()) {
11913        can = tech.canPlayType(type);
11914
11915        if (can) {
11916          return can;
11917        }
11918      }
11919    }
11920
11921    return '';
11922  };
11923
11924  /**
11925   * Select source based on tech-order or source-order
11926   * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11927   * defaults to tech-order selection
11928   *
11929   * @param {Array} sources The sources for a media asset
11930   * @return {Object|Boolean} Object of source and tech order, otherwise false
11931   * @method selectSource
11932   */
11933
11934  Player.prototype.selectSource = function selectSource(sources) {
11935    // Get only the techs specified in `techOrder` that exist and are supported by the
11936    // current platform
11937    var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) {
11938      // `Component.getComponent(...)` is for support of old behavior of techs
11939      // being registered as components.
11940      // Remove once that deprecated behavior is removed.
11941      return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)];
11942    }).filter(function (_ref) {
11943      var techName = _ref[0];
11944      var tech = _ref[1];
11945
11946      // Check if the current tech is defined before continuing
11947      if (tech) {
11948        // Check if the browser supports this technology
11949        return tech.isSupported();
11950      }
11951
11952      _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11953      return false;
11954    });
11955
11956    // Iterate over each `innerArray` element once per `outerArray` element and execute
11957    // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11958    // that value.
11959    var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11960      var found = undefined;
11961
11962      outerArray.some(function (outerChoice) {
11963        return innerArray.some(function (innerChoice) {
11964          found = tester(outerChoice, innerChoice);
11965
11966          if (found) {
11967            return true;
11968          }
11969        });
11970      });
11971
11972      return found;
11973    };
11974
11975    var foundSourceAndTech = undefined;
11976    var flip = function flip(fn) {
11977      return function (a, b) {
11978        return fn(b, a);
11979      };
11980    };
11981    var finder = function finder(_ref2, source) {
11982      var techName = _ref2[0];
11983      var tech = _ref2[1];
11984
11985      if (tech.canPlaySource(source)) {
11986        return { source: source, tech: techName };
11987      }
11988    };
11989
11990    // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11991    // to select from them based on their priority.
11992    if (this.options_.sourceOrder) {
11993      // Source-first ordering
11994      foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11995    } else {
11996      // Tech-first ordering
11997      foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11998    }
11999
12000    return foundSourceAndTech || false;
12001  };
12002
12003  /**
12004   * The source function updates the video source
12005   * There are three types of variables you can pass as the argument.
12006   * **URL String**: A URL to the the video file. Use this method if you are sure
12007   * the current playback technology (HTML5/Flash) can support the source you
12008   * provide. Currently only MP4 files can be used in both HTML5 and Flash.
12009   * ```js
12010   *     myPlayer.src("http://www.example.com/path/to/video.mp4");
12011   * ```
12012   * **Source Object (or element):* * A javascript object containing information
12013   * about the source file. Use this method if you want the player to determine if
12014   * it can support the file using the type information.
12015   * ```js
12016   *     myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" });
12017   * ```
12018   * **Array of Source Objects:* * To provide multiple versions of the source so
12019   * that it can be played using HTML5 across browsers you can use an array of
12020   * source objects. Video.js will detect which version is supported and load that
12021   * file.
12022   * ```js
12023   *     myPlayer.src([
12024   *       { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" },
12025   *       { type: "video/webm", src: "http://www.example.com/path/to/video.webm" },
12026   *       { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" }
12027   *     ]);
12028   * ```
12029   *
12030   * @param  {String|Object|Array=} source The source URL, object, or array of sources
12031   * @return {String} The current video source when getting
12032   * @return {String} The player when setting
12033   * @method src
12034   */
12035
12036  Player.prototype.src = function src(source) {
12037    if (source === undefined) {
12038      return this.techGet_('src');
12039    }
12040
12041    var currentTech = _techTechJs2['default'].getTech(this.techName_);
12042    // Support old behavior of techs being registered as components.
12043    // Remove once that deprecated behavior is removed.
12044    if (!currentTech) {
12045      currentTech = _componentJs2['default'].getComponent(this.techName_);
12046    }
12047
12048    // case: Array of source objects to choose from and pick the best to play
12049    if (Array.isArray(source)) {
12050      this.sourceList_(source);
12051
12052      // case: URL String (http://myvideo...)
12053    } else if (typeof source === 'string') {
12054        // create a source object from the string
12055        this.src({ src: source });
12056
12057        // case: Source object { src: '', type: '' ... }
12058      } else if (source instanceof Object) {
12059          // check if the source has a type and the loaded tech cannot play the source
12060          // if there's no type we'll just try the current tech
12061          if (source.type && !currentTech.canPlaySource(source)) {
12062            // create a source list with the current source and send through
12063            // the tech loop to check for a compatible technology
12064            this.sourceList_([source]);
12065          } else {
12066            this.cache_.src = source.src;
12067            this.currentType_ = source.type || '';
12068
12069            // wait until the tech is ready to set the source
12070            this.ready(function () {
12071
12072              // The setSource tech method was added with source handlers
12073              // so older techs won't support it
12074              // We need to check the direct prototype for the case where subclasses
12075              // of the tech do not support source handlers
12076              if (currentTech.prototype.hasOwnProperty('setSource')) {
12077                this.techCall_('setSource', source);
12078              } else {
12079                this.techCall_('src', source.src);
12080              }
12081
12082              if (this.options_.preload === 'auto') {
12083                this.load();
12084              }
12085
12086              if (this.options_.autoplay) {
12087                this.play();
12088              }
12089
12090              // Set the source synchronously if possible (#2326)
12091            }, true);
12092          }
12093        }
12094
12095    return this;
12096  };
12097
12098  /**
12099   * Handle an array of source objects
12100   *
12101   * @param  {Array} sources Array of source objects
12102   * @private
12103   * @method sourceList_
12104   */
12105
12106  Player.prototype.sourceList_ = function sourceList_(sources) {
12107    var sourceTech = this.selectSource(sources);
12108
12109    if (sourceTech) {
12110      if (sourceTech.tech === this.techName_) {
12111        // if this technology is already loaded, set the source
12112        this.src(sourceTech.source);
12113      } else {
12114        // load this technology with the chosen source
12115        this.loadTech_(sourceTech.tech, sourceTech.source);
12116      }
12117    } else {
12118      // We need to wrap this in a timeout to give folks a chance to add error event handlers
12119      this.setTimeout(function () {
12120        this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
12121      }, 0);
12122
12123      // we could not find an appropriate tech, but let's still notify the delegate that this is it
12124      // this needs a better comment about why this is needed
12125      this.triggerReady();
12126    }
12127  };
12128
12129  /**
12130   * Begin loading the src data.
12131   *
12132   * @return {Player} Returns the player
12133   * @method load
12134   */
12135
12136  Player.prototype.load = function load() {
12137    this.techCall_('load');
12138    return this;
12139  };
12140
12141  /**
12142   * Reset the player. Loads the first tech in the techOrder,
12143   * and calls `reset` on the tech`.
12144   *
12145   * @return {Player} Returns the player
12146   * @method reset
12147   */
12148
12149  Player.prototype.reset = function reset() {
12150    this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null);
12151    this.techCall_('reset');
12152    return this;
12153  };
12154
12155  /**
12156   * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
12157   * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
12158   *
12159   * @return {String} The current source
12160   * @method currentSrc
12161   */
12162
12163  Player.prototype.currentSrc = function currentSrc() {
12164    return this.techGet_('currentSrc') || this.cache_.src || '';
12165  };
12166
12167  /**
12168   * Get the current source type e.g. video/mp4
12169   * This can allow you rebuild the current source object so that you could load the same
12170   * source and tech later
12171   *
12172   * @return {String} The source MIME type
12173   * @method currentType
12174   */
12175
12176  Player.prototype.currentType = function currentType() {
12177    return this.currentType_ || '';
12178  };
12179
12180  /**
12181   * Get or set the preload attribute
12182   *
12183   * @param {Boolean} value Boolean to determine if preload should be used
12184   * @return {String} The preload attribute value when getting
12185   * @return {Player} Returns the player when setting
12186   * @method preload
12187   */
12188
12189  Player.prototype.preload = function preload(value) {
12190    if (value !== undefined) {
12191      this.techCall_('setPreload', value);
12192      this.options_.preload = value;
12193      return this;
12194    }
12195    return this.techGet_('preload');
12196  };
12197
12198  /**
12199   * Get or set the autoplay attribute.
12200   *
12201   * @param {Boolean} value Boolean to determine if video should autoplay
12202   * @return {String} The autoplay attribute value when getting
12203   * @return {Player} Returns the player when setting
12204   * @method autoplay
12205   */
12206
12207  Player.prototype.autoplay = function autoplay(value) {
12208    if (value !== undefined) {
12209      this.techCall_('setAutoplay', value);
12210      this.options_.autoplay = value;
12211      return this;
12212    }
12213    return this.techGet_('autoplay', value);
12214  };
12215
12216  /**
12217   * Get or set the loop attribute on the video element.
12218   *
12219   * @param {Boolean} value Boolean to determine if video should loop
12220   * @return {String} The loop attribute value when getting
12221   * @return {Player} Returns the player when setting
12222   * @method loop
12223   */
12224
12225  Player.prototype.loop = function loop(value) {
12226    if (value !== undefined) {
12227      this.techCall_('setLoop', value);
12228      this.options_['loop'] = value;
12229      return this;
12230    }
12231    return this.techGet_('loop');
12232  };
12233
12234  /**
12235   * Get or set the poster image source url
12236   *
12237   * ##### EXAMPLE:
12238   * ```js
12239   *     // get
12240   *     var currentPoster = myPlayer.poster();
12241   *     // set
12242   *     myPlayer.poster('http://example.com/myImage.jpg');
12243   * ```
12244   *
12245   * @param  {String=} src Poster image source URL
12246   * @return {String} poster URL when getting
12247   * @return {Player} self when setting
12248   * @method poster
12249   */
12250
12251  Player.prototype.poster = function poster(src) {
12252    if (src === undefined) {
12253      return this.poster_;
12254    }
12255
12256    // The correct way to remove a poster is to set as an empty string
12257    // other falsey values will throw errors
12258    if (!src) {
12259      src = '';
12260    }
12261
12262    // update the internal poster variable
12263    this.poster_ = src;
12264
12265    // update the tech's poster
12266    this.techCall_('setPoster', src);
12267
12268    // alert components that the poster has been set
12269    this.trigger('posterchange');
12270
12271    return this;
12272  };
12273
12274  /**
12275   * Some techs (e.g. YouTube) can provide a poster source in an
12276   * asynchronous way. We want the poster component to use this
12277   * poster source so that it covers up the tech's controls.
12278   * (YouTube's play button). However we only want to use this
12279   * soruce if the player user hasn't set a poster through
12280   * the normal APIs.
12281   *
12282   * @private
12283   * @method handleTechPosterChange_
12284   */
12285
12286  Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
12287    if (!this.poster_ && this.tech_ && this.tech_.poster) {
12288      this.poster_ = this.tech_.poster() || '';
12289
12290      // Let components know the poster has changed
12291      this.trigger('posterchange');
12292    }
12293  };
12294
12295  /**
12296   * Get or set whether or not the controls are showing.
12297   *
12298   * @param  {Boolean} bool Set controls to showing or not
12299   * @return {Boolean}    Controls are showing
12300   * @method controls
12301   */
12302
12303  Player.prototype.controls = function controls(bool) {
12304    if (bool !== undefined) {
12305      bool = !!bool; // force boolean
12306      // Don't trigger a change event unless it actually changed
12307      if (this.controls_ !== bool) {
12308        this.controls_ = bool;
12309
12310        if (this.usingNativeControls()) {
12311          this.techCall_('setControls', bool);
12312        }
12313
12314        if (bool) {
12315          this.removeClass('vjs-controls-disabled');
12316          this.addClass('vjs-controls-enabled');
12317          this.trigger('controlsenabled');
12318
12319          if (!this.usingNativeControls()) {
12320            this.addTechControlsListeners_();
12321          }
12322        } else {
12323          this.removeClass('vjs-controls-enabled');
12324          this.addClass('vjs-controls-disabled');
12325          this.trigger('controlsdisabled');
12326
12327          if (!this.usingNativeControls()) {
12328            this.removeTechControlsListeners_();
12329          }
12330        }
12331      }
12332      return this;
12333    }
12334    return !!this.controls_;
12335  };
12336
12337  /**
12338   * Toggle native controls on/off. Native controls are the controls built into
12339   * devices (e.g. default iPhone controls), Flash, or other techs
12340   * (e.g. Vimeo Controls)
12341   * **This should only be set by the current tech, because only the tech knows
12342   * if it can support native controls**
12343   *
12344   * @param  {Boolean} bool    True signals that native controls are on
12345   * @return {Player}      Returns the player
12346   * @private
12347   * @method usingNativeControls
12348   */
12349
12350  Player.prototype.usingNativeControls = function usingNativeControls(bool) {
12351    if (bool !== undefined) {
12352      bool = !!bool; // force boolean
12353      // Don't trigger a change event unless it actually changed
12354      if (this.usingNativeControls_ !== bool) {
12355        this.usingNativeControls_ = bool;
12356        if (bool) {
12357          this.addClass('vjs-using-native-controls');
12358
12359          /**
12360            * player is using the native device controls
12361           *
12362            * @event usingnativecontrols
12363            * @memberof Player
12364            * @instance
12365            * @private
12366            */
12367          this.trigger('usingnativecontrols');
12368        } else {
12369          this.removeClass('vjs-using-native-controls');
12370
12371          /**
12372            * player is using the custom HTML controls
12373           *
12374            * @event usingcustomcontrols
12375            * @memberof Player
12376            * @instance
12377            * @private
12378            */
12379          this.trigger('usingcustomcontrols');
12380        }
12381      }
12382      return this;
12383    }
12384    return !!this.usingNativeControls_;
12385  };
12386
12387  /**
12388   * Set or get the current MediaError
12389   *
12390   * @param  {*} err A MediaError or a String/Number to be turned into a MediaError
12391   * @return {MediaError|null}     when getting
12392   * @return {Player}              when setting
12393   * @method error
12394   */
12395
12396  Player.prototype.error = function error(err) {
12397    if (err === undefined) {
12398      return this.error_ || null;
12399    }
12400
12401    // restoring to default
12402    if (err === null) {
12403      this.error_ = err;
12404      this.removeClass('vjs-error');
12405      this.errorDisplay.close();
12406      return this;
12407    }
12408
12409    // error instance
12410    if (err instanceof _mediaErrorJs2['default']) {
12411      this.error_ = err;
12412    } else {
12413      this.error_ = new _mediaErrorJs2['default'](err);
12414    }
12415
12416    // add the vjs-error classname to the player
12417    this.addClass('vjs-error');
12418
12419    // log the name of the error type and any message
12420    // ie8 just logs "[object object]" if you just log the error object
12421    _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
12422
12423    // fire an error event on the player
12424    this.trigger('error');
12425
12426    return this;
12427  };
12428
12429  /**
12430   * Returns whether or not the player is in the "ended" state.
12431   *
12432   * @return {Boolean} True if the player is in the ended state, false if not.
12433   * @method ended
12434   */
12435
12436  Player.prototype.ended = function ended() {
12437    return this.techGet_('ended');
12438  };
12439
12440  /**
12441   * Returns whether or not the player is in the "seeking" state.
12442   *
12443   * @return {Boolean} True if the player is in the seeking state, false if not.
12444   * @method seeking
12445   */
12446
12447  Player.prototype.seeking = function seeking() {
12448    return this.techGet_('seeking');
12449  };
12450
12451  /**
12452   * Returns the TimeRanges of the media that are currently available
12453   * for seeking to.
12454   *
12455   * @return {TimeRanges} the seekable intervals of the media timeline
12456   * @method seekable
12457   */
12458
12459  Player.prototype.seekable = function seekable() {
12460    return this.techGet_('seekable');
12461  };
12462
12463  /**
12464   * Report user activity
12465   *
12466   * @param {Object} event Event object
12467   * @method reportUserActivity
12468   */
12469
12470  Player.prototype.reportUserActivity = function reportUserActivity(event) {
12471    this.userActivity_ = true;
12472  };
12473
12474  /**
12475   * Get/set if user is active
12476   *
12477   * @param {Boolean} bool Value when setting
12478   * @return {Boolean} Value if user is active user when getting
12479   * @method userActive
12480   */
12481
12482  Player.prototype.userActive = function userActive(bool) {
12483    if (bool !== undefined) {
12484      bool = !!bool;
12485      if (bool !== this.userActive_) {
12486        this.userActive_ = bool;
12487        if (bool) {
12488          // If the user was inactive and is now active we want to reset the
12489          // inactivity timer
12490          this.userActivity_ = true;
12491          this.removeClass('vjs-user-inactive');
12492          this.addClass('vjs-user-active');
12493          this.trigger('useractive');
12494        } else {
12495          // We're switching the state to inactive manually, so erase any other
12496          // activity
12497          this.userActivity_ = false;
12498
12499          // Chrome/Safari/IE have bugs where when you change the cursor it can
12500          // trigger a mousemove event. This causes an issue when you're hiding
12501          // the cursor when the user is inactive, and a mousemove signals user
12502          // activity. Making it impossible to go into inactive mode. Specifically
12503          // this happens in fullscreen when we really need to hide the cursor.
12504          //
12505          // When this gets resolved in ALL browsers it can be removed
12506          // https://code.google.com/p/chromium/issues/detail?id=103041
12507          if (this.tech_) {
12508            this.tech_.one('mousemove', function (e) {
12509              e.stopPropagation();
12510              e.preventDefault();
12511            });
12512          }
12513
12514          this.removeClass('vjs-user-active');
12515          this.addClass('vjs-user-inactive');
12516          this.trigger('userinactive');
12517        }
12518      }
12519      return this;
12520    }
12521    return this.userActive_;
12522  };
12523
12524  /**
12525   * Listen for user activity based on timeout value
12526   *
12527   * @private
12528   * @method listenForUserActivity_
12529   */
12530
12531  Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
12532    var mouseInProgress = undefined,
12533        lastMoveX = undefined,
12534        lastMoveY = undefined;
12535
12536    var handleActivity = Fn.bind(this, this.reportUserActivity);
12537
12538    var handleMouseMove = function handleMouseMove(e) {
12539      // #1068 - Prevent mousemove spamming
12540      // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
12541      if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
12542        lastMoveX = e.screenX;
12543        lastMoveY = e.screenY;
12544        handleActivity();
12545      }
12546    };
12547
12548    var handleMouseDown = function handleMouseDown() {
12549      handleActivity();
12550      // For as long as the they are touching the device or have their mouse down,
12551      // we consider them active even if they're not moving their finger or mouse.
12552      // So we want to continue to update that they are active
12553      this.clearInterval(mouseInProgress);
12554      // Setting userActivity=true now and setting the interval to the same time
12555      // as the activityCheck interval (250) should ensure we never miss the
12556      // next activityCheck
12557      mouseInProgress = this.setInterval(handleActivity, 250);
12558    };
12559
12560    var handleMouseUp = function handleMouseUp(event) {
12561      handleActivity();
12562      // Stop the interval that maintains activity if the mouse/touch is down
12563      this.clearInterval(mouseInProgress);
12564    };
12565
12566    // Any mouse movement will be considered user activity
12567    this.on('mousedown', handleMouseDown);
12568    this.on('mousemove', handleMouseMove);
12569    this.on('mouseup', handleMouseUp);
12570
12571    // Listen for keyboard navigation
12572    // Shouldn't need to use inProgress interval because of key repeat
12573    this.on('keydown', handleActivity);
12574    this.on('keyup', handleActivity);
12575
12576    // Run an interval every 250 milliseconds instead of stuffing everything into
12577    // the mousemove/touchmove function itself, to prevent performance degradation.
12578    // `this.reportUserActivity` simply sets this.userActivity_ to true, which
12579    // then gets picked up by this loop
12580    // http://ejohn.org/blog/learning-from-twitter/
12581    var inactivityTimeout = undefined;
12582    var activityCheck = this.setInterval(function () {
12583      // Check to see if mouse/touch activity has happened
12584      if (this.userActivity_) {
12585        // Reset the activity tracker
12586        this.userActivity_ = false;
12587
12588        // If the user state was inactive, set the state to active
12589        this.userActive(true);
12590
12591        // Clear any existing inactivity timeout to start the timer over
12592        this.clearTimeout(inactivityTimeout);
12593
12594        var timeout = this.options_['inactivityTimeout'];
12595        if (timeout > 0) {
12596          // In <timeout> milliseconds, if no more activity has occurred the
12597          // user will be considered inactive
12598          inactivityTimeout = this.setTimeout(function () {
12599            // Protect against the case where the inactivityTimeout can trigger just
12600            // before the next user activity is picked up by the activityCheck loop
12601            // causing a flicker
12602            if (!this.userActivity_) {
12603              this.userActive(false);
12604            }
12605          }, timeout);
12606        }
12607      }
12608    }, 250);
12609  };
12610
12611  /**
12612   * Gets or sets the current playback rate.  A playback rate of
12613   * 1.0 represents normal speed and 0.5 would indicate half-speed
12614   * playback, for instance.
12615   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
12616   *
12617   * @param  {Number} rate    New playback rate to set.
12618   * @return {Number}         Returns the new playback rate when setting
12619   * @return {Number}         Returns the current playback rate when getting
12620   * @method playbackRate
12621   */
12622
12623  Player.prototype.playbackRate = function playbackRate(rate) {
12624    if (rate !== undefined) {
12625      this.techCall_('setPlaybackRate', rate);
12626      return this;
12627    }
12628
12629    if (this.tech_ && this.tech_['featuresPlaybackRate']) {
12630      return this.techGet_('playbackRate');
12631    } else {
12632      return 1.0;
12633    }
12634  };
12635
12636  /**
12637   * Gets or sets the audio flag
12638   *
12639   * @param  {Boolean} bool    True signals that this is an audio player.
12640   * @return {Boolean}         Returns true if player is audio, false if not when getting
12641   * @return {Player}      Returns the player if setting
12642   * @private
12643   * @method isAudio
12644   */
12645
12646  Player.prototype.isAudio = function isAudio(bool) {
12647    if (bool !== undefined) {
12648      this.isAudio_ = !!bool;
12649      return this;
12650    }
12651
12652    return !!this.isAudio_;
12653  };
12654
12655  /**
12656   * Returns the current state of network activity for the element, from
12657   * the codes in the list below.
12658   * - NETWORK_EMPTY (numeric value 0)
12659   *   The element has not yet been initialised. All attributes are in
12660   *   their initial states.
12661   * - NETWORK_IDLE (numeric value 1)
12662   *   The element's resource selection algorithm is active and has
12663   *   selected a resource, but it is not actually using the network at
12664   *   this time.
12665   * - NETWORK_LOADING (numeric value 2)
12666   *   The user agent is actively trying to download data.
12667   * - NETWORK_NO_SOURCE (numeric value 3)
12668   *   The element's resource selection algorithm is active, but it has
12669   *   not yet found a resource to use.
12670   *
12671   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
12672   * @return {Number} the current network activity state
12673   * @method networkState
12674   */
12675
12676  Player.prototype.networkState = function networkState() {
12677    return this.techGet_('networkState');
12678  };
12679
12680  /**
12681   * Returns a value that expresses the current state of the element
12682   * with respect to rendering the current playback position, from the
12683   * codes in the list below.
12684   * - HAVE_NOTHING (numeric value 0)
12685   *   No information regarding the media resource is available.
12686   * - HAVE_METADATA (numeric value 1)
12687   *   Enough of the resource has been obtained that the duration of the
12688   *   resource is available.
12689   * - HAVE_CURRENT_DATA (numeric value 2)
12690   *   Data for the immediate current playback position is available.
12691   * - HAVE_FUTURE_DATA (numeric value 3)
12692   *   Data for the immediate current playback position is available, as
12693   *   well as enough data for the user agent to advance the current
12694   *   playback position in the direction of playback.
12695   * - HAVE_ENOUGH_DATA (numeric value 4)
12696   *   The user agent estimates that enough data is available for
12697   *   playback to proceed uninterrupted.
12698   *
12699   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
12700   * @return {Number} the current playback rendering state
12701   * @method readyState
12702   */
12703
12704  Player.prototype.readyState = function readyState() {
12705    return this.techGet_('readyState');
12706  };
12707
12708  /**
12709   * Get a video track list
12710   * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
12711   *
12712   * @return {VideoTrackList} thes current video track list
12713   * @method videoTracks
12714   */
12715
12716  Player.prototype.videoTracks = function videoTracks() {
12717    // if we have not yet loadTech_, we create videoTracks_
12718    // these will be passed to the tech during loading
12719    if (!this.tech_) {
12720      this.videoTracks_ = this.videoTracks_ || new _tracksVideoTrackListJs2['default']();
12721      return this.videoTracks_;
12722    }
12723
12724    return this.tech_.videoTracks();
12725  };
12726
12727  /**
12728   * Get an audio track list
12729   * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
12730   *
12731   * @return {AudioTrackList} thes current audio track list
12732   * @method audioTracks
12733   */
12734
12735  Player.prototype.audioTracks = function audioTracks() {
12736    // if we have not yet loadTech_, we create videoTracks_
12737    // these will be passed to the tech during loading
12738    if (!this.tech_) {
12739      this.audioTracks_ = this.audioTracks_ || new _tracksAudioTrackListJs2['default']();
12740      return this.audioTracks_;
12741    }
12742
12743    return this.tech_.audioTracks();
12744  };
12745
12746  /*
12747    * Text tracks are tracks of timed text events.
12748    * Captions - text displayed over the video for the hearing impaired
12749    * Subtitles - text displayed over the video for those who don't understand language in the video
12750    * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
12751    * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
12752    */
12753
12754  /**
12755   * Get an array of associated text tracks. captions, subtitles, chapters, descriptions
12756   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
12757   *
12758   * @return {Array}           Array of track objects
12759   * @method textTracks
12760   */
12761
12762  Player.prototype.textTracks = function textTracks() {
12763    // cannot use techGet_ directly because it checks to see whether the tech is ready.
12764    // Flash is unlikely to be ready in time but textTracks should still work.
12765    return this.tech_ && this.tech_['textTracks']();
12766  };
12767
12768  /**
12769   * Get an array of remote text tracks
12770   *
12771   * @return {Array}
12772   * @method remoteTextTracks
12773   */
12774
12775  Player.prototype.remoteTextTracks = function remoteTextTracks() {
12776    return this.tech_ && this.tech_['remoteTextTracks']();
12777  };
12778
12779  /**
12780   * Get an array of remote html track elements
12781   *
12782   * @return {HTMLTrackElement[]}
12783   * @method remoteTextTrackEls
12784   */
12785
12786  Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
12787    return this.tech_ && this.tech_['remoteTextTrackEls']();
12788  };
12789
12790  /**
12791   * Add a text track
12792   * In addition to the W3C settings we allow adding additional info through options.
12793   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
12794   *
12795   * @param {String}  kind        Captions, subtitles, chapters, descriptions, or metadata
12796   * @param {String=} label       Optional label
12797   * @param {String=} language    Optional language
12798   * @method addTextTrack
12799   */
12800
12801  Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
12802    return this.tech_ && this.tech_['addTextTrack'](kind, label, language);
12803  };
12804
12805  /**
12806   * Add a remote text track
12807   *
12808   * @param {Object} options    Options for remote text track
12809   * @method addRemoteTextTrack
12810   */
12811
12812  Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
12813    return this.tech_ && this.tech_['addRemoteTextTrack'](options);
12814  };
12815
12816  /**
12817   * Remove a remote text track
12818   *
12819   * @param {Object} track    Remote text track to remove
12820   * @method removeRemoteTextTrack
12821   */
12822  // destructure the input into an object with a track argument, defaulting to arguments[0]
12823  // default the whole argument to an empty object if nothing was passed in
12824
12825  Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
12826    var _ref3 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
12827
12828    var _ref3$track = _ref3.track;
12829    var track = _ref3$track === undefined ? arguments[0] : _ref3$track;
12830    // jshint ignore:line
12831    this.tech_ && this.tech_['removeRemoteTextTrack'](track);
12832  };
12833
12834  /**
12835   * Get video width
12836   *
12837   * @return {Number} Video width
12838   * @method videoWidth
12839   */
12840
12841  Player.prototype.videoWidth = function videoWidth() {
12842    return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12843  };
12844
12845  /**
12846   * Get video height
12847   *
12848   * @return {Number} Video height
12849   * @method videoHeight
12850   */
12851
12852  Player.prototype.videoHeight = function videoHeight() {
12853    return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12854  };
12855
12856  // Methods to add support for
12857  // initialTime: function(){ return this.techCall_('initialTime'); },
12858  // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
12859  // played: function(){ return this.techCall_('played'); },
12860  // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
12861  // defaultMuted: function(){ return this.techCall_('defaultMuted'); }
12862
12863  /**
12864   * The player's language code
12865   * NOTE: The language should be set in the player options if you want the
12866   * the controls to be built with a specific language. Changing the lanugage
12867   * later will not update controls text.
12868   *
12869   * @param {String} code  The locale string
12870   * @return {String}      The locale string when getting
12871   * @return {Player}      self when setting
12872   * @method language
12873   */
12874
12875  Player.prototype.language = function language(code) {
12876    if (code === undefined) {
12877      return this.language_;
12878    }
12879
12880    this.language_ = ('' + code).toLowerCase();
12881    return this;
12882  };
12883
12884  /**
12885   * Get the player's language dictionary
12886   * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12887   * Languages specified directly in the player options have precedence
12888   *
12889   * @return {Array} Array of languages
12890   * @method languages
12891   */
12892
12893  Player.prototype.languages = function languages() {
12894    return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_);
12895  };
12896
12897  /**
12898   * Converts track info to JSON
12899   *
12900   * @return {Object} JSON object of options
12901   * @method toJSON
12902   */
12903
12904  Player.prototype.toJSON = function toJSON() {
12905    var options = _utilsMergeOptionsJs2['default'](this.options_);
12906    var tracks = options.tracks;
12907
12908    options.tracks = [];
12909
12910    for (var i = 0; i < tracks.length; i++) {
12911      var track = tracks[i];
12912
12913      // deep merge tracks and null out player so no circular references
12914      track = _utilsMergeOptionsJs2['default'](track);
12915      track.player = undefined;
12916      options.tracks[i] = track;
12917    }
12918
12919    return options;
12920  };
12921
12922  /**
12923   * Creates a simple modal dialog (an instance of the `ModalDialog`
12924   * component) that immediately overlays the player with arbitrary
12925   * content and removes itself when closed.
12926   *
12927   * @param {String|Function|Element|Array|Null} content
12928   *        Same as `ModalDialog#content`'s param of the same name.
12929   *
12930   *        The most straight-forward usage is to provide a string or DOM
12931   *        element.
12932   *
12933   * @param {Object} [options]
12934   *        Extra options which will be passed on to the `ModalDialog`.
12935   *
12936   * @return {ModalDialog}
12937   */
12938
12939  Player.prototype.createModal = function createModal(content, options) {
12940    var player = this;
12941
12942    options = options || {};
12943    options.content = content || '';
12944
12945    var modal = new _modalDialog2['default'](player, options);
12946
12947    player.addChild(modal);
12948    modal.on('dispose', function () {
12949      player.removeChild(modal);
12950    });
12951
12952    return modal.open();
12953  };
12954
12955  /**
12956   * Gets tag settings
12957   *
12958   * @param {Element} tag The player tag
12959   * @return {Array} An array of sources and track objects
12960   * @static
12961   * @method getTagSettings
12962   */
12963
12964  Player.getTagSettings = function getTagSettings(tag) {
12965    var baseOptions = {
12966      'sources': [],
12967      'tracks': []
12968    };
12969
12970    var tagOptions = Dom.getElAttributes(tag);
12971    var dataSetup = tagOptions['data-setup'];
12972
12973    // Check if data-setup attr exists.
12974    if (dataSetup !== null) {
12975      // Parse options JSON
12976
12977      var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}');
12978
12979      var err = _safeParseTuple[0];
12980      var data = _safeParseTuple[1];
12981
12982      if (err) {
12983        _utilsLogJs2['default'].error(err);
12984      }
12985      _objectAssign2['default'](tagOptions, data);
12986    }
12987
12988    _objectAssign2['default'](baseOptions, tagOptions);
12989
12990    // Get tag children settings
12991    if (tag.hasChildNodes()) {
12992      var children = tag.childNodes;
12993
12994      for (var i = 0, j = children.length; i < j; i++) {
12995        var child = children[i];
12996        // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12997        var childName = child.nodeName.toLowerCase();
12998        if (childName === 'source') {
12999          baseOptions.sources.push(Dom.getElAttributes(child));
13000        } else if (childName === 'track') {
13001          baseOptions.tracks.push(Dom.getElAttributes(child));
13002        }
13003      }
13004    }
13005
13006    return baseOptions;
13007  };
13008
13009  return Player;
13010})(_componentJs2['default']);
13011
13012Player.players = {};
13013
13014var navigator = _globalWindow2['default'].navigator;
13015/*
13016 * Player instance options, surfaced using options
13017 * options = Player.prototype.options_
13018 * Make changes in options, not here.
13019 *
13020 * @type {Object}
13021 * @private
13022 */
13023Player.prototype.options_ = {
13024  // Default order of fallback technology
13025  techOrder: ['html5', 'flash'],
13026  // techOrder: ['flash','html5'],
13027
13028  html5: {},
13029  flash: {},
13030
13031  // defaultVolume: 0.85,
13032  defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
13033
13034  // default inactivity timeout
13035  inactivityTimeout: 2000,
13036
13037  // default playback rates
13038  playbackRates: [],
13039  // Add playback rate selection by adding rates
13040  // 'playbackRates': [0.5, 1, 1.5, 2],
13041
13042  // Included control sets
13043  children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
13044
13045  language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',
13046
13047  // locales and their language translations
13048  languages: {},
13049
13050  // Default message to show when a video cannot be played.
13051  notSupportedMessage: 'No compatible source was found for this media.'
13052};
13053
13054/**
13055 * Fired when the player has initial duration and dimension information
13056 *
13057 * @event loadedmetadata
13058 */
13059Player.prototype.handleLoadedMetaData_;
13060
13061/**
13062 * Fired when the player has downloaded data at the current playback position
13063 *
13064 * @event loadeddata
13065 */
13066Player.prototype.handleLoadedData_;
13067
13068/**
13069 * Fired when the user is active, e.g. moves the mouse over the player
13070 *
13071 * @event useractive
13072 */
13073Player.prototype.handleUserActive_;
13074
13075/**
13076 * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction
13077 *
13078 * @event userinactive
13079 */
13080Player.prototype.handleUserInactive_;
13081
13082/**
13083 * Fired when the current playback position has changed *
13084 * During playback this is fired every 15-250 milliseconds, depending on the
13085 * playback technology in use.
13086 *
13087 * @event timeupdate
13088 */
13089Player.prototype.handleTimeUpdate_;
13090
13091/**
13092 * Fired when video playback ends
13093 *
13094 * @event ended
13095 */
13096Player.prototype.handleTechEnded_;
13097
13098/**
13099 * Fired when the volume changes
13100 *
13101 * @event volumechange
13102 */
13103Player.prototype.handleVolumeChange_;
13104
13105/**
13106 * Fired when an error occurs
13107 *
13108 * @event error
13109 */
13110Player.prototype.handleError_;
13111
13112Player.prototype.flexNotSupported_ = function () {
13113  var elem = _globalDocument2['default'].createElement('i');
13114
13115  // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
13116  // common flex features that we can rely on when checking for flex support.
13117  return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 'msFlexOrder' in elem.style) /* IE10-specific (2012 flex spec)  */;
13118};
13119
13120_componentJs2['default'].registerComponent('Player', Player);
13121exports['default'] = Player;
13122module.exports = exports['default'];
13123// If empty string, make it a parsable json object.
13124
13125},{"./big-play-button.js":63,"./component.js":67,"./control-bar/control-bar.js":70,"./error-display.js":103,"./fullscreen-api.js":106,"./loading-spinner.js":107,"./media-error.js":108,"./modal-dialog":112,"./poster-image.js":117,"./tech/html5.js":122,"./tech/loader.js":123,"./tech/tech.js":124,"./tracks/audio-track-list.js":125,"./tracks/text-track-display.js":130,"./tracks/text-track-list-converter.js":131,"./tracks/text-track-settings.js":133,"./tracks/video-track-list.js":138,"./utils/browser.js":140,"./utils/buffer.js":141,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/guid.js":147,"./utils/log.js":148,"./utils/merge-options.js":149,"./utils/stylesheet.js":150,"./utils/time-ranges.js":151,"./utils/to-title-case.js":152,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":54}],114:[function(_dereq_,module,exports){
13126/**
13127 * @file plugins.js
13128 */
13129'use strict';
13130
13131exports.__esModule = true;
13132
13133function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13134
13135var _playerJs = _dereq_('./player.js');
13136
13137var _playerJs2 = _interopRequireDefault(_playerJs);
13138
13139/**
13140 * The method for registering a video.js plugin
13141 *
13142 * @param  {String} name The name of the plugin
13143 * @param  {Function} init The function that is run when the player inits
13144 * @method plugin
13145 */
13146var plugin = function plugin(name, init) {
13147  _playerJs2['default'].prototype[name] = init;
13148};
13149
13150exports['default'] = plugin;
13151module.exports = exports['default'];
13152
13153},{"./player.js":113}],115:[function(_dereq_,module,exports){
13154/**
13155 * @file popup-button.js
13156 */
13157'use strict';
13158
13159exports.__esModule = true;
13160
13161function _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; } }
13162
13163function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13164
13165function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13166
13167function _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, { c
13167onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
13168
13169var _clickableComponentJs = _dereq_('../clickable-component.js');
13170
13171var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
13172
13173var _componentJs = _dereq_('../component.js');
13174
13175var _componentJs2 = _interopRequireDefault(_componentJs);
13176
13177var _popupJs = _dereq_('./popup.js');
13178
13179var _popupJs2 = _interopRequireDefault(_popupJs);
13180
13181var _utilsDomJs = _dereq_('../utils/dom.js');
13182
13183var Dom = _interopRequireWildcard(_utilsDomJs);
13184
13185var _utilsFnJs = _dereq_('../utils/fn.js');
13186
13187var Fn = _interopRequireWildcard(_utilsFnJs);
13188
13189var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
13190
13191var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
13192
13193/**
13194 * A button class with a popup control
13195 *
13196 * @param {Player|Object} player
13197 * @param {Object=} options
13198 * @extends ClickableComponent
13199 * @class PopupButton
13200 */
13201
13202var PopupButton = (function (_ClickableComponent) {
13203  _inherits(PopupButton, _ClickableComponent);
13204
13205  function PopupButton(player) {
13206    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
13207
13208    _classCallCheck(this, PopupButton);
13209
13210    _ClickableComponent.call(this, player, options);
13211
13212    this.update();
13213  }
13214
13215  /**
13216   * Update popup
13217   *
13218   * @method update
13219   */
13220
13221  PopupButton.prototype.update = function update() {
13222    var popup = this.createPopup();
13223
13224    if (this.popup) {
13225      this.removeChild(this.popup);
13226    }
13227
13228    this.popup = popup;
13229    this.addChild(popup);
13230
13231    if (this.items && this.items.length === 0) {
13232      this.hide();
13233    } else if (this.items && this.items.length > 1) {
13234      this.show();
13235    }
13236  };
13237
13238  /**
13239   * Create popup - Override with specific functionality for component
13240   *
13241   * @return {Popup} The constructed popup
13242   * @method createPopup
13243   */
13244
13245  PopupButton.prototype.createPopup = function createPopup() {};
13246
13247  /**
13248   * Create the component's DOM element
13249   *
13250   * @return {Element}
13251   * @method createEl
13252   */
13253
13254  PopupButton.prototype.createEl = function createEl() {
13255    return _ClickableComponent.prototype.createEl.call(this, 'div', {
13256      className: this.buildCSSClass()
13257    });
13258  };
13259
13260  /**
13261   * Allow sub components to stack CSS class names
13262   *
13263   * @return {String} The constructed class name
13264   * @method buildCSSClass
13265   */
13266
13267  PopupButton.prototype.buildCSSClass = function buildCSSClass() {
13268    var menuButtonClass = 'vjs-menu-button';
13269
13270    // If the inline option is passed, we want to use different styles altogether.
13271    if (this.options_.inline === true) {
13272      menuButtonClass += '-inline';
13273    } else {
13274      menuButtonClass += '-popup';
13275    }
13276
13277    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
13278  };
13279
13280  return PopupButton;
13281})(_clickableComponentJs2['default']);
13282
13283_componentJs2['default'].registerComponent('PopupButton', PopupButton);
13284exports['default'] = PopupButton;
13285module.exports = exports['default'];
13286
13287},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/to-title-case.js":152,"./popup.js":116}],116:[function(_dereq_,module,exports){
13288/**
13289 * @file popup.js
13290 */
13291'use strict';
13292
13293exports.__esModule = true;
13294
13295function _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; } }
13296
13297function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13298
13299function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13300
13301function _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, { c
13301onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
13302
13303var _componentJs = _dereq_('../component.js');
13304
13305var _componentJs2 = _interopRequireDefault(_componentJs);
13306
13307var _utilsDomJs = _dereq_('../utils/dom.js');
13308
13309var Dom = _interopRequireWildcard(_utilsDomJs);
13310
13311var _utilsFnJs = _dereq_('../utils/fn.js');
13312
13313var Fn = _interopRequireWildcard(_utilsFnJs);
13314
13315var _utilsEventsJs = _dereq_('../utils/events.js');
13316
13317var Events = _interopRequireWildcard(_utilsEventsJs);
13318
13319/**
13320 * The Popup component is used to build pop up controls.
13321 *
13322 * @extends Component
13323 * @class Popup
13324 */
13325
13326var Popup = (function (_Component) {
13327  _inherits(Popup, _Component);
13328
13329  function Popup() {
13330    _classCallCheck(this, Popup);
13331
13332    _Component.apply(this, arguments);
13333  }
13334
13335  /**
13336   * Add a popup item to the popup
13337   *
13338   * @param {Object|String} component Component or component type to add
13339   * @method addItem
13340   */
13341
13342  Popup.prototype.addItem = function addItem(component) {
13343    this.addChild(component);
13344    component.on('click', Fn.bind(this, function () {
13345      this.unlockShowing();
13346    }));
13347  };
13348
13349  /**
13350   * Create the component's DOM element
13351   *
13352   * @return {Element}
13353   * @method createEl
13354   */
13355
13356  Popup.prototype.createEl = function createEl() {
13357    var contentElType = this.options_.contentElType || 'ul';
13358    this.contentEl_ = Dom.createEl(contentElType, {
13359      className: 'vjs-menu-content'
13360    });
13361    var el = _Component.prototype.createEl.call(this, 'div', {
13362      append: this.contentEl_,
13363      className: 'vjs-menu'
13364    });
13365    el.appendChild(this.contentEl_);
13366
13367    // Prevent clicks from bubbling up. Needed for Popup Buttons,
13368    // where a click on the parent is significant
13369    Events.on(el, 'click', function (event) {
13370      event.preventDefault();
13371      event.stopImmediatePropagation();
13372    });
13373
13374    return el;
13375  };
13376
13377  return Popup;
13378})(_componentJs2['default']);
13379
13380_componentJs2['default'].registerComponent('Popup', Popup);
13381exports['default'] = Popup;
13382module.exports = exports['default'];
13383
13384},{"../component.js":67,"../utils/dom.js":143,"../utils/events.js":144,"../utils/fn.js":145}],117:[function(_dereq_,module,exports){
13385/**
13386 * @file poster-image.js
13387 */
13388'use strict';
13389
13390exports.__esModule = true;
13391
13392function _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; } }
13393
13394function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13395
13396function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13397
13398function _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; }
13399
13400var _clickableComponentJs = _dereq_('./clickable-component.js');
13401
13402var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
13403
13404var _componentJs = _dereq_('./component.js');
13405
13406var _componentJs2 = _interopRequireDefault(_componentJs);
13407
13408var _utilsFnJs = _dereq_('./utils/fn.js');
13409
13410var Fn = _interopRequireWildcard(_utilsFnJs);
13411
13412var _utilsDomJs = _dereq_('./utils/dom.js');
13413
13414var Dom = _interopRequireWildcard(_utilsDomJs);
13415
13416var _utilsBrowserJs = _dereq_('./utils/browser.js');
13417
13418var browser = _interopRequireWildcard(_utilsBrowserJs);
13419
13420/**
13421 * The component that handles showing the poster image.
13422 *
13423 * @param {Player|Object} player
13424 * @param {Object=} options
13425 * @extends Button
13426 * @class PosterImage
13427 */
13428
13429var PosterImage = (function (_ClickableComponent) {
13430  _inherits(PosterImage, _ClickableComponent);
13431
13432  function PosterImage(player, options) {
13433    _classCallCheck(this, PosterImage);
13434
13435    _ClickableComponent.call(this, player, options);
13436
13437    this.update();
13438    player.on('posterchange', Fn.bind(this, this.update));
13439  }
13440
13441  /**
13442   * Clean up the poster image
13443   *
13444   * @method dispose
13445   */
13446
13447  PosterImage.prototype.dispose = function dispose() {
13448    this.player().off('posterchange', this.update);
13449    _ClickableComponent.prototype.dispose.call(this);
13450  };
13451
13452  /**
13453   * Create the poster's image element
13454   *
13455   * @return {Element}
13456   * @method createEl
13457   */
13458
13459  PosterImage.prototype.createEl = function createEl() {
13460    var el = Dom.createEl('div', {
13461      className: 'vjs-poster',
13462
13463      // Don't want poster to be tabbable.
13464      tabIndex: -1
13465    });
13466
13467    // To ensure the poster image resizes while maintaining its original aspect
13468    // ratio, use a div with `background-size` when available. For browsers that
13469    // do not support `background-size` (e.g. IE8), fall back on using a regular
13470    // img element.
13471    if (!browser.BACKGROUND_SIZE_SUPPORTED) {
13472      this.fallbackImg_ = Dom.createEl('img');
13473      el.appendChild(this.fallbackImg_);
13474    }
13475
13476    return el;
13477  };
13478
13479  /**
13480   * Event handler for updates to the player's poster source
13481   *
13482   * @method update
13483   */
13484
13485  PosterImage.prototype.update = function update() {
13486    var url = this.player().poster();
13487
13488    this.setSrc(url);
13489
13490    // If there's no poster source we should display:none on this component
13491    // so it's not still clickable or right-clickable
13492    if (url) {
13493      this.show();
13494    } else {
13495      this.hide();
13496    }
13497  };
13498
13499  /**
13500   * Set the poster source depending on the display method
13501   *
13502   * @param {String} url The URL to the poster source
13503   * @method setSrc
13504   */
13505
13506  PosterImage.prototype.setSrc = function setSrc(url) {
13507    if (this.fallbackImg_) {
13508      this.fallbackImg_.src = url;
13509    } else {
13510      var backgroundImage = '';
13511      // Any falsey values should stay as an empty string, otherwise
13512      // this will throw an extra error
13513      if (url) {
13514        backgroundImage = 'url("' + url + '")';
13515      }
13516
13517      this.el_.style.backgroundImage = backgroundImage;
13518    }
13519  };
13520
13521  /**
13522   * Event handler for clicks on the poster image
13523   *
13524   * @method handleClick
13525   */
13526
13527  PosterImage.prototype.handleClick = function handleClick() {
13528    // We don't want a click to trigger playback when controls are disabled
13529    // but CSS should be hiding the poster to prevent that from happening
13530    if (this.player_.paused()) {
13531      this.player_.play();
13532    } else {
13533      this.player_.pause();
13534    }
13535  };
13536
13537  return PosterImage;
13538})(_clickableComponentJs2['default']);
13539
13540_componentJs2['default'].registerComponent('PosterImage', PosterImage);
13541exports['default'] = PosterImage;
13542module.exports = exports['default'];
13543
13544},{"./clickable-component.js":65,"./component.js":67,"./utils/browser.js":140,"./utils/dom.js":143,"./utils/fn.js":145}],118:[function(_dereq_,module,exports){
13545/**
13546 * @file setup.js
13547 *
13548 * Functions for automatically setting up a player
13549 * based on the data-setup attribute of the video tag
13550 */
13551'use strict';
13552
13553exports.__esModule = true;
13554
13555function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13556
13557function _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; } }
13558
13559var _utilsEventsJs = _dereq_('./utils/events.js');
13560
13561var Events = _interopRequireWildcard(_utilsEventsJs);
13562
13563var _globalDocument = _dereq_('global/document');
13564
13565var _globalDocument2 = _interopRequireDefault(_globalDocument);
13566
13567var _globalWindow = _dereq_('global/window');
13568
13569var _globalWindow2 = _interopRequireDefault(_globalWindow);
13570
13571var _windowLoaded = false;
13572var videojs = undefined;
13573
13574// Automatically set up any tags that have a data-setup attribute
13575var autoSetup = function autoSetup() {
13576  // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
13577  // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
13578  // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
13579  // var mediaEls = vids.concat(audios);
13580
13581  // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements
13582  // to build up a new, combined list of elements.
13583  var vids = _globalDocument2['default'].getElementsByTagName('video');
13584  var audios = _globalDocument2['default'].getElementsByTagName('audio');
13585  var mediaEls = [];
13586  if (vids && vids.length > 0) {
13587    for (var i = 0, e = vids.length; i < e; i++) {
13588      mediaEls.push(vids[i]);
13589    }
13590  }
13591  if (audios && audios.length > 0) {
13592    for (var i = 0, e = audios.length; i < e; i++) {
13593      mediaEls.push(audios[i]);
13594    }
13595  }
13596
13597  // Check if any media elements exist
13598  if (mediaEls && mediaEls.length > 0) {
13599
13600    for (var i = 0, e = mediaEls.length; i < e; i++) {
13601      var mediaEl = mediaEls[i];
13602
13603      // Check if element exists, has getAttribute func.
13604      // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately.
13605      if (mediaEl && mediaEl.getAttribute) {
13606
13607        // Make sure this player hasn't already been set up.
13608        if (mediaEl['player'] === undefined) {
13609          var options = mediaEl.getAttribute('data-setup');
13610
13611          // Check if data-setup attr exists.
13612          // We only auto-setup if they've added the data-setup attr.
13613          if (options !== null) {
13614            // Create new video.js instance.
13615            var player = videojs(mediaEl);
13616          }
13617        }
13618
13619        // If getAttribute isn't defined, we need to wait for the DOM.
13620      } else {
13621          autoSetupTimeout(1);
13622          break;
13623        }
13624    }
13625
13626    // No videos were found, so keep looping unless page is finished loading.
13627  } else if (!_windowLoaded) {
13628      autoSetupTimeout(1);
13629    }
13630};
13631
13632// Pause to let the DOM keep processing
13633var autoSetupTimeout = function autoSetupTimeout(wait, vjs) {
13634  if (vjs) {
13635    videojs = vjs;
13636  }
13637
13638  setTimeout(autoSetup, wait);
13639};
13640
13641if (_globalDocument2['default'].readyState === 'complete') {
13642  _windowLoaded = true;
13643} else {
13644  Events.one(_globalWindow2['default'], 'load', function () {
13645    _windowLoaded = true;
13646  });
13647}
13648
13649var hasLoaded = function hasLoaded() {
13650  return _windowLoaded;
13651};
13652
13653exports.autoSetup = autoSetup;
13654exports.autoSetupTimeout = autoSetupTimeout;
13655exports.hasLoaded = hasLoaded;
13656
13657},{"./utils/events.js":144,"global/document":1,"global/window":2}],119:[function(_dereq_,module,exports){
13658/**
13659 * @file slider.js
13660 */
13661'use strict';
13662
13663exports.__esModule = true;
13664
13665function _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; } }
13666
13667function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13668
13669function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13670
13671function _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, { c
13671onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
13672
13673var _componentJs = _dereq_('../component.js');
13674
13675var _componentJs2 = _interopRequireDefault(_componentJs);
13676
13677var _utilsDomJs = _dereq_('../utils/dom.js');
13678
13679var Dom = _interopRequireWildcard(_utilsDomJs);
13680
13681var _objectAssign = _dereq_('object.assign');
13682
13683var _objectAssign2 = _interopRequireDefault(_objectAssign);
13684
13685/**
13686 * The base functionality for sliders like the volume bar and seek bar
13687 *
13688 * @param {Player|Object} player
13689 * @param {Object=} options
13690 * @extends Component
13691 * @class Slider
13692 */
13693
13694var Slider = (function (_Component) {
13695  _inherits(Slider, _Component);
13696
13697  function Slider(player, options) {
13698    _classCallCheck(this, Slider);
13699
13700    _Component.call(this, player, options);
13701
13702    // Set property names to bar to match with the child Slider class is looking for
13703    this.bar = this.getChild(this.options_.barName);
13704
13705    // Set a horizontal or vertical class on the slider depending on the slider type
13706    this.vertical(!!this.options_.vertical);
13707
13708    this.on('mousedown', this.handleMouseDown);
13709    this.on('touchstart', this.handleMouseDown);
13710    this.on('focus', this.handleFocus);
13711    this.on('blur', this.handleBlur);
13712    this.on('click', this.handleClick);
13713
13714    this.on(player, 'controlsvisible', this.update);
13715    this.on(player, this.playerEvent, this.update);
13716  }
13717
13718  /**
13719   * Create the component's DOM element
13720   *
13721   * @param {String} type Type of element to create
13722   * @param {Object=} props List of properties in Object form
13723   * @return {Element}
13724   * @method createEl
13725   */
13726
13727  Slider.prototype.createEl = function createEl(type) {
13728    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
13729    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
13730
13731    // Add the slider element class to all sub classes
13732    props.className = props.className + ' vjs-slider';
13733    props = _objectAssign2['default']({
13734      tabIndex: 0
13735    }, props);
13736
13737    attributes = _objectAssign2['default']({
13738      'role': 'slider',
13739      'aria-valuenow': 0,
13740      'aria-valuemin': 0,
13741      'aria-valuemax': 100,
13742      tabIndex: 0
13743    }, attributes);
13744
13745    return _Component.prototype.createEl.call(this, type, props, attributes);
13746  };
13747
13748  /**
13749   * Handle mouse down on slider
13750   *
13751   * @param {Object} event Mouse down event object
13752   * @method handleMouseDown
13753   */
13754
13755  Slider.prototype.handleMouseDown = function handleMouseDown(event) {
13756    var doc = this.bar.el_.ownerDocument;
13757
13758    event.preventDefault();
13759    Dom.blockTextSelection();
13760
13761    this.addClass('vjs-sliding');
13762    this.trigger('slideractive');
13763
13764    this.on(doc, 'mousemove', this.handleMouseMove);
13765    this.on(doc, 'mouseup', this.handleMouseUp);
13766    this.on(doc, 'touchmove', this.handleMouseMove);
13767    this.on(doc, 'touchend', this.handleMouseUp);
13768
13769    this.handleMouseMove(event);
13770  };
13771
13772  /**
13773   * To be overridden by a subclass
13774   *
13775   * @method handleMouseMove
13776   */
13777
13778  Slider.prototype.handleMouseMove = function handleMouseMove() {};
13779
13780  /**
13781   * Handle mouse up on Slider
13782   *
13783   * @method handleMouseUp
13784   */
13785
13786  Slider.prototype.handleMouseUp = function handleMouseUp() {
13787    var doc = this.bar.el_.ownerDocument;
13788
13789    Dom.unblockTextSelection();
13790
13791    this.removeClass('vjs-sliding');
13792    this.trigger('sliderinactive');
13793
13794    this.off(doc, 'mousemove', this.handleMouseMove);
13795    this.off(doc, 'mouseup', this.handleMouseUp);
13796    this.off(doc, 'touchmove', this.handleMouseMove);
13797    this.off(doc, 'touchend', this.handleMouseUp);
13798
13799    this.update();
13800  };
13801
13802  /**
13803   * Update slider
13804   *
13805   * @method update
13806   */
13807
13808  Slider.prototype.update = function update() {
13809    // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
13810    // execution stack. The player is destroyed before then update will cause an error
13811    if (!this.el_) return;
13812
13813    // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
13814    // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
13815    // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
13816    var progress = this.getPercent();
13817    var bar = this.bar;
13818
13819    // If there's no bar...
13820    if (!bar) return;
13821
13822    // Protect against no duration and other division issues
13823    if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
13824      progress = 0;
13825    }
13826
13827    // Convert to a percentage for setting
13828    var percentage = (progress * 100).toFixed(2) + '%';
13829
13830    // Set the new bar width or height
13831    if (this.vertical()) {
13832      bar.el().style.height = percentage;
13833    } else {
13834      bar.el().style.width = percentage;
13835    }
13836  };
13837
13838  /**
13839   * Calculate distance for slider
13840   *
13841   * @param {Object} event Event object
13842   * @method calculateDistance
13843   */
13844
13845  Slider.prototype.calculateDistance = function calculateDistance(event) {
13846    var position = Dom.getPointerPosition(this.el_, event);
13847    if (this.vertical()) {
13848      return position.y;
13849    }
13850    return position.x;
13851  };
13852
13853  /**
13854   * Handle on focus for slider
13855   *
13856   * @method handleFocus
13857   */
13858
13859  Slider.prototype.handleFocus = function handleFocus() {
13860    this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13861  };
13862
13863  /**
13864   * Handle key press for slider
13865   *
13866   * @param {Object} event Event object
13867   * @method handleKeyPress
13868   */
13869
13870  Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13871    if (event.which === 37 || event.which === 40) {
13872      // Left and Down Arrows
13873      event.preventDefault();
13874      this.stepBack();
13875    } else if (event.which === 38 || event.which === 39) {
13876      // Up and Right Arrows
13877      event.preventDefault();
13878      this.stepForward();
13879    }
13880  };
13881
13882  /**
13883   * Handle on blur for slider
13884   *
13885   * @method handleBlur
13886   */
13887
13888  Slider.prototype.handleBlur = function handleBlur() {
13889    this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13890  };
13891
13892  /**
13893   * Listener for click events on slider, used to prevent clicks
13894   *   from bubbling up to parent elements like button menus.
13895   *
13896   * @param {Object} event Event object
13897   * @method handleClick
13898   */
13899
13900  Slider.prototype.handleClick = function handleClick(event) {
13901    event.stopImmediatePropagation();
13902    event.preventDefault();
13903  };
13904
13905  /**
13906   * Get/set if slider is horizontal for vertical
13907   *
13908   * @param {Boolean} bool True if slider is vertical, false is horizontal
13909   * @return {Boolean} True if slider is vertical, false is horizontal
13910   * @method vertical
13911   */
13912
13913  Slider.prototype.vertical = function vertical(bool) {
13914    if (bool === undefined) {
13915      return this.vertical_ || false;
13916    }
13917
13918    this.vertical_ = !!bool;
13919
13920    if (this.vertical_) {
13921      this.addClass('vjs-slider-vertical');
13922    } else {
13923      this.addClass('vjs-slider-horizontal');
13924    }
13925
13926    return this;
13927  };
13928
13929  return Slider;
13930})(_componentJs2['default']);
13931
13932_componentJs2['default'].registerComponent('Slider', Slider);
13933exports['default'] = Slider;
13934module.exports = exports['default'];
13935
13936},{"../component.js":67,"../utils/dom.js":143,"object.assign":45}],120:[function(_dereq_,module,exports){
13937/**
13938 * @file flash-rtmp.js
13939 */
13940'use strict';
13941
13942exports.__esModule = true;
13943function FlashRtmpDecorator(Flash) {
13944  Flash.streamingFormats = {
13945    'rtmp/mp4': 'MP4',
13946    'rtmp/flv': 'FLV'
13947  };
13948
13949  Flash.streamFromParts = function (connection, stream) {
13950    return connection + '&' + stream;
13951  };
13952
13953  Flash.streamToParts = function (src) {
13954    var parts = {
13955      connection: '',
13956      stream: ''
13957    };
13958
13959    if (!src) return parts;
13960
13961    // Look for the normal URL separator we expect, '&'.
13962    // If found, we split the URL into two pieces around the
13963    // first '&'.
13964    var connEnd = src.search(/&(?!\w+=)/);
13965    var streamBegin = undefined;
13966    if (connEnd !== -1) {
13967      streamBegin = connEnd + 1;
13968    } else {
13969      // If there's not a '&', we use the last '/' as the delimiter.
13970      connEnd = streamBegin = src.lastIndexOf('/') + 1;
13971      if (connEnd === 0) {
13972        // really, there's not a '/'?
13973        connEnd = streamBegin = src.length;
13974      }
13975    }
13976    parts.connection = src.substring(0, connEnd);
13977    parts.stream = src.substring(streamBegin, src.length);
13978
13979    return parts;
13980  };
13981
13982  Flash.isStreamingType = function (srcType) {
13983    return srcType in Flash.streamingFormats;
13984  };
13985
13986  // RTMP has four variations, any string starting
13987  // with one of these protocols should be valid
13988  Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13989
13990  Flash.isStreamingSrc = function (src) {
13991    return Flash.RTMP_RE.test(src);
13992  };
13993
13994  /**
13995   * A source handler for RTMP urls
13996   * @type {Object}
13997   */
13998  Flash.rtmpSourceHandler = {};
13999
14000  /**
14001   * Check if Flash can play the given videotype
14002   * @param  {String} type    The mimetype to check
14003   * @return {String}         'probably', 'maybe', or '' (empty string)
14004   */
14005  Flash.rtmpSourceHandler.canPlayType = function (type) {
14006    if (Flash.isStreamingType(type)) {
14007      return 'maybe';
14008    }
14009
14010    return '';
14011  };
14012
14013  /**
14014   * Check if Flash can handle the source natively
14015   * @param  {Object} source  The source object
14016   * @return {String}         'probably', 'maybe', or '' (empty string)
14017   */
14018  Flash.rtmpSourceHandler.canHandleSource = function (source) {
14019    var can = Flash.rtmpSourceHandler.canPlayType(source.type);
14020
14021    if (can) {
14022      return can;
14023    }
14024
14025    if (Flash.isStreamingSrc(source.src)) {
14026      return 'maybe';
14027    }
14028
14029    return '';
14030  };
14031
14032  /**
14033   * Pass the source to the flash object
14034   * Adaptive source handlers will have more complicated workflows before passing
14035   * video data to the video element
14036   * @param  {Object} source   The source object
14037   * @param  {Flash}  tech     The instance of the Flash tech
14038   * @param  {Object} options  The options to pass to the source
14039   */
14040  Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
14041    var srcParts = Flash.streamToParts(source.src);
14042
14043    tech['setRtmpConnection'](srcParts.connection);
14044    tech['setRtmpStream'](srcParts.stream);
14045  };
14046
14047  // Register the native source handler
14048  Flash.registerSourceHandler(Flash.rtmpSourceHandler);
14049
14050  return Flash;
14051}
14052
14053exports['default'] = FlashRtmpDecorator;
14054module.exports = exports['default'];
14055
14056},{}],121:[function(_dereq_,module,exports){
14057/**
14058 * @file flash.js
14059 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
14060 * https://github.com/zencoder/video-js-swf
14061 * Not using setupTriggers. Using global onEvent func to distribute events
14062 */
14063
14064'use strict';
14065
14066exports.__esModule = true;
14067
14068function _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; } }
14069
14070function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14071
14072function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
14073
14074function _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; }
14075
14076var _tech = _dereq_('./tech');
14077
14078var _tech2 = _interopRequireDefault(_tech);
14079
14080var _utilsDomJs = _dereq_('../utils/dom.js');
14081
14082var Dom = _interopRequireWildcard(_utilsDomJs);
14083
14084var _utilsUrlJs = _dereq_('../utils/url.js');
14085
14086var Url = _interopRequireWildcard(_utilsUrlJs);
14087
14088var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
14089
14090var _flashRtmp = _dereq_('./flash-rtmp');
14091
14092var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
14093
14094var _component = _dereq_('../component');
14095
14096var _component2 = _interopRequireDefault(_component);
14097
14098var _globalWindow = _dereq_('global/window');
14099
14100var _globalWindow2 = _interopRequireDefault(_globalWindow);
14101
14102var _objectAssign = _dereq_('object.assign');
14103
14104var _objectAssign2 = _interopRequireDefault(_objectAssign);
14105
14106var navigator = _globalWindow2['default'].navigator;
14107/**
14108 * Flash Media Controller - Wrapper for fallback SWF API
14109 *
14110 * @param {Object=} options Object of option names and values
14111 * @param {Function=} ready Ready callback function
14112 * @extends Tech
14113 * @class Flash
14114 */
14115
14116var Flash = (function (_Tech) {
14117  _inherits(Flash, _Tech);
14118
14119  function Flash(options, ready) {
14120    _classCallCheck(this, Flash);
14121
14122    _Tech.call(this, options, ready);
14123
14124    // Set the source when ready
14125    if (options.source) {
14126      this.ready(function () {
14127        this.setSource(options.source);
14128      }, true);
14129    }
14130
14131    // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
14132    // This allows resetting the playhead when we catch the reload
14133    if (options.startTime) {
14134      this.ready(function () {
14135        this.load();
14136        this.play();
14137        this.currentTime(options.startTime);
14138      }, true);
14139    }
14140
14141    // Add global window functions that the swf expects
14142    // A 4.x workflow we weren't able to solve for in 5.0
14143    // because of the need to hard code these functions
14144    // into the swf for security reasons
14145    _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {};
14146    _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {};
14147    _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady;
14148    _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent;
14149    _globalWindow2['default'].videojs.Flash.onError = Flash.onError;
14150
14151    this.on('seeked', function () {
14152      this.lastSeekTarget_ = undefined;
14153    });
14154  }
14155
14156  // Create setters and getters for attributes
14157
14158  /**
14159   * Create the component's DOM element
14160   *
14161   * @return {Element}
14162   * @method createEl
14163   */
14164
14165  Flash.prototype.createEl = function createEl() {
14166    var options = this.options_;
14167
14168    // If video.js is hosted locally you should also set the location
14169    // for the hosted swf, which should be relative to the page (not video.js)
14170    // Otherwise this adds a CDN url.
14171    // The CDN also auto-adds a swf URL for that specific version.
14172    if (!options.swf) {
14173      options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf';
14174    }
14175
14176    // Generate ID for swf object
14177    var objId = options.techId;
14178
14179    // Merge default flashvars with ones passed in to init
14180    var flashVars = _objectAssign2['default']({
14181
14182      // SWF Callback Functions
14183      'readyFunction': 'videojs.Flash.onReady',
14184      'eventProxyFunction': 'videojs.Flash.onEvent',
14185      'errorEventProxyFunction': 'videojs.Flash.onError',
14186
14187      // Player Settings
14188      'autoplay': options.autoplay,
14189      'preload': options.preload,
14190      'loop': options.loop,
14191      'muted': options.muted
14192
14193    }, options.flashVars);
14194
14195    // Merge default parames with ones passed in
14196    var params = _objectAssign2['default']({
14197      'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance
14198      'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading
14199    }, options.params);
14200
14201    // Merge default attributes with ones passed in
14202    var attributes = _objectAssign2['default']({
14203      'id': objId,
14204      'name': objId, // Both ID and Name needed or swf to identify itself
14205      'class': 'vjs-tech'
14206    }, options.attributes);
14207
14208    this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
14209    this.el_.tech = this;
14210
14211    return this.el_;
14212  };
14213
14214  /**
14215   * Play for flash tech
14216   *
14217   * @method play
14218   */
14219
14220  Flash.prototype.play = function play() {
14221    if (this.ended()) {
14222      this.setCurrentTime(0);
14223    }
14224    this.el_.vjs_play();
14225  };
14226
14227  /**
14228   * Pause for flash tech
14229   *
14230   * @method pause
14231   */
14232
14233  Flash.prototype.pause = function pause() {
14234    this.el_.vjs_pause();
14235  };
14236
14237  /**
14238   * Get/set video
14239   *
14240   * @param {Object=} src Source object
14241   * @return {Object}
14242   * @method src
14243   */
14244
14245  Flash.prototype.src = function src(_src) {
14246    if (_src === undefined) {
14247      return this.currentSrc();
14248    }
14249
14250    // Setting src through `src` not `setSrc` will be deprecated
14251    return this.setSrc(_src);
14252  };
14253
14254  /**
14255   * Set video
14256   *
14257   * @param {Object=} src Source object
14258   * @deprecated
14259   * @method setSrc
14260   */
14261
14262  Flash.prototype.setSrc = function setSrc(src) {
14263    // Make sure source URL is absolute.
14264    src = Url.getAbsoluteURL(src);
14265    this.el_.vjs_src(src);
14266
14267    // Currently the SWF doesn't autoplay if you load a source later.
14268    // e.g. Load player w/ no source, wait 2s, set src.
14269    if (this.autoplay()) {
14270      var tech = this;
14271      this.setTimeout(function () {
14272        tech.play();
14273      }, 0);
14274    }
14275  };
14276
14277  /**
14278   * Returns true if the tech is currently seeking.
14279   * @return {boolean} true if seeking
14280   */
14281
14282  Flash.prototype.seeking = function seeking() {
14283    return this.lastSeekTarget_ !== undefined;
14284  };
14285
14286  /**
14287   * Set current time
14288   *
14289   * @param {Number} time Current time of video
14290   * @method setCurrentTime
14291   */
14292
14293  Flash.prototype.setCurrentTime = function setCurrentTime(time) {
14294    var seekable = this.seekable();
14295    if (seekable.length) {
14296      // clamp to the current seekable range
14297      time = time > seekable.start(0) ? time : seekable.start(0);
14298      time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
14299
14300      this.lastSeekTarget_ = time;
14301      this.trigger('seeking');
14302      this.el_.vjs_setProperty('currentTime', time);
14303      _Tech.prototype.setCurrentTime.call(this);
14304    }
14305  };
14306
14307  /**
14308   * Get current time
14309   *
14310   * @param {Number=}
14310 time Current time of video
14311   * @return {Number} Current time
14312   * @method currentTime
14313   */
14314
14315  Flash.prototype.currentTime = function currentTime(time) {
14316    // when seeking make the reported time keep up with the requested time
14317    // by reading the time we're seeking to
14318    if (this.seeking()) {
14319      return this.lastSeekTarget_ || 0;
14320    }
14321    return this.el_.vjs_getProperty('currentTime');
14322  };
14323
14324  /**
14325   * Get current source
14326   *
14327   * @method currentSrc
14328   */
14329
14330  Flash.prototype.currentSrc = function currentSrc() {
14331    if (this.currentSource_) {
14332      return this.currentSource_.src;
14333    } else {
14334      return this.el_.vjs_getProperty('currentSrc');
14335    }
14336  };
14337
14338  /**
14339   * Load media into player
14340   *
14341   * @method load
14342   */
14343
14344  Flash.prototype.load = function load() {
14345    this.el_.vjs_load();
14346  };
14347
14348  /**
14349   * Get poster
14350   *
14351   * @method poster
14352   */
14353
14354  Flash.prototype.poster = function poster() {
14355    this.el_.vjs_getProperty('poster');
14356  };
14357
14358  /**
14359   * Poster images are not handled by the Flash tech so make this a no-op
14360   *
14361   * @method setPoster
14362   */
14363
14364  Flash.prototype.setPoster = function setPoster() {};
14365
14366  /**
14367   * Determine if can seek in media
14368   *
14369   * @return {TimeRangeObject}
14370   * @method seekable
14371   */
14372
14373  Flash.prototype.seekable = function seekable() {
14374    var duration = this.duration();
14375    if (duration === 0) {
14376      return _utilsTimeRangesJs.createTimeRange();
14377    }
14378    return _utilsTimeRangesJs.createTimeRange(0, duration);
14379  };
14380
14381  /**
14382   * Get buffered time range
14383   *
14384   * @return {TimeRangeObject}
14385   * @method buffered
14386   */
14387
14388  Flash.prototype.buffered = function buffered() {
14389    var ranges = this.el_.vjs_getProperty('buffered');
14390    if (ranges.length === 0) {
14391      return _utilsTimeRangesJs.createTimeRange();
14392    }
14393    return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]);
14394  };
14395
14396  /**
14397   * Get fullscreen support -
14398   * Flash does not allow fullscreen through javascript
14399   * so always returns false
14400   *
14401   * @return {Boolean} false
14402   * @method supportsFullScreen
14403   */
14404
14405  Flash.prototype.supportsFullScreen = function supportsFullScreen() {
14406    return false; // Flash does not allow fullscreen through javascript
14407  };
14408
14409  /**
14410   * Request to enter fullscreen
14411   * Flash does not allow fullscreen through javascript
14412   * so always returns false
14413   *
14414   * @return {Boolean} false
14415   * @method enterFullScreen
14416   */
14417
14418  Flash.prototype.enterFullScreen = function enterFullScreen() {
14419    return false;
14420  };
14421
14422  return Flash;
14423})(_tech2['default']);
14424
14425var _api = Flash.prototype;
14426var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
14427var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
14428
14429function _createSetter(attr) {
14430  var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
14431  _api['set' + attrUpper] = function (val) {
14432    return this.el_.vjs_setProperty(attr, val);
14433  };
14434}
14435function _createGetter(attr) {
14436  _api[attr] = function () {
14437    return this.el_.vjs_getProperty(attr);
14438  };
14439}
14440
14441// Create getter and setters for all read/write attributes
14442for (var i = 0; i < _readWrite.length; i++) {
14443  _createGetter(_readWrite[i]);
14444  _createSetter(_readWrite[i]);
14445}
14446
14447// Create getters for read-only attributes
14448for (var i = 0; i < _readOnly.length; i++) {
14449  _createGetter(_readOnly[i]);
14450}
14451
14452/* Flash Support Testing -------------------------------------------------------- */
14453
14454Flash.isSupported = function () {
14455  return Flash.version()[0] >= 10;
14456  // return swfobject.hasFlashPlayerVersion('10');
14457};
14458
14459// Add Source Handler pattern functions to this tech
14460_tech2['default'].withSourceHandlers(Flash);
14461
14462/*
14463 * The default native source handler.
14464 * This simply passes the source to the video element. Nothing fancy.
14465 *
14466 * @param  {Object} source   The source object
14467 * @param  {Flash} tech  The instance of the Flash tech
14468 */
14469Flash.nativeSourceHandler = {};
14470
14471/**
14472 * Check if Flash can play the given videotype
14473 * @param  {String} type    The mimetype to check
14474 * @return {String}         'probably', 'maybe', or '' (empty string)
14475 */
14476Flash.nativeSourceHandler.canPlayType = function (type) {
14477  if (type in Flash.formats) {
14478    return 'maybe';
14479  }
14480
14481  return '';
14482};
14483
14484/*
14485 * Check Flash can handle the source natively
14486 *
14487 * @param  {Object} source  The source object
14488 * @return {String}         'probably', 'maybe', or '' (empty string)
14489 */
14490Flash.nativeSourceHandler.canHandleSource = function (source) {
14491  var type;
14492
14493  function guessMimeType(src) {
14494    var ext = Url.getFileExtension(src);
14495    if (ext) {
14496      return 'video/' + ext;
14497    }
14498    return '';
14499  }
14500
14501  if (!source.type) {
14502    type = guessMimeType(source.src);
14503  } else {
14504    // Strip code information from the type because we don't get that specific
14505    type = source.type.replace(/;.*/, '').toLowerCase();
14506  }
14507
14508  return Flash.nativeSourceHandler.canPlayType(type);
14509};
14510
14511/*
14512 * Pass the source to the flash object
14513 * Adaptive source handlers will have more complicated workflows before passing
14514 * video data to the video element
14515 *
14516 * @param  {Object} source   The source object
14517 * @param  {Flash}  tech     The instance of the Flash tech
14518 * @param  {Object} options  The options to pass to the source
14519 */
14520Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
14521  tech.setSrc(source.src);
14522};
14523
14524/*
14525 * Clean up the source handler when disposing the player or switching sources..
14526 * (no cleanup is needed when supporting the format natively)
14527 */
14528Flash.nativeSourceHandler.dispose = function () {};
14529
14530// Register the native source handler
14531Flash.registerSourceHandler(Flash.nativeSourceHandler);
14532
14533Flash.formats = {
14534  'video/flv': 'FLV',
14535  'video/x-flv': 'FLV',
14536  'video/mp4': 'MP4',
14537  'video/m4v': 'MP4'
14538};
14539
14540Flash.onReady = function (currSwf) {
14541  var el = Dom.getEl(currSwf);
14542  var tech = el && el.tech;
14543
14544  // if there is no el then the tech has been disposed
14545  // and the tech element was removed from the player div
14546  if (tech && tech.el()) {
14547    // check that the flash object is really ready
14548    Flash.checkReady(tech);
14549  }
14550};
14551
14552// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
14553// If it's not ready, we set a timeout to check again shortly.
14554Flash.checkReady = function (tech) {
14555  // stop worrying if the tech has been disposed
14556  if (!tech.el()) {
14557    return;
14558  }
14559
14560  // check if API property exists
14561  if (tech.el().vjs_getProperty) {
14562    // tell tech it's ready
14563    tech.triggerReady();
14564  } else {
14565    // wait longer
14566    this.setTimeout(function () {
14567      Flash['checkReady'](tech);
14568    }, 50);
14569  }
14570};
14571
14572// Trigger events from the swf on the player
14573Flash.onEvent = function (swfID, eventName) {
14574  var tech = Dom.getEl(swfID).tech;
14575  tech.trigger(eventName);
14576};
14577
14578// Log errors from the swf
14579Flash.onError = function (swfID, err) {
14580  var tech = Dom.getEl(swfID).tech;
14581
14582  // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
14583  if (err === 'srcnotfound') {
14584    return tech.error(4);
14585  }
14586
14587  // trigger a custom error
14588  tech.error('FLASH: ' + err);
14589};
14590
14591// Flash Version Check
14592Flash.version = function () {
14593  var version = '0,0,0';
14594
14595  // IE
14596  try {
14597    version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14598
14599    // other browsers
14600  } catch (e) {
14601    try {
14602      if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
14603        version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14604      }
14605    } catch (err) {}
14606  }
14607  return version.split(',');
14608};
14609
14610// Flash embedding method. Only used in non-iframe mode
14611Flash.embed = function (swf, flashVars, params, attributes) {
14612  var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
14613
14614  // Get element by embedding code and retrieving created element
14615  var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
14616
14617  return obj;
14618};
14619
14620Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
14621  var objTag = '<object type="application/x-shockwave-flash" ';
14622  var flashVarsString = '';
14623  var paramsString = '';
14624  var attrsString = '';
14625
14626  // Convert flash vars to string
14627  if (flashVars) {
14628    Object.getOwnPropertyNames(flashVars).forEach(function (key) {
14629      flashVarsString += key + '=' + flashVars[key] + '&amp;';
14630    });
14631  }
14632
14633  // Add swf, flashVars, and other default params
14634  params = _objectAssign2['default']({
14635    'movie': swf,
14636    'flashvars': flashVarsString,
14637    'allowScriptAccess': 'always', // Required to talk to swf
14638    'allowNetworking': 'all' // All should be default, but having security issues.
14639  }, params);
14640
14641  // Create param tags string
14642  Object.getOwnPropertyNames(params).forEach(function (key) {
14643    paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
14644  });
14645
14646  attributes = _objectAssign2['default']({
14647    // Add swf to attributes (need both for IE and Others to work)
14648    'data': swf,
14649
14650    // Default to 100% width/height
14651    'width': '100%',
14652    'height': '100%'
14653
14654  }, attributes);
14655
14656  // Create Attributes string
14657  Object.getOwnPropertyNames(attributes).forEach(function (key) {
14658    attrsString += key + '="' + attributes[key] + '" ';
14659  });
14660
14661  return '' + objTag + attrsString + '>' + paramsString + '</object>';
14662};
14663
14664// Run Flash through the RTMP decorator
14665_flashRtmp2['default'](Flash);
14666
14667_component2['default'].registerComponent('Flash', Flash);
14668_tech2['default'].registerTech('Flash', Flash);
14669exports['default'] = Flash;
14670module.exports = exports['default'];
14671
14672},{"../component":67,"../utils/dom.js":143,"../utils/time-ranges.js":151,"../utils/url.js":153,"./flash-rtmp":120,"./tech":124,"global/window":2,"object.assign":45}],122:[function(_dereq_,module,exports){
14673/**
14674 * @file html5.js
14675 * HTML5 Media Controller - Wrapper for HTML5 Media API
14676 */
14677
14678'use strict';
14679
14680exports.__esModule = true;
14681
14682var _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.']);
14683
14684function _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; } }
14685
14686function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14687
14688function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
14689
14690function _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, { c
14690onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
14691
14692function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
14693
14694var _techJs = _dereq_('./tech.js');
14695
14696var _techJs2 = _interopRequireDefault(_techJs);
14697
14698var _component = _dereq_('../component');
14699
14700var _component2 = _interopRequireDefault(_component);
14701
14702var _utilsDomJs = _dereq_('../utils/dom.js');
14703
14704var Dom = _interopRequireWildcard(_utilsDomJs);
14705
14706var _utilsUrlJs = _dereq_('../utils/url.js');
14707
14708var Url = _interopRequireWildcard(_utilsUrlJs);
14709
14710var _utilsFnJs = _dereq_('../utils/fn.js');
14711
14712var Fn = _interopRequireWildcard(_utilsFnJs);
14713
14714var _utilsLogJs = _dereq_('../utils/log.js');
14715
14716var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
14717
14718var _tsml = _dereq_('tsml');
14719
14720var _tsml2 = _interopRequireDefault(_tsml);
14721
14722var _srcJsTracksTextTrackJs = _dereq_('../../../src/js/tracks/text-track.js');
14723
14724var _srcJsTracksTextTrackJs2 = _interopRequireDefault(_srcJsTracksTextTrackJs);
14725
14726var _utilsBrowserJs = _dereq_('../utils/browser.js');
14727
14728var browser = _interopRequireWildcard(_utilsBrowserJs);
14729
14730var _globalDocument = _dereq_('global/document');
14731
14732var _globalDocument2 = _interopRequireDefault(_globalDocument);
14733
14734var _globalWindow = _dereq_('global/window');
14735
14736var _globalWindow2 = _interopRequireDefault(_globalWindow);
14737
14738var _objectAssign = _dereq_('object.assign');
14739
14740var _objectAssign2 = _interopRequireDefault(_objectAssign);
14741
14742var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
14743
14744var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
14745
14746var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
14747
14748var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
14749
14750/**
14751 * HTML5 Media Controller - Wrapper for HTML5 Media API
14752 *
14753 * @param {Object=} options Object of option names and values
14754 * @param {Function=} ready Ready callback function
14755 * @extends Tech
14756 * @class Html5
14757 */
14758
14759var Html5 = (function (_Tech) {
14760  _inherits(Html5, _Tech);
14761
14762  function Html5(options, ready) {
14763    var _this = this;
14764
14765    _classCallCheck(this, Html5);
14766
14767    _Tech.call(this, options, ready);
14768
14769    var source = options.source;
14770    var crossoriginTracks = false;
14771
14772    // Set the source if one is provided
14773    // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
14774    // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
14775    // anyway so the error gets fired.
14776    if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.
14776initNetworkState_ === 3)) {
14777      this.setSource(source);
14778    } else {
14779      this.handleLateInit_(this.el_);
14780    }
14781
14782    if (this.el_.hasChildNodes()) {
14783
14784      var nodes = this.el_.childNodes;
14785      var nodesLength = nodes.length;
14786      var removeNodes = [];
14787
14788      while (nodesLength--) {
14789        var node = nodes[nodesLength];
14790        var nodeName = node.nodeName.toLowerCase();
14791
14792        if (nodeName === 'track') {
14793          if (!this.featuresNativeTextTracks) {
14794            // Empty video tag tracks so the built-in player doesn't use them also.
14795            // This may not be fast enough to stop HTML5 browsers from reading the tags
14796            // so we'll need to turn off any default tracks if we're manually doing
14797            // captions and subtitles. videoElement.textTracks
14798            removeNodes.push(node);
14799          } else {
14800            // store HTMLTrackElement and TextTrack to remote list
14801            this.remoteTextTrackEls().addTrackElement_(node);
14802            this.remoteTextTracks().addTrack_(node.track);
14803            if (!crossoriginTracks && !this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
14804              crossoriginTracks = true;
14805            }
14806          }
14807        }
14808      }
14809
14810      for (var i = 0; i < removeNodes.length; i++) {
14811        this.el_.removeChild(removeNodes[i]);
14812      }
14813    }
14814
14815    var trackTypes = ['audio', 'video'];
14816
14817    // ProxyNativeTextTracks
14818    trackTypes.forEach(function (type) {
14819      var capitalType = _utilsToTitleCaseJs2['default'](type);
14820
14821      if (!_this['featuresNative' + capitalType + 'Tracks']) {
14822        return;
14823      }
14824      var tl = _this.el()[type + 'Tracks'];
14825
14826      if (tl && tl.addEventListener) {
14827        tl.addEventListener('change', Fn.bind(_this, _this['handle' + capitalType + 'TrackChange_']));
14828        tl.addEventListener('addtrack', Fn.bind(_this, _this['handle' + capitalType + 'TrackAdd_']));
14829        tl.addEventListener('removetrack', Fn.bind(_this, _this['handle' + capitalType + 'TrackRemove_']));
14830      }
14831    });
14832
14833    if (this.featuresNativeTextTracks) {
14834      if (crossoriginTracks) {
14835        _utilsLogJs2['default'].warn(_tsml2['default'](_templateObject));
14836      }
14837
14838      this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange);
14839      this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd);
14840      this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove);
14841      this.proxyNativeTextTracks_();
14842    }
14843
14844    // Determine if native controls should be used
14845    // Our goal should be to get the custom controls on mobile solid everywhere
14846    // so we can remove this all together. Right now this will block custom
14847    // controls on touch enabled laptops like the Chrome Pixel
14848    if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) {
14849      this.setControls(true);
14850    }
14851
14852    this.triggerReady();
14853  }
14854
14855  /* HTML5 Support Testing ---------------------------------------------------- */
14856
14857  /*
14858  * Element for testing browser HTML5 video capabilities
14859  *
14860  * @type {Element}
14861  * @constant
14862  * @private
14863  */
14864
14865  /**
14866   * Dispose of html5 media element
14867   *
14868   * @method dispose
14869   */
14870
14871  Html5.prototype.dispose = function dispose() {
14872    var _this2 = this;
14873
14874    // Un-ProxyNativeTracks
14875    ['audio', 'video', 'text'].forEach(function (type) {
14876      var capitalType = _utilsToTitleCaseJs2['default'](type);
14877      var tl = _this2.el_[type + 'Tracks'];
14878
14879      if (tl && tl.removeEventListener) {
14880        tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
14881        tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
14882        tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
14883      }
14884    });
14885
14886    Html5.disposeMediaElement(this.el_);
14887    // tech will handle clearing of the emulated track list
14888    _Tech.prototype.dispose.call(this);
14889  };
14890
14891  /**
14892   * Create the component's DOM element
14893   *
14894   * @return {Element}
14895   * @method createEl
14896   */
14897
14898  Html5.prototype.createEl = function createEl() {
14899    var el = this.options_.tag;
14900
14901    // Check if this browser supports moving the element into the box.
14902    // On the iPhone video will break if you move the element,
14903    // So we have to create a brand new element.
14904    if (!el || this['movingMediaElementInDOM'] === false) {
14905
14906      // If the original tag is still there, clone and remove it.
14907      if (el) {
14908        var clone = el.cloneNode(true);
14909        el.parentNode.insertBefore(clone, el);
14910        Html5.disposeMediaElement(el);
14911        el = clone;
14912      } else {
14913        el = _globalDocument2['default'].createElement('video');
14914
14915        // determine if native controls should be used
14916        var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
14917        var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes);
14918        if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
14919          delete attributes.controls;
14920        }
14921
14922        Dom.setElAttributes(el, _objectAssign2['default'](attributes, {
14923          id: this.options_.techId,
14924          'class': 'vjs-tech'
14925        }));
14926      }
14927    }
14928
14929    // Update specific tag settings, in case they were overridden
14930    var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
14931    for (var i = settingsAttrs.length - 1; i >= 0; i--) {
14932      var attr = settingsAttrs[i];
14933      var overwriteAttrs = {};
14934      if (typeof this.options_[attr] !== 'undefined') {
14935        overwriteAttrs[attr] = this.options_[attr];
14936      }
14937      Dom.setElAttributes(el, overwriteAttrs);
14938    }
14939
14940    return el;
14941    // jenniisawesome = true;
14942  };
14943
14944  // If we're loading the playback object after it has started loading
14945  // or playing the video (often with autoplay on) then the loadstart event
14946  // has already fired and we need to fire it manually because many things
14947  // rely on it.
14948
14949  Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
14950    var _this3 = this;
14951
14952    if (el.networkState === 0 || el.networkState === 3) {
14953      // The video element hasn't started loading the source yet
14954      // or didn't find a source
14955      return;
14956    }
14957
14958    if (el.readyState === 0) {
14959      var _ret = (function () {
14960        // NetworkState is set synchronously BUT loadstart is fired at the
14961        // end of the current stack, usually before setInterval(fn, 0).
14962        // So at this point we know loadstart may have already fired or is
14963        // about to fire, and either way the player hasn't seen it yet.
14964        // We don't want to fire loadstart prematurely here and cause a
14965        // double loadstart so we'll wait and see if it happens between now
14966        // and the next loop, and fire it if not.
14967        // HOWEVER, we also want to make sure it fires before loadedmetadata
14968        // which could also happen between now and the next loop, so we'll
14969        // watch for that also.
14970        var loadstartFired = false;
14971        var setLoadstartFired = function setLoadstartFired() {
14972          loadstartFired = true;
14973        };
14974        _this3.on('loadstart', setLoadstartFired);
14975
14976        var triggerLoadstart = function triggerLoadstart() {
14977          // We did miss the original loadstart. Make sure the player
14978          // sees loadstart before loadedmetadata
14979          if (!loadstartFired) {
14980            this.trigger('loadstart');
14981          }
14982        };
14983        _this3.on('loadedmetadata', triggerLoadstart);
14984
14985        _this3.ready(function () {
14986          this.off('loadstart', setLoadstartFired);
14987          this.off('loadedmetadata', triggerLoadstart);
14988
14989          if (!loadstartFired) {
14990            // We did miss the original native loadstart. Fire it now.
14991            this.trigger('loadstart');
14992          }
14993        });
14994
14995        return {
14996          v: undefined
14997        };
14998      })();
14999
15000      if (typeof _ret === 'object') return _ret.v;
15001    }
15002
15003    // From here on we know that loadstart already fired and we missed it.
15004    // The other readyState events aren't as much of a problem if we double
15005    // them, so not going to go to as much trouble as loadstart to prevent
15006    // that unless we find reason to.
15007    var eventsToTrigger = ['loadstart'];
15008
15009    // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
15010    eventsToTrigger.push('loadedmetadata');
15011
15012    // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
15013    if (el.readyState >= 2) {
15014      eventsToTrigger.push('loadeddata');
15015    }
15016
15017    // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
15018    if (el.readyState >= 3) {
15019      eventsToTrigger.push('canplay');
15020    }
15021
15022    // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
15023    if (el.readyState >= 4) {
15024      eventsToTrigger.push('canplaythrough');
15025    }
15026
15027    // We still need to give the player time to add event listeners
15028    this.ready(function () {
15029      eventsToTrigger.forEach(function (type) {
15030        this.trigger(type);
15031      }, this);
15032    });
15033  };
15034
15035  Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
15036    var tt = this.el().textTracks;
15037
15038    if (tt) {
15039      // Add tracks - if player is initialised after DOM loaded, textTracks
15040      // will not trigger addtrack
15041      for (var i = 0; i < tt.length; i++) {
15042        this.textTracks().addTrack_(tt[i]);
15043      }
15044
15045      if (tt.addEventListener) {
15046        tt.addEventListener('change', this.handleTextTrackChange_);
15047        tt.addEventListener('addtrack', this.handleTextTrackAdd_);
15048        tt.addEventListener('removetrack', this.handleTextTrackRemove_);
15049      }
15050    }
15051  };
15052
15053  Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
15054    var tt = this.textTracks();
15055    this.textTracks().trigger({
15056      type: 'change',
15057      target: tt,
15058      currentTarget: tt,
15059      srcElement: tt
15060    });
15061  };
15062
15063  Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
15064    this.textTracks().addTrack_(e.track);
15065  };
15066
15067  Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
15068    this.textTracks().removeTrack_(e.track);
15069  };
15070
15071  Html5.prototype.handleVideoTrackChange_ = function handleVideoTrackChange_(e) {
15072    var vt = this.videoTracks();
15073    this.videoTracks().trigger({
15074      type: 'change',
15075      target: vt,
15076      currentTarget: vt,
15077      srcElement: vt
15078    });
15079  };
15080
15081  Html5.prototype.handleVideoTrackAdd_ = function handleVideoTrackAdd_(e) {
15082    this.videoTracks().addTrack_(e.track);
15083  };
15084
15085  Html5.prototype.handleVideoTrackRemove_ = function handleVideoTrackRemove_(e) {
15086    this.videoTracks().removeTrack_(e.track);
15087  };
15088
15089  Html5.prototype.handleAudioTrackChange_ = function handleAudioTrackChange_(e) {
15090    var audioTrackList = this.audioTracks();
15091    this.audioTracks().trigger({
15092      type: 'change',
15093      target: audioTrackList,
15094      currentTarget: audioTrackList,
15095      srcElement: audioTrackList
15096    });
15097  };
15098
15099  Html5.prototype.handleAudioTrackAdd_ = function handleAudioTrackAdd_(e) {
15100    this.audioTracks().addTrack_(e.track);
15101  };
15102
15103  Html5.prototype.handleAudioTrackRemove_ = function handleAudioTrackRemove_(e) {
15104    this.audioTracks().removeTrack_(e.track);
15105  };
15106
15107  /**
15108   * Play for html5 tech
15109   *
15110   * @method play
15111   */
15112
15113  Html5.prototype.play = function play() {
15114    this.el_.play();
15115  };
15116
15117  /**
15118   * Pause for html5 tech
15119   *
15120   * @method pause
15121   */
15122
15123  Html5.prototype.pause = function pause() {
15124    this.el_.pause();
15125  };
15126
15127  /**
15128   * Paused for html5 tech
15129   *
15130   * @return {Boolean}
15131   * @method paused
15132   */
15133
15134  Html5.prototype.paused = function paused() {
15135    return this.el_.paused;
15136  };
15137
15138  /**
15139   * Get current time
15140   *
15141   * @return {Number}
15142   * @method currentTime
15143   */
15144
15145  Html5.prototype.currentTime = function currentTime() {
15146    return this.el_.currentTime;
15147  };
15148
15149  /**
15150   * Set current time
15151   *
15152   * @param {Number} seconds Current time of video
15153   * @method setCurrentTime
15154   */
15155
15156  Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
15157    try {
15158      this.el_.currentTime = seconds;
15159    } catch (e) {
15160      _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)');
15161      // this.warning(VideoJS.warnings.videoNotReady);
15162    }
15163  };
15164
15165  /**
15166   * Get duration
15167   *
15168   * @return {Number}
15169   * @method duration
15170   */
15171
15172  Html5.prototype.duration = function duration() {
15173    return this.el_.duration || 0;
15174  };
15175
15176  /**
15177   * Get a TimeRange object that represents the intersection
15178   * of the time ranges for which the user agent has all
15179   * relevant media
15180   *
15181   * @return {TimeRangeObject}
15182   * @method buffered
15183   */
15184
15185  Html5.prototype.buffered = function buffered() {
15186    return this.el_.buffered;
15187  };
15188
15189  /**
15190   * Get volume level
15191   *
15192   * @return {Number}
15193   * @method volume
15194   */
15195
15196  Html5.prototype.volume = function volume() {
15197    return this.el_.volume;
15198  };
15199
15200  /**
15201   * Set volume level
15202   *
15203   * @param {Number} percentAsDecimal Volume percent as a decimal
15204   * @method setVolume
15205   */
15206
15207  Html5.prototype.setVolume = function setVolume(percentAsDecimal) {
15208    this.el_.volume = percentAsDecimal;
15209  };
15210
15211  /**
15212   * Get if muted
15213   *
15214   * @return {Boolean}
15215   * @method muted
15216   */
15217
15218  Html5.prototype.muted = function muted() {
15219    return this.el_.muted;
15220  };
15221
15222  /**
15223   * Set muted
15224   *
15225   * @param {Boolean} If player is to be muted or note
15226   * @method setMuted
15227   */
15228
15229  Html5.prototype.setMuted = function setMuted(muted) {
15230    this.el_.muted = muted;
15231  };
15232
15233  /**
15234   * Get player width
15235   *
15236   * @return {Number}
15237   * @method width
15238   */
15239
15240  Html5.prototype.width = function width() {
15241    return this.el_.offsetWidth;
15242  };
15243
15244  /**
15245   * Get player height
15246   *
15247   * @return {Number}
15248   * @method height
15249   */
15250
15251  Html5.prototype.height = function height() {
15252    return this.el_.offsetHeight;
15253  };
15254
15255  /**
15256   * Get if there is fullscreen support
15257   *
15258   * @return {Boolean}
15259   * @method supportsFullScreen
15260   */
15261
15262  Html5.prototype.supportsFullScreen = function supportsFullScreen() {
15263    if (typeof this.el_.webkitEnterFullScreen === 'function') {
15264      var userAgent = _globalWindow2['default'].navigator.userAgent;
15265      // Seems to be broken in Chromium/Chrome && Safari in Leopard
15266      if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
15267        return true;
15268      }
15269    }
15270    return false;
15271  };
15272
15273  /**
15274   * Request to enter fullscreen
15275   *
15276   * @method enterFullScreen
15277   */
15278
15279  Html5.prototype.enterFullScreen = function enterFullScreen() {
15280    var video = this.el_;
15281
15282    if ('webkitDisplayingFullscreen' in video) {
15283      this.one('webkitbeginfullscreen', function () {
15284        this.one('webkitendfullscreen', function () {
15285          this.trigger('fullscreenchange', { isFullscreen: false });
15286        });
15287
15288        this.trigger('fullscreenchange', { isFullscreen: true });
15289      });
15290    }
15291
15292    if (video.paused && video.networkState <= video.HAVE_METADATA) {
15293      // attempt to prime the video element for programmatic access
15294      // this isn't necessary on the desktop but shouldn't hurt
15295      this.el_.play();
15296
15297      // playing and pausing synchronously during the transition to fullscreen
15298      // can get iOS ~6.1 devices into a play/pause loop
15299      this.setTimeout(function () {
15300        video.pause();
15301        video.webkitEnterFullScreen();
15302      }, 0);
15303    } else {
15304      video.webkitEnterFullScreen();
15305    }
15306  };
15307
15308  /**
15309   * Request to exit fullscreen
15310   *
15311   * @method exitFullScreen
15312   */
15313
15314  Html5.prototype.exitFullScreen = function exitFullScreen() {
15315    this.el_.webkitExitFullScreen();
15316  };
15317
15318  /**
15319   * Get/set video
15320   *
15321   * @param {Object=} src Source object
15322   * @return {Object}
15323   * @method src
15324   */
15325
15326  Html5.prototype.src = function src(_src) {
15327    if (_src === undefined) {
15328      return this.el_.src;
15329    } else {
15330      // Setting src through `src` instead of `setSrc` will be deprecated
15331      this.setSrc(_src);
15332    }
15333  };
15334
15335  /**
15336   * Set video
15337   *
15338   * @param {Object} src Source object
15339   * @deprecated
15340   * @method setSrc
15341   */
15342
15343  Html5.prototype.setSrc = function setSrc(src) {
15344    this.el_.src = src;
15345  };
15346
15347  /**
15348   * Load media into player
15349   *
15350   * @method load
15351   */
15352
15353  Html5.prototype.load = function load() {
15354    this.el_.load();
15355  };
15356
15357  /**
15358   * Reset the tech. Removes all sources and calls `load`.
15359   *
15360   * @method reset
15361   */
15362
15363  Html5.prototype.reset = function reset() {
15364    Html5.resetMediaElement(this.el_);
15365  };
15366
15367  /**
15368   * Get current source
15369   *
15370   * @return {Object}
15371   * @method currentSrc
15372   */
15373
15374  Html5.prototype.currentSrc = function currentSrc() {
15375    if (this.currentSource_) {
15376      return this.currentSource_.src;
15377    } else {
15378      return this.el_.currentSrc;
15379    }
15380  };
15381
15382  /**
15383   * Get poster
15384   *
15385   * @return {String}
15386   * @method poster
15387   */
15388
15389  Html5.prototype.poster = function poster() {
15390    return this.el_.poster;
15391  };
15392
15393  /**
15394   * Set poster
15395   *
15396   * @param {String} val URL to poster image
15397   * @method
15398   */
15399
15400  Html5.prototype.setPoster = function setPoster(val) {
15401    this.el_.poster = val;
15402  };
15403
15404  /**
15405   * Get preload attribute
15406   *
15407   * @return {String}
15408   * @method preload
15409   */
15410
15411  Html5.prototype.preload = function preload() {
15412    return this.el_.preload;
15413  };
15414
15415  /**
15416   * Set preload attribute
15417   *
15418   * @param {String} val Value for preload attribute
15419   * @method setPreload
15420   */
15421
15422  Html5.prototype.setPreload = function setPreload(val) {
15423    this.el_.preload = val;
15424  };
15425
15426  /**
15427   * Get autoplay attribute
15428   *
15429   * @return {String}
15430   * @method autoplay
15431   */
15432
15433  Html5.prototype.autoplay = function autoplay() {
15434    return this.el_.autoplay;
15435  };
15436
15437  /**
15438   * Set autoplay attribute
15439   *
15440   * @param {String} val Value for preload attribute
15441   * @method setAutoplay
15442   */
15443
15444  Html5.prototype.setAutoplay = function setAutoplay(val) {
15445    this.el_.autoplay = val;
15446  };
15447
15448  /**
15449   * Get controls attribute
15450   *
15451   * @return {String}
15452   * @method controls
15453   */
15454
15455  Html5.prototype.controls = function controls() {
15456    return this.el_.controls;
15457  };
15458
15459  /**
15460   * Set controls attribute
15461   *
15462   * @param {String} val Value for controls attribute
15463   * @method setControls
15464   */
15465
15466  Html5.prototype.setControls = function setControls(val) {
15467    this.el_.controls = !!val;
15468  };
15469
15470  /**
15471   * Get loop attribute
15472   *
15473   * @return {String}
15474   * @method loop
15475   */
15476
15477  Html5.prototype.loop = function loop() {
15478    return this.el_.loop;
15479  };
15480
15481  /**
15482   * Set loop attribute
15483   *
15484   * @param {String} val Value for loop attribute
15485   * @method setLoop
15486   */
15487
15488  Html5.prototype.setLoop = function setLoop(val) {
15489    this.el_.loop = val;
15490  };
15491
15492  /**
15493   * Get error value
15494   *
15495   * @return {String}
15496   * @method error
15497   */
15498
15499  Html5.prototype.error = function error() {
15500    return this.el_.error;
15501  };
15502
15503  /**
15504   * Get whether or not the player is in the "seeking" state
15505   *
15506   * @return {Boolean}
15507   * @method seeking
15508   */
15509
15510  Html5.prototype.seeking = function seeking() {
15511    return this.el_.seeking;
15512  };
15513
15514  /**
15515   * Get a TimeRanges object that represents the
15516   * ranges of the media resource to which it is possible
15517   * for the user agent to seek.
15518   *
15519   * @return {TimeRangeObject}
15520   * @method seekable
15521   */
15522
15523  Html5.prototype.seekable = function seekable() {
15524    return this.el_.seekable;
15525  };
15526
15527  /**
15528   * Get if video ended
15529   *
15530   * @return {Boolean}
15531   * @method ended
15532   */
15533
15534  Html5.prototype.ended = function ended() {
15535    return this.el_.ended;
15536  };
15537
15538  /**
15539   * Get the value of the muted content attribute
15540   * This attribute has no dynamic effect, it only
15541   * controls the default state of the element
15542   *
15543   * @return {Boolean}
15544   * @method defaultMuted
15545   */
15546
15547  Html5.prototype.defaultMuted = function defaultMuted() {
15548    return this.el_.defaultMuted;
15549  };
15550
15551  /**
15552   * Get desired speed at which the media resource is to play
15553   *
15554   * @return {Number}
15555   * @method playbackRate
15556   */
15557
15558  Html5.prototype.playbackRate = function playbackRate() {
15559    return this.el_.playbackRate;
15560  };
15561
15562  /**
15563   * Returns a TimeRanges object that represents the ranges of the
15564   * media resource that the user agent has played.
15565   * @return {TimeRangeObject} the range of points on the media
15566   * timeline that has been reached through normal playback
15567   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played
15568   */
15569
15570  Html5.prototype.played = function played() {
15571    return this.el_.played;
15572  };
15573
15574  /**
15575   * Set desired speed at which the media resource is to play
15576   *
15577   * @param {Number} val Speed at which the media resource is to play
15578   * @method setPlaybackRate
15579   */
15580
15581  Html5.prototype.setPlaybackRate = function setPlaybackRate(val) {
15582    this.el_.playbackRate = val;
15583  };
15584
15585  /**
15586   * Get the current state of network activity for the element, from
15587   * the list below
15588   * NETWORK_EMPTY (numeric value 0)
15589   * NETWORK_IDLE (numeric value 1)
15590   * NETWORK_LOADING (numeric value 2)
15591   * NETWORK_NO_SOURCE (numeric value 3)
15592   *
15593   * @return {Number}
15594   * @method networkState
15595   */
15596
15597  Html5.prototype.networkState = function networkState() {
15598    return this.el_.networkState;
15599  };
15600
15601  /**
15602   * Get a value that expresses the current state of the element
15603   * with respect to rendering the current playback position, from
15604   * the codes in the list below
15605   * HAVE_NOTHING (numeric value 0)
15606   * HAVE_METADATA (numeric value 1)
15607   * HAVE_CURRENT_DATA (numeric value 2)
15608   * HAVE_FUTURE_DATA (numeric value 3)
15609   * HAVE_ENOUGH_DATA (numeric value 4)
15610   *
15611   * @return {Number}
15612   * @method readyState
15613   */
15614
15615  Html5.prototype.readyState = function readyState() {
15616    return this.el_.readyState;
15617  };
15618
15619  /**
15620   * Get width of video
15621   *
15622   * @return {Number}
15623   * @method videoWidth
15624   */
15625
15626  Html5.prototype.videoWidth = function videoWidth() {
15627    return this.el_.videoWidth;
15628  };
15629
15630  /**
15631   * Get height of video
15632   *
15633   * @return {Number}
15634   * @method videoHeight
15635   */
15636
15637  Html5.prototype.videoHeight = function videoHeight() {
15638    return this.el_.videoHeight;
15639  };
15640
15641  /**
15642   * Get text tracks
15643   *
15644   * @return {TextTrackList}
15645   * @method textTracks
15646   */
15647
15648  Html5.prototype.textTracks = function textTracks() {
15649    return _Tech.prototype.textTracks.call(this);
15650  };
15651
15652  /**
15653   * Creates and returns a text track object
15654   *
15655   * @param {String} kind Text track kind (subtitles, captions, descriptions
15656   *                                       chapters and metadata)
15657   * @param {String=} label Label to identify the text track
15658   * @param {String=} language Two letter language abbreviation
15659   * @return {TextTrackObject}
15660   * @method addTextTrack
15661   */
15662
15663  Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15664    if (!this['featuresNativeTextTracks']) {
15665      return _Tech.prototype.addTextTrack.call(this, kind, label, language);
15666    }
15667
15668    return this.el_.addTextTrack(kind, label, language);
15669  };
15670
15671  /**
15672   * Creates a remote text track object and returns a html track element
15673   *
15674   * @param {Object} options The object should contain values for
15675   * kind, language, label and src (location of the WebVTT file)
15676   * @return {HTMLTrackElement}
15677   * @method addRemoteTextTrack
15678   */
15679
15680  Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
15681    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
15682
15683    if (!this['featuresNativeTextTracks']) {
15684      return _Tech.prototype.addRemoteTextTrack.call(this, options);
15685    }
15686
15687    var htmlTrackElement = _globalDocument2['default'].createElement('track');
15688
15689    if (options.kind) {
15690      htmlTrackElement.kind = options.kind;
15691    }
15692    if (options.label) {
15693      htmlTrackElement.label = options.label;
15694    }
15695    if (options.language || options.srclang) {
15696      htmlTrackElement.srclang = options.language || options.srclang;
15697    }
15698    if (options['default']) {
15699      htmlTrackElement['default'] = options['default'];
15700    }
15701    if (options.id) {
15702      htmlTrackElement.id = options.id;
15703    }
15704    if (options.src) {
15705      htmlTrackElement.src = options.src;
15706    }
15707
15708    this.el().appendChild(htmlTrackElement);
15709
15710    // store HTMLTrackElement and TextTrack to remote list
15711    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
15712    this.remoteTextTracks().addTrack_(htmlTrackElement.track);
15713
15714    return htmlTrackElement;
15715  };
15716
15717  /**
15718   * Remove remote text track from TextTrackList object
15719   *
15720   * @param {TextTrackObject} track Texttrack object to remove
15721   * @method removeRemoteTextTrack
15722   */
15723
15724  Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15725    if (!this['featuresNativeTextTracks']) {
15726      return _Tech.prototype.removeRemoteTextTrack.call(this, track);
15727    }
15728
15729    var tracks = undefined,
15730        i = undefined;
15731
15732    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
15733
15734    // remove HTMLTrackElement and TextTrack from remote list
15735    this.remoteTextTrackEls().removeTrackElement_(trackElement);
15736    this.remoteTextTracks().removeTrack_(track);
15737
15738    tracks = this.$$('track');
15739
15740    i = tracks.length;
15741    while (i--) {
15742      if (track === tracks[i] || track === tracks[i].track) {
15743        this.el().removeChild(tracks[i]);
15744      }
15745    }
15746  };
15747
15748  return Html5;
15749})(_techJs2['default']);
15750
15751Html5.TEST_VID = _globalDocument2['default'].createElement('video');
15752var track = _globalDocument2['default'].createElement('track');
15753track.kind = 'captions';
15754track.srclang = 'en';
15755track.label = 'English';
15756Html5.TEST_VID.appendChild(track);
15757
15758/*
15759 * Check if HTML5 video is supported by this browser/device
15760 *
15761 * @return {Boolean}
15762 */
15763Html5.isSupported = function () {
15764  // IE9 with no Media Player is a LIAR! (#984)
15765  try {
15766    Html5.TEST_VID['volume'] = 0.5;
15767  } catch (e) {
15768    return false;
15769  }
15770
15771  return !!Html5.TEST_VID.canPlayType;
15772};
15773
15774// Add Source Handler pattern functions to this tech
15775_techJs2['default'].withSourceHandlers(Html5);
15776
15777/*
15778 * The default native source handler.
15779 * This simply passes the source to the video element. Nothing fancy.
15780 *
15781 * @param  {Object} source   The source object
15782 * @param  {Html5} tech  The instance of the HTML5 tech
15783 */
15784Html5.nativeSourceHandler = {};
15785
15786/*
15787 * Check if the video element can play the given videotype
15788 *
15789 * @param  {String} type    The mimetype to check
15790 * @return {String}         'probably', 'maybe', or '' (empty string)
15791 */
15792Html5.nativeSourceHandler.canPlayType = function (type) {
15793  // IE9 on Windows 7 without MediaPlayer throws an error here
15794  // https://github.com/videojs/video.js/issues/519
15795  try {
15796    return Html5.TEST_VID.canPlayType(type);
15797  } catch (e) {
15798    return '';
15799  }
15800};
15801
15802/*
15803 * Check if the video element can handle the source natively
15804 *
15805 * @param  {Object} source  The source object
15806 * @return {String}         'probably', 'maybe', or '' (empty string)
15807 */
15808Html5.nativeSourceHandler.canHandleSource = function (source) {
15809  var match, ext;
15810
15811  // If a type was provided we should rely on that
15812  if (source.type) {
15813    return Html5.nativeSourceHandler.canPlayType(source.type);
15814  } else if (source.src) {
15815    // If no type, fall back to checking 'video/[EXTENSION]'
15816    ext = Url.getFileExtension(source.src);
15817
15818    return Html5.nativeSourceHandler.canPlayType('video/' + ext);
15819  }
15820
15821  return '';
15822};
15823
15824/*
15825 * Pass the source to the video element
15826 * Adaptive source handlers will have more complicated workflows before passing
15827 * video data to the video element
15828 *
15829 * @param  {Object} source   The source object
15830 * @param  {Html5}  tech     The instance of the Html5 tech
15831 * @param  {Object} options  The options to pass to the source
15832 */
15833Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
15834  tech.setSrc(source.src);
15835};
15836
15837/*
15838* Clean up the source handler when disposing the player or switching sources..
15839* (no cleanup is needed when supporting the format natively)
15840*/
15841Html5.nativeSourceHandler.dispose = function () {};
15842
15843// Register the native source handler
15844Html5.registerSourceHandler(Html5.nativeSourceHandler);
15845
15846/*
15847 * Check if the volume can be changed in this browser/device.
15848 * Volume cannot be changed in a lot of mobile devices.
15849 * Specifically, it can't be changed from 1 on iOS.
15850 *
15851 * @return {Boolean}
15852 */
15853Html5.canControlVolume = function () {
15854  var volume = Html5.TEST_VID.volume;
15855  Html5.TEST_VID.volume = volume / 2 + 0.1;
15856  return volume !== Html5.TEST_VID.volume;
15857};
15858
15859/*
15860 * Check if playbackRate is supported in this browser/device.
15861 *
15862 * @return {Boolean}
15863 */
15864Html5.canControlPlaybackRate = function () {
15865  // Playback rate API is implemented in Android Chrome, but doesn't do anything
15866  // https://github.com/videojs/video.js/issues/3180
15867  if (browser.IS_ANDROID && browser.IS_CHROME) {
15868    return false;
15869  }
15870  var playbackRate = Html5.TEST_VID.playbackRate;
15871  Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
15872  return playbackRate !== Html5.TEST_VID.playbackRate;
15873};
15874
15875/*
15876 * Check to see if native text tracks are supported by this browser/device
15877 *
15878 * @return {Boolean}
15879 */
15880Html5.supportsNativeTextTracks = function () {
15881  var supportsTextTracks;
15882
15883  // Figure out native text track support
15884  // If mode is a number, we cannot change it because it'll disappear from view.
15885  // Browsers with numeric modes include IE10 and older (<=2013) samsung android models.
15886  // Firefox isn't playing nice either with modifying the mode
15887  // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862
15888  supportsTextTracks = !!Html5.TEST_VID.textTracks;
15889  if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) {
15890    supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number';
15891  }
15892  if (supportsTextTracks && browser.IS_FIREFOX) {
15893    supportsTextTracks = false;
15894  }
15895  if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) {
15896    supportsTextTracks = false;
15897  }
15898
15899  return supportsTextTracks;
15900};
15901
15902/*
15903 * Check to see if native video tracks are supported by this browser/device
15904 *
15905 * @return {Boolean}
15906 */
15907Html5.supportsNativeVideoTracks = function () {
15908  var supportsVideoTracks = !!Html5.TEST_VID.videoTracks;
15909  return supportsVideoTracks;
15910};
15911
15912/*
15913 * Check to see if native audio tracks are supported by this browser/device
15914 *
15915 * @return {Boolean}
15916 */
15917Html5.supportsNativeAudioTracks = function () {
15918  var supportsAudioTracks = !!Html5.TEST_VID.audioTracks;
15919  return supportsAudioTracks;
15920};
15921
15922/**
15923 * An array of events available on the Html5 tech.
15924 *
15925 * @private
15926 * @type {Array}
15927 */
15928Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
15929
15930/*
15931 * Set the tech's volume control support status
15932 *
15933 * @type {Boolean}
15934 */
15935Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume();
15936
15937/*
15938 * Set the tech's playbackRate support status
15939 *
15940 * @type {Boolean}
15941 */
15942Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();
15943
15944/*
15945 * Set the tech's status on moving the video element.
15946 * In iOS, if you move a video element in the DOM, it breaks video playback.
15947 *
15948 * @type {Boolean}
15949 */
15950Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS;
15951
15952/*
15953 * Set the the tech's fullscreen resize support status.
15954 * HTML video is able to automatically resize when going to fullscreen.
15955 * (No longer appears to be used. Can probably be removed.)
15956 */
15957Html5.prototype['featuresFullscreenResize'] = true;
15958
15959/*
15960 * Set the tech's progress event support status
15961 * (this disables the manual progress events of the Tech)
15962 */
15963Html5.prototype['featuresProgressEvents'] = true;
15964
15965/*
15966 * Sets the tech's status on native text track support
15967 *
15968 * @type {Boolean}
15969 */
15970Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();
15971
15972/**
15973 * Sets the tech's status on native text track support
15974 *
15975 * @type {Boolean}
15976 */
15977Html5.prototype['featuresNativeVideoTracks'] = Html5.supportsNativeVideoTracks();
15978
15979/**
15980 * Sets the tech's status on native audio track support
15981 *
15982 * @type {Boolean}
15983 */
15984Html5.prototype['featuresNativeAudioTracks'] = Html5.supportsNativeAudioTracks();
15985
15986// HTML5 Feature detection and Device Fixes --------------------------------- //
15987var canPlayType = undefined;
15988var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15989var mp4RE = /^video\/mp4/i;
15990
15991Html5.patchCanPlayType = function () {
15992  // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15993  if (browser.ANDROID_VERSION >= 4.0) {
15994    if (!canPlayType) {
15995      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
15996    }
15997
15998    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15999      if (type && mpegurlRE.test(type)) {
16000        return 'maybe';
16001      }
16002      return canPlayType.call(this, type);
16003    };
16004  }
16005
16006  // Override Android 2.2 and less canPlayType method which is broken
16007  if (browser.IS_OLD_ANDROID) {
16008    if (!canPlayType) {
16009      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
16010    }
16011
16012    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
16013      if (type && mp4RE.test(type)) {
16014        return 'maybe';
16015      }
16016      return canPlayType.call(this, type);
16017    };
16018  }
16019};
16020
16021Html5.unpatchCanPlayType = function () {
16022  var r = Html5.TEST_VID.constructor.prototype.canPlayType;
16023  Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
16024  canPlayType = null;
16025  return r;
16026};
16027
16028// by default, patch the video element
16029Html5.patchCanPlayType();
16030
16031Html5.disposeMediaElement = function (el) {
16032  if (!el) {
16033    return;
16034  }
16035
16036  if (el.parentNode) {
16037    el.parentNode.removeChild(el);
16038  }
16039
16040  // remove any child track or source nodes to prevent their loading
16041  while (el.hasChildNodes()) {
16042    el.removeChild(el.firstChild);
16043  }
16044
16045  // remove any src reference. not setting `src=''` because that causes a warning
16046  // in firefox
16047  el.removeAttribute('src');
16048
16049  // force the media element to update its loading state by calling load()
16050  // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
16051  if (typeof el.load === 'function') {
16052    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
16053    (function () {
16054      try {
16055        el.load();
16056      } catch (e) {
16057        // not supported
16058      }
16059    })();
16060  }
16061};
16062
16063Html5.resetMediaElement = function (el) {
16064  if (!el) {
16065    return;
16066  }
16067
16068  var sources = el.querySelectorAll('source');
16069  var i = sources.length;
16070  while (i--) {
16071    el.removeChild(sources[i]);
16072  }
16073
16074  // remove any src reference.
16075  // not setting `src=''` because that throws an error
16076  el.removeAttribute('src');
16077
16078  if (typeof el.load === 'function') {
16079    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
16080    (function () {
16081      try {
16082        el.load();
16083      } catch (e) {}
16084    })();
16085  }
16086};
16087
16088_component2['default'].registerComponent('Html5', Html5);
16089_techJs2['default'].registerTech('Html5', Html5);
16090exports['default'] = Html5;
16091module.exports = exports['default'];
16092
16093},{"../../../src/js/tracks/text-track.js":134,"../component":67,"../utils/browser.js":140,"../utils/dom.js":143,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options.js":149,"../utils/to-title-case.js":152,"../utils/url.js":153,"./tech.js":124,"global/document":1,"global/window":2,"object.assign":45,"tsml":55}],123:[function(_dereq_,module,exports){
16094/**
16095 * @file loader.js
16096 */
16097'use strict';
16098
16099exports.__esModule = true;
16100
16101function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16102
16103function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16104
16105function _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; }
16106
16107var _componentJs = _dereq_('../component.js');
16108
16109var _componentJs2 = _interopRequireDefault(_componentJs);
16110
16111var _techJs = _dereq_('./tech.js');
16112
16113var _techJs2 = _interopRequireDefault(_techJs);
16114
16115var _globalWindow = _dereq_('global/window');
16116
16117var _globalWindow2 = _interopRequireDefault(_globalWindow);
16118
16119var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
16120
16121var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
16122
16123/**
16124 * The Media Loader is the component that decides which playback technology to load
16125 * when the player is initialized.
16126 *
16127 * @param {Object} player  Main Player
16128 * @param {Object=} options Object of option names and values
16129 * @param {Function=} ready    Ready callback function
16130 * @extends Component
16131 * @class MediaLoader
16132 */
16133
16134var MediaLoader = (function (_Component) {
16135  _inherits(MediaLoader, _Component);
16136
16137  function MediaLoader(player, options, ready) {
16138    _classCallCheck(this, MediaLoader);
16139
16140    _Component.call(this, player, options, ready);
16141
16142    // If there are no sources when the player is initialized,
16143    // load the first supported playback technology.
16144
16145    if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
16146      for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) {
16147        var techName = _utilsToTitleCaseJs2['default'](j[i]);
16148        var tech = _techJs2['default'].getTech(techName);
16149        // Support old behavior of techs being registered as components.
16150        // Remove once that deprecated behavior is removed.
16151        if (!techName) {
16152          tech = _componentJs2['default'].getComponent(techName);
16153        }
16154
16155        // Check if the browser supports this technology
16156        if (tech && tech.isSupported()) {
16157          player.loadTech_(techName);
16158          break;
16159        }
16160      }
16161    } else {
16162      // // Loop through playback technologies (HTML5, Flash) and check for support.
16163      // // Then load the best source.
16164      // // A few assumptions here:
16165      // //   All playback technologies respect preload false.
16166      player.src(options.playerOptions['sources']);
16167    }
16168  }
16169
16170  return MediaLoader;
16171})(_componentJs2['default']);
16172
16173_componentJs2['default'].registerComponent('MediaLoader', MediaLoader);
16174exports['default'] = MediaLoader;
16175module.exports = exports['default'];
16176
16177},{"../component.js":67,"../utils/to-title-case.js":152,"./tech.js":124,"global/window":2}],124:[function(_dereq_,module,exports){
16178/**
16179 * @file tech.js
16180 * Media Technology Controller - Base class for media playback
16181 * technology controllers like Flash and HTML5
16182 */
16183
16184'use strict';
16185
16186exports.__esModule = true;
16187
16188function _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; } }
16189
16190function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16191
16192function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16193
16194function _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; }
16195
16196var _component = _dereq_('../component');
16197
16198var _component2 = _interopRequireDefault(_component);
16199
16200var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element');
16201
16202var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement);
16203
16204var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list');
16205
16206var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList);
16207
16208var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
16209
16210var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
16211
16212var _tracksTextTrack = _dereq_('../tracks/text-track');
16213
16214var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
16215
16216var _tracksTextTrackList = _dereq_('../tracks/text-track-list');
16217
16218var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList);
16219
16220var _tracksVideoTrack = _dereq_('../tracks/video-track');
16221
16222var _tracksVideoTrack2 = _interopRequireDefault(_tracksVideoTrack);
16223
16224var _tracksVideoTrackList = _dereq_('../tracks/video-track-list');
16225
16226var _tracksVideoTrackList2 = _interopRequireDefault(_tracksVideoTrackList);
16227
16228var _tracksAudioTrackList = _dereq_('../tracks/audio-track-list');
16229
16230var _tracksAudioTrackList2 = _interopRequireDefault(_tracksAudioTrackList);
16231
16232var _tracksAudioTrack = _dereq_('../tracks/audio-track');
16233
16234var _tracksAudioTrack2 = _interopRequireDefault(_tracksAudioTrack);
16235
16236var _utilsFnJs = _dereq_('../utils/fn.js');
16237
16238var Fn = _interopRequireWildcard(_utilsFnJs);
16239
16240var _utilsLogJs = _dereq_('../utils/log.js');
16241
16242var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
16243
16244var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
16245
16246var _utilsBufferJs = _dereq_('../utils/buffer.js');
16247
16248var _mediaErrorJs = _dereq_('../media-error.js');
16249
16250var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
16251
16252var _globalWindow = _dereq_('global/window');
16253
16254var _globalWindow2 = _interopRequireDefault(_globalWindow);
16255
16256var _globalDocument = _dereq_('global/document');
16257
16258var _globalDocument2 = _interopRequireDefault(_globalDocument);
16259
16260/**
16261 * Base class for media (HTML5 Video, Flash) controllers
16262 *
16263 * @param {Object=} options Options object
16264 * @param {Function=} ready Ready callback function
16265 * @extends Component
16266 * @class Tech
16267 */
16268
16269var Tech = (function (_Component) {
16270  _inherits(Tech, _Component);
16271
16272  function Tech() {
16273    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
16274    var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];
16275
16276    _classCallCheck(this, Tech);
16277
16278    // we don't want the tech to report user activity automatically.
16279    // This is done manually in addControlsListeners
16280    options.reportTouchActivity = false;
16281    _Component.call(this, null, options, ready);
16282
16283    // keep track of whether the current source has played at all to
16284    // implement a very limited played()
16285    this.hasStarted_ = false;
16286    this.on('playing', function () {
16287      this.hasStarted_ = true;
16288    });
16289    this.on('loadstart', function () {
16290      this.hasStarted_ = false;
16291    });
16292
16293    this.textTracks_ = options.textTracks;
16294    this.videoTracks_ = options.videoTracks;
16295    this.audioTracks_ = options.audioTracks;
16296
16297    // Manually track progress in cases where the browser/flash player doesn't report it.
16298    if (!this.featuresProgressEvents) {
16299      this.manualProgressOn();
16300    }
16301
16302    // Manually track timeupdates in cases where the browser/flash player doesn't report it.
16303    if (!this.featuresTimeupdateEvents) {
16304      this.manualTimeUpdatesOn();
16305    }
16306
16307    if (options.nativeCaptions === false || options.nativeTextTracks === false) {
16308      this.featuresNativeTextTracks = false;
16309    }
16310
16311    if (!this.featuresNativeTextTracks) {
16312      this.on('ready', this.emulateTextTracks);
16313    }
16314
16315    this.initTextTrackListeners();
16316    this.initTrackListeners();
16317
16318    // Turn on component tap events
16319    this.emitTapEvents();
16320  }
16321
16322  /**
16323   * List of associated text tracks
16324   *
16325   * @type {TextTrackList}
16326   * @private
16327   */
16328
16329  /* Fallbacks for unsupported event types
16330  ================================================================================ */
16331  // Manually trigger progress events based on changes to the buffered amount
16332  // Many flash players and older HTML5 browsers don't send progress or progress-like events
16333  /**
16334   * Turn on progress events
16335   *
16336   * @method manualProgressOn
16337   */
16338
16339  Tech.prototype.manualProgressOn = function manualProgressOn() {
16340    this.on('durationchange', this.onDurationChange);
16341
16342    this.manualProgress = true;
16343
16344    // Trigger progress watching when a source begins loading
16345    this.one('ready', this.trackProgress);
16346  };
16347
16348  /**
16349   * Turn off progress events
16350   *
16351   * @method manualProgressOff
16352   */
16353
16354  Tech.prototype.manualProgressOff = function manualProgressOff() {
16355    this.manualProgress = false;
16356    this.stopTrackingProgress();
16357
16358    this.off('durationchange', this.onDurationChange);
16359  };
16360
16361  /**
16362   * Track progress
16363   *
16364   * @method trackProgress
16365   */
16366
16367  Tech.prototype.trackProgress = function trackProgress() {
16368    this.stopTrackingProgress();
16369    this.progressInterval = this.setInterval(Fn.bind(this, function () {
16370      // Don't trigger unless buffered amount is greater than last time
16371
16372      var numBufferedPercent = this.bufferedPercent();
16373
16374      if (this.bufferedPercent_ !== numBufferedPercent) {
16375        this.trigger('progress');
16376      }
16377
16378      this.bufferedPercent_ = numBufferedPercent;
16379
16380      if (numBufferedPercent === 1) {
16381        this.stopTrackingProgress();
16382      }
16383    }), 500);
16384  };
16385
16386  /**
16387   * Update duration
16388   *
16389   * @method onDurationChange
16390   */
16391
16392  Tech.prototype.onDurationChange = function onDurationChange() {
16393    this.duration_ = this.duration();
16394  };
16395
16396  /**
16397   * Create and get TimeRange object for buffering
16398   *
16399   * @return {TimeRangeObject}
16400   * @method buffered
16401   */
16402
16403  Tech.prototype.buffered = function buffered() {
16404    return _utilsTimeRangesJs.createTimeRange(0, 0);
16405  };
16406
16407  /**
16408   * Get buffered percent
16409   *
16410   * @return {Number}
16411   * @method bufferedPercent
16412   */
16413
16414  Tech.prototype.bufferedPercent = function bufferedPercent() {
16415    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_);
16416  };
16417
16418  /**
16419   * Stops tracking progress by clearing progress interval
16420   *
16421   * @method stopTrackingProgress
16422   */
16423
16424  Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
16425    this.clearInterval(this.progressInterval);
16426  };
16427
16428  /*! Time Tracking -------------------------------------------------------------- */
16429  /**
16430   * Set event listeners for on play and pause and tracking current time
16431   *
16432   * @method manualTimeUpdatesOn
16433   */
16434
16435  Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
16436    this.manualTimeUpdates = true;
16437
16438    this.on('play', this.trackCurrentTime);
16439    this.on('pause', this.stopTrackingCurrentTime);
16440  };
16441
16442  /**
16443   * Remove event listeners for on play and pause and tracking current time
16444   *
16445   * @method manualTimeUpdatesOff
16446   */
16447
16448  Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
16449    this.manualTimeUpdates = false;
16450    this.stopTrackingCurrentTime();
16451    this.off('play', this.trackCurrentTime);
16452    this.off('pause', this.stopTrackingCurrentTime);
16453  };
16454
16455  /**
16456   * Tracks current time
16457   *
16458   * @method trackCurrentTime
16459   */
16460
16461  Tech.prototype.trackCurrentTime = function trackCurrentTime() {
16462    if (this.currentTimeInterval) {
16463      this.stopTrackingCurrentTime();
16464    }
16465    this.currentTimeInterval = this.setInterval(function () {
16466      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
16467    }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
16468  };
16469
16470  /**
16471   * Turn off play progress tracking (when paused or dragging)
16472   *
16473   * @method stopTrackingCurrentTime
16474   */
16475
16476  Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
16477    this.clearInterval(this.currentTimeInterval);
16478
16479    // #1002 - if the video ends right before the next timeupdate would happen,
16480    // the progress bar won't make it all the way to the end
16481    this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
16482  };
16483
16484  /**
16485   * Turn off any manual progress or timeupdate tracking
16486   *
16487   * @method dispose
16488   */
16489
16490  Tech.prototype.dispose = function dispose() {
16491
16492    // clear out all tracks because we can't reuse them between techs
16493    this.clearTracks(['audio', 'video', 'text']);
16494
16495    // Turn off any manual progress or timeupdate tracking
16496    if (this.manualProgress) {
16497      this.manualProgressOff();
16498    }
16499
16500    if (this.manualTimeUpdates) {
16501      this.manualTimeUpdatesOff();
16502    }
16503
16504    _Component.prototype.dispose.call(this);
16505  };
16506
16507  /**
16508   * clear out a track list, or multiple track lists
16509   *
16510   * Note: Techs without source handlers should call this between
16511   * sources for video & audio tracks, as usually you don't want
16512   * to use them between tracks and we have no automatic way to do
16513   * it for you
16514   *
16515   * @method clearTracks
16516   * @param {Array|String} types type(s) of track lists to empty
16517   */
16518
16519  Tech.prototype.clearTracks = function clearTracks(types) {
16520    var _this = this;
16521
16522    types = [].concat(types);
16523    // clear out all tracks because we can't reuse them between techs
16524    types.forEach(function (type) {
16525      var list = _this[type + 'Tracks']() || [];
16526      var i = list.length;
16527      while (i--) {
16528        var track = list[i];
16529        if (type === 'text') {
16530          _this.removeRemoteTextTrack(track);
16531        }
16532        list.removeTrack_(track);
16533      }
16534    });
16535  };
16536
16537  /**
16538   * Reset the tech. Removes all sources and resets readyState.
16539   *
16540   * @method reset
16541   */
16542
16543  Tech.prototype.reset = function reset() {};
16544
16545  /**
16546   * When invoked without an argument, returns a MediaError object
16547   * representing the current error state of the player or null if
16548   * there is no error. When invoked with an argument, set the current
16549   * error state of the player.
16550   * @param {MediaError=} err    Optional an error object
16551   * @return {MediaError}        the current error object or null
16552   * @method error
16553   */
16554
16555  Tech.prototype.error = function error(err) {
16556    if (err !== undefined) {
16557      if (err instanceof _mediaErrorJs2['default']) {
16558        this.error_ = err;
16559      } else {
16560        this.error_ = new _mediaErrorJs2['default'](err);
16561      }
16562      this.trigger('error');
16563    }
16564    return this.error_;
16565  };
16566
16567  /**
16568   * Return the time ranges that have been played through for the
16569   * current source. This implementation is incomplete. It does not
16570   * track the played time ranges, only whether the source has played
16571   * at all or not.
16572   * @return {TimeRangeObject} a single time range if this video has
16573   * played or an empty set of ranges if not.
16574   * @method played
16575   */
16576
16577  Tech.prototype.played = function played() {
16578    if (this.hasStarted_) {
16579      return _utilsTimeRangesJs.createTimeRange(0, 0);
16580    }
16581    return _utilsTimeRangesJs.createTimeRange();
16582  };
16583
16584  /**
16585   * Set current time
16586   *
16587   * @method setCurrentTime
16588   */
16589
16590  Tech.prototype.setCurrentTime = function setCurrentTime() {
16591    // improve the accuracy of manual timeupdates
16592    if (this.manualTimeUpdates) {
16593      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
16594    }
16595  };
16596
16597  /**
16598   * Initialize texttrack listeners
16599   *
16600   * @method initTextTrackListeners
16601   */
16602
16603  Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
16604    var textTrackListChanges = Fn.bind(this, function () {
16605      this.trigger('texttrackchange');
16606    });
16607
16608    var tracks = this.textTracks();
16609
16610    if (!tracks) return;
16611
16612    tracks.addEventListener('removetrack', textTrackListChanges);
16613    tracks.addEventListener('addtrack', textTrackListChanges);
16614
16615    this.on('dispose', Fn.bind(this, function () {
16616      tracks.removeEventListener('removetrack', textTrackListChanges);
16617      tracks.removeEventListener('addtrack', textTrackListChanges);
16618    }));
16619  };
16620
16621  /**
16622   * Initialize audio and video track listeners
16623   *
16624   * @method initTrackListeners
16625   */
16626
16627  Tech.prototype.initTrackListeners = function initTrackListeners() {
16628    var _this2 = this;
16629
16630    var trackTypes = ['video', 'audio'];
16631
16632    trackTypes.forEach(function (type) {
16633      var trackListChanges = function trackListChanges() {
16634        _this2.trigger(type + 'trackchange');
16635      };
16636
16637      var tracks = _this2[type + 'Tracks']();
16638
16639      tracks.addEventListener('removetrack', trackListChanges);
16640      tracks.addEventListener('addtrack', trackListChanges);
16641
16642      _this2.on('dispose', function () {
16643        tracks.removeEventListener('removetrack', trackListChanges);
16644        tracks.removeEventListener('addtrack', trackListChanges);
16645      });
16646    });
16647  };
16648
16649  /**
16650   * Emulate texttracks
16651   *
16652   * @method emulateTextTracks
16653   */
16654
16655  Tech.prototype.emulateTextTracks = function emulateTextTracks() {
16656    var _this3 = this;
16657
16658    var tracks = this.textTracks();
16659    if (!tracks) {
16660      return;
16661    }
16662
16663    if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) {
16664      (function () {
16665        var script = _globalDocument2['default'].createElement('script');
16666        script.src = _this3.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
16667        script.onload = function () {
16668          _this3.trigger('vttjsloaded');
16669        };
16670        script.onerror = function () {
16671          _this3.trigger('vttjserror');
16672        };
16673        _this3.on('dispose', function () {
16674          script.onload = null;
16675          script.onerror = null;
16676        });
16677        // but have not loaded yet and we set it to true before the inject so that
16678        // we don't overwrite the injected window.WebVTT if it loads right away
16679        _globalWindow2['default']['WebVTT'] = true;
16680        _this3.el().parentNode.appendChild(script);
16681      })();
16682    }
16683
16684    var updateDisplay = function updateDisplay() {
16685      return _this3.trigger('texttrackchange');
16686    };
16687    var textTracksChanges = function textTracksChanges() {
16688      updateDisplay();
16689
16690      for (var i = 0; i < tracks.length; i++) {
16691        var track = tracks[i];
16692        track.removeEventListener('cuechange', updateDisplay);
16693        if (track.mode === 'showing') {
16694          track.addEventListener('cuechange', updateDisplay);
16695        }
16696      }
16697    };
16698
16699    textTracksChanges();
16700    tracks.addEventListener('change', textTracksChanges);
16701
16702    this.on('dispose', function () {
16703      tracks.removeEventListener('change', textTracksChanges);
16704    });
16705  };
16706
16707  /**
16708   * Get videotracks
16709   *
16710   * @returns {VideoTrackList}
16711   * @method videoTracks
16712   */
16713
16714  Tech.prototype.videoTracks = function videoTracks() {
16715    this.videoTracks_ = this.videoTracks_ || new _tracksVideoTrackList2['default']();
16716    return this.videoTracks_;
16717  };
16718
16719  /**
16720   * Get audiotracklist
16721   *
16722   * @returns {AudioTrackList}
16723   * @method audioTracks
16724   */
16725
16726  Tech.prototype.audioTracks = function audioTracks() {
16727    this.audioTracks_ = this.audioTracks_ || new _tracksAudioTrackList2['default']();
16728    return this.audioTracks_;
16729  };
16730
16731  /*
16732   * Provide default methods for text tracks.
16733   *
16734   * Html5 tech overrides these.
16735   */
16736
16737  /**
16738   * Get texttracks
16739   *
16740   * @returns {TextTrackList}
16741   * @method textTracks
16742   */
16743
16744  Tech.prototype.textTracks = function textTracks() {
16745    this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default']();
16746    return this.textTracks_;
16747  };
16748
16749  /**
16750   * Get remote texttracks
16751   *
16752   * @returns {TextTrackList}
16753   * @method remoteTextTracks
16754   */
16755
16756  Tech.prototype.remoteTextTracks = function remoteTextTracks() {
16757    this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default']();
16758    return this.remoteTextTracks_;
16759  };
16760
16761  /**
16762   * Get remote htmltrackelements
16763   *
16764   * @returns {HTMLTrackElementList}
16765   * @method remoteTextTrackEls
16766   */
16767
16768  Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
16769    this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default']();
16770    return this.remoteTextTrackEls_;
16771  };
16772
16773  /**
16774   * Creates and returns a remote text track object
16775   *
16776   * @param {String} kind Text track kind (subtitles, captions, descriptions
16777   *                                       chapters and metadata)
16778   * @param {String=} label Label to identify the text track
16779   * @param {String=} language Two letter language abbreviation
16780   * @return {TextTrackObject}
16781   * @method addTextTrack
16782   */
16783
16784  Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
16785    if (!kind) {
16786      throw new Error('TextTrack kind is required but was not provided');
16787    }
16788
16789    return createTrackHelper(this, kind, label, language);
16790  };
16791
16792  /**
16793   * Creates a remote text track object and returns a emulated html track element
16794   *
16795   * @param {Object} options The object should contain values for
16796   * kind, language, label and src (location of the WebVTT file)
16797   * @return {HTMLTrackElement}
16798   * @method addRemoteTextTrack
16799   */
16800
16801  Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
16802    var track = _utilsMergeOptionsJs2['default'](options, {
16803      tech: this
16804    });
16805
16806    var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track);
16807
16808    // store HTMLTrackElement and TextTrack to remote list
16809    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
16810    this.remoteTextTracks().addTrack_(htmlTrackElement.track);
16811
16812    // must come after remoteTextTracks()
16813    this.textTracks().addTrack_(htmlTrackElement.track);
16814
16815    return htmlTrackElement;
16816  };
16817
16818  /**
16819   * Remove remote texttrack
16820   *
16821   * @param {TextTrackObject} track Texttrack to remove
16822   * @method removeRemoteTextTrack
16823   */
16824
16825  Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
16826    this.textTracks().removeTrack_(track);
16827
16828    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
16829
16830    // remove HTMLTrackElement and TextTrack from remote list
16831    this.remoteTextTrackEls().removeTrackElement_(trackElement);
16832    this.remoteTextTracks().removeTrack_(track);
16833  };
16834
16835  /**
16836   * Provide a default setPoster method for techs
16837   * Poster support for techs should be optional, so we don't want techs to
16838   * break if they don't have a way to set a poster.
16839   *
16840   * @method setPoster
16841   */
16842
16843  Tech.prototype.setPoster = function setPoster() {};
16844
16845  /*
16846   * Check if the tech can support the given type
16847   *
16848   * The base tech does not support any type, but source handlers might
16849   * overwrite this.
16850   *
16851   * @param  {String} type    The mimetype to check
16852   * @return {String}         'probably', 'maybe', or '' (empty string)
16853   */
16854
16855  Tech.prototype.canPlayType = function canPlayType() {
16856    return '';
16857  };
16858
16859  /*
16860   * Return whether the argument is a Tech or not.
16861   * Can be passed either a Class like `Html5` or a instance like `player.tech_`
16862   *
16863   * @param {Object} component An item to check
16864   * @return {Boolean}         Whether it is a tech or not
16865   */
16866
16867  Tech.isTech = function isTech(component) {
16868    return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
16869  };
16870
16871  /**
16872   * Registers a Tech
16873   *
16874   * @param {String} name Name of the Tech to register
16875   * @param {Object} tech The tech to register
16876   * @static
16877   * @method registerComponent
16878   */
16879
16880  Tech.registerTech = function registerTech(name, tech) {
16881    if (!Tech.techs_) {
16882      Tech.techs_ = {};
16883    }
16884
16885    if (!Tech.isTech(tech)) {
16886      throw new Error('Tech ' + name + ' must be a Tech');
16887    }
16888
16889    Tech.techs_[name] = tech;
16890    return tech;
16891  };
16892
16893  /**
16894   * Gets a component by name
16895   *
16896   * @param {String} name Name of the component to get
16897   * @return {Component}
16898   * @static
16899   * @method getComponent
16900   */
16901
16902  Tech.getTech = function getTech(name) {
16903    if (Tech.techs_ && Tech.techs_[name]) {
16904      return Tech.techs_[name];
16905    }
16906
16907    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
16908      _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
16909      return _globalWindow2['default'].videojs[name];
16910    }
16911  };
16912
16913  return Tech;
16914})(_component2['default']);
16915
16916Tech.prototype.textTracks_;
16917
16918/**
16919 * List of associated audio tracks
16920 *
16921 * @type {AudioTrackList}
16922 * @private
16923 */
16924Tech.prototype.audioTracks_;
16925
16926/**
16927 * List of associated video tracks
16928 *
16929 * @type {VideoTrackList}
16930 * @private
16931 */
16932Tech.prototype.videoTracks_;
16933
16934var createTrackHelper = function createTrackHelper(self, kind, label, language) {
16935  var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
16936
16937  var tracks = self.textTracks();
16938
16939  options.kind = kind;
16940
16941  if (label) {
16942    options.label = label;
16943  }
16944  if (language) {
16945    options.language = language;
16946  }
16947  options.tech = self;
16948
16949  var track = new _tracksTextTrack2['default'](options);
16950  tracks.addTrack_(track);
16951
16952  return track;
16953};
16954
16955Tech.prototype.featuresVolumeControl = true;
16956
16957// Resizing plugins using request fullscreen reloads the plugin
16958Tech.prototype.featuresFullscreenResize = false;
16959Tech.prototype.featuresPlaybackRate = false;
16960
16961// Optional events that we can manually mimic with timers
16962// currently not triggered by video-js-swf
16963Tech.prototype.featuresProgressEvents = false;
16964Tech.prototype.featuresTimeupdateEvents = false;
16965
16966Tech.prototype.featuresNativeTextTracks = false;
16967
16968/*
16969 * A functional mixin for techs that want to use the Source Handler pattern.
16970 *
16971 * ##### EXAMPLE:
16972 *
16973 *   Tech.withSourceHandlers.call(MyTech);
16974 *
16975 */
16976Tech.withSourceHandlers = function (_Tech) {
16977  /*
16978   * Register a source handler
16979   * Source handlers are scripts for handling specific formats.
16980   * The source handler pattern is used for adaptive formats (HLS, DASH) that
16981   * manually load video data and feed it into a Source Buffer (Media Source Extensions)
16982   * @param  {Function} handler  The source handler
16983   * @param  {Boolean}  first    Register it before any existing handlers
16984   */
16985  _Tech.registerSourceHandler = function (handler, index) {
16986    var handlers = _Tech.sourceHandlers;
16987
16988    if (!handlers) {
16989      handlers = _Tech.sourceHandlers = [];
16990    }
16991
16992    if (index === undefined) {
16993      // add to the end of the list
16994      index = handlers.length;
16995    }
16996
16997    handlers.splice(index, 0, handler);
16998  };
16999
17000  /*
17001   * Check if the tech can support the given type
17002   * @param  {String} type    The mimetype to check
17003   * @return {String}         'probably', 'maybe', or '' (empty string)
17004   */
17005  _Tech.canPlayType = function (type) {
17006    var handlers = _Tech.sourceHandlers || [];
17007    var can = undefined;
17008
17009    for (var i = 0; i < handlers.length; i++) {
17010      can = handlers[i].canPlayType(type);
17011
17012      if (can) {
17013        return can;
17014      }
17015    }
17016
17017    return '';
17018  };
17019
17020  /*
17021   * Return the first source handler that supports the source
17022   * TODO: Answer question: should 'probably' be prioritized over 'maybe'
17023   * @param  {Object} source The source object
17024   * @returns {Object}       The first source handler that supports the source
17025   * @returns {null}         Null if no source handler is found
17026   */
17027  _Tech.selectSourceHandler = function (source) {
17028    var handlers = _Tech.sourceHandlers || [];
17029    var can = undefined;
17030
17031    for (var i = 0; i < handlers.length; i++) {
17032      can = handlers[i].canHandleSource(source);
17033
17034      if (can) {
17035        return handlers[i];
17036      }
17037    }
17038
17039    return null;
17040  };
17041
17042  /*
17043   * Check if the tech can support the given source
17044   * @param  {Object} srcObj  The source object
17045   * @return {String}         'probably', 'maybe', or '' (empty string)
17046   */
17047  _Tech.canPlaySource = function (srcObj) {
17048    var sh = _Tech.selectSourceHandler(srcObj);
17049
17050    if (sh) {
17051      return sh.canHandleSource(srcObj);
17052    }
17053
17054    return '';
17055  };
17056
17057  /*
17058   * When using a source handler, prefer its implementation of
17059   * any function normally provided by the tech.
17060   */
17061  var deferrable = ['seekable', 'duration'];
17062
17063  deferrable.forEach(function (fnName) {
17064    var originalFn = this[fnName];
17065
17066    if (typeof originalFn !== 'function') {
17067      return;
17068    }
17069
17070    this[fnName] = function () {
17071      if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
17072        return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
17073      }
17074      return originalFn.apply(this, arguments);
17075    };
17076  }, _Tech.prototype);
17077
17078  /*
17079   * Create a function for setting the source using a source object
17080   * and source handlers.
17081   * Should never be called unless a source handler was found.
17082   * @param {Object} source  A source object with src and type keys
17083   * @return {Tech} self
17084   */
17085  _Tech.prototype.setSource = function (source) {
17086    var sh = _Tech.selectSourceHandler(source);
17087
17088    if (!sh) {
17089      // Fall back to a native source hander when unsupported sources are
17090      // deliberately set
17091      if (_Tech.nativeSourceHandler) {
17092        sh = _Tech.nativeSourceHandler;
17093      } else {
17094        _utilsLogJs2['default'].error('No source hander found for the current source.');
17095      }
17096    }
17097
17098    // Dispose any existing source handler
17099    this.disposeSourceHandler();
17100    this.off('dispose', this.disposeSourceHandler);
17101
17102    // if we have a source and get another one
17103    // then we are loading something new
17104    // than clear all of our current tracks
17105    if (this.currentSource_) {
17106      this.clearTracks(['audio', 'video']);
17107
17108      this.currentSource_ = null;
17109    }
17110
17111    if (sh !== _Tech.nativeSourceHandler) {
17112
17113      this.currentSource_ = source;
17114
17115      // Catch if someone replaced the src without calling setSource.
17116      // If they do, set currentSource_ to null and dispose our source handler.
17117      this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17118      this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17119      this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17120    }
17121
17122    this.sourceHandler_ = sh.handleSource(source, this, this.options_);
17123    this.on('dispose', this.disposeSourceHandler);
17124
17125    return this;
17126  };
17127
17128  // On the first loadstart after setSource
17129  _Tech.prototype.firstLoadStartListener_ = function () {
17130    this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17131  };
17132
17133  // On successive loadstarts when setSource has not been called again
17134  _Tech.prototype.successiveLoadStartListener_ = function () {
17135    this.currentSource_ = null;
17136    this.disposeSourceHandler();
17137    this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17138  };
17139
17140  /*
17141   * Clean up any existing source handler
17142   */
17143  _Tech.prototype.disposeSourceHandler = function () {
17144    if (this.sourceHandler_ && this.sourceHandler_.dispose) {
17145      this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17146      this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17147      this.sourceHandler_.dispose();
17148      this.sourceHandler_ = null;
17149    }
17150  };
17151};
17152
17153_component2['default'].registerComponent('Tech', Tech);
17154// Old name for Tech
17155_component2['default'].registerComponent('MediaTechController', Tech);
17156Tech.registerTech('Tech', Tech);
17157exports['default'] = Tech;
17158module.exports = exports['default'];
17159
17160},{"../component":67,"../media-error.js":108,"../tracks/audio-track":126,"../tracks/audio-track-list":125,"../tracks/html-track-element":128,"../tracks/html-track-element-list":127,"../tracks/text-track":134,"../tracks/text-track-list":132,"../tracks/video-track":139,"../tracks/video-track-list":138,"../utils/buffer.js":141,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options.js":149,"../utils/time-ranges.js":151,"global/document":1,"global/window":2}],125:[function(_dereq_,module,exports){
17161/**
17162 * @file audio-track-list.js
17163 */
17164'use strict';
17165
17166exports.__esModule = true;
17167
17168function _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; } }
17169
17170function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17171
17172function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17173
17174function _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; }
17175
17176var _trackList = _dereq_('./track-list');
17177
17178var _trackList2 = _interopRequireDefault(_trackList);
17179
17180var _utilsBrowserJs = _dereq_('../utils/browser.js');
17181
17182var browser = _interopRequireWildcard(_utilsBrowserJs);
17183
17184var _globalDocument = _dereq_('global/document');
17185
17186var _globalDocument2 = _interopRequireDefault(_globalDocument);
17187
17188/**
17189 * anywhere we call this function we diverge from the spec
17190 * as we only support one enabled audiotrack at a time
17191 *
17192 * @param {Array|AudioTrackList} list list to work on
17193 * @param {AudioTrack} track the track to skip
17194 */
17195var disableOthers = function disableOthers(list, track) {
17196  for (var i = 0; i < list.length; i++) {
17197    if (track.id === list[i].id) {
17198      continue;
17199    }
17200    // another audio track is enabled, disable it
17201    list[i].enabled = false;
17202  }
17203};
17204/**
17205 * A list of possible audio tracks. All functionality is in the
17206 * base class Tracklist and the spec for AudioTrackList is located at:
17207 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
17208 *
17209 * interface AudioTrackList : EventTarget {
17210 *   readonly attribute unsigned long length;
17211 *   getter AudioTrack (unsigned long index);
17212 *   AudioTrack? getTrackById(DOMString id);
17213 *
17214 *   attribute EventHandler onchange;
17215 *   attribute EventHandler onaddtrack;
17216 *   attribute EventHandler onremovetrack;
17217 * };
17218 *
17219 * @param {AudioTrack[]} tracks a list of audio tracks to instantiate the list with
17220 * @extends TrackList
17221 * @class AudioTrackList
17222 */
17223
17224var AudioTrackList = (function (_TrackList) {
17225  _inherits(AudioTrackList, _TrackList);
17226
17227  function AudioTrackList() {
17228    var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
17229
17230    _classCallCheck(this, AudioTrackList);
17231
17232    var list = undefined;
17233
17234    // make sure only 1 track is enabled
17235    // sorted from last index to first index
17236    for (var i = tracks.length - 1; i >= 0; i--) {
17237      if (tracks[i].enabled) {
17238        disableOthers(tracks, tracks[i]);
17239        break;
17240      }
17241    }
17242
17243    // IE8 forces us to implement inheritance ourselves
17244    // as it does not support Object.defineProperty properly
17245    if (browser.IS_IE8) {
17246      list = _globalDocument2['default'].createElement('custom');
17247      for (var prop in _trackList2['default'].prototype) {
17248        if (prop !== 'constructor') {
17249          list[prop] = _trackList2['default'].prototype[prop];
17250        }
17251      }
17252      for (var prop in AudioTrackList.prototype) {
17253        if (prop !== 'constructor') {
17254          list[prop] = AudioTrackList.prototype[prop];
17255        }
17256      }
17257    }
17258
17259    list = _TrackList.call(this, tracks, list);
17260    list.changing_ = false;
17261
17262    return list;
17263  }
17264
17265  AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
17266    var _this = this;
17267
17268    if (track.enabled) {
17269      disableOthers(this, track);
17270    }
17271
17272    _TrackList.prototype.addTrack_.call(this, track);
17273    // native tracks don't have this
17274    if (!track.addEventListener) {
17275      return;
17276    }
17277
17278    track.addEventListener('enabledchange', function () {
17279      // when we are disabling other tracks (since we don't support
17280      // more than one track at a time) we will set changing_
17281      // to true so that we don't trigger additional change events
17282      if (_this.changing_) {
17283        return;
17284      }
17285      _this.changing_ = true;
17286      disableOthers(_this, track);
17287      _this.changing_ = false;
17288      _this.trigger('change');
17289    });
17290  };
17291
17292  AudioTrackList.prototype.addTrack = function addTrack(track) {
17293    this.addTrack_(track);
17294  };
17295
17296  AudioTrackList.prototype.removeTrack = function removeTrack(track) {
17297    _TrackList.prototype.removeTrack_.call(this, track);
17298  };
17299
17300  return AudioTrackList;
17301})(_trackList2['default']);
17302
17303exports['default'] = AudioTrackList;
17304module.exports = exports['default'];
17305
17306},{"../utils/browser.js":140,"./track-list":136,"global/document":1}],126:[function(_dereq_,module,exports){
17307'use strict';
17308
17309exports.__esModule = true;
17310
17311function _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; } }
17312
17313function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17314
17315function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17316
17317function _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; }
17318
17319var _trackEnums = _dereq_('./track-enums');
17320
17321var _track = _dereq_('./track');
17322
17323var _track2 = _interopRequireDefault(_track);
17324
17325var _utilsMergeOptions = _dereq_('../utils/merge-options');
17326
17327var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
17328
17329var _utilsBrowserJs = _dereq_('../utils/browser.js');
17330
17331var browser = _interopRequireWildcard(_utilsBrowserJs);
17332
17333/**
17334 * A single audio text track as defined in:
17335 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack
17336 *
17337 * interface AudioTrack {
17338 *   readonly attribute DOMString id;
17339 *   readonly attribute DOMString kind;
17340 *   readonly attribute DOMString label;
17341 *   readonly attribute DOMString language;
17342 *   attribute boolean enabled;
17343 * };
17344 *
17345 * @param {Object=} options Object of option names and values
17346 * @class AudioTrack
17347 */
17348
17349var AudioTrack = (function (_Track) {
17350  _inherits(AudioTrack, _Track);
17351
17352  function AudioTrack() {
17353    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
17354
17355    _classCallCheck(this, AudioTrack);
17356
17357    var settings = _utilsMergeOptions2['default'](options, {
17358      kind: _trackEnums.AudioTrackKind[options.kind] || ''
17359    });
17360    // on IE8 this will be a document element
17361    // for every other browser this will be a normal object
17362    var track = _Track.call(this, settings);
17363    var enabled = false;
17364
17365    if (browser.IS_IE8) {
17366      for (var prop in AudioTrack.prototype) {
17367        if (prop !== 'constructor') {
17368          track[prop] = AudioTrack.prototype[prop];
17369        }
17370      }
17371    }
17372
17373    Object.defineProperty(track, 'enabled', {
17374      get: function get() {
17375        return enabled;
17376      },
17377      set: function set(newEnabled) {
17378        // an invalid or unchanged value
17379        if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
17380          return;
17381        }
17382        enabled = newEnabled;
17383        this.trigger('enabledchange');
17384      }
17385    });
17386
17387    // if the user sets this track to selected then
17388    // set selected to that true value otherwise
17389    // we keep it false
17390    if (settings.enabled) {
17391      track.enabled = settings.enabled;
17392    }
17393    track.loaded_ = true;
17394
17395    return track;
17396  }
17397
17398  return AudioTrack;
17399})(_track2['default']);
17400
17401exports['default'] = AudioTrack;
17402module.exports = exports['default'];
17403
17404},{"../utils/browser.js":140,"../utils/merge-options":149,"./track":137,"./track-enums":135}],127:[function(_dereq_,module,exports){
17405/**
17406 * @file html-track-element-list.js
17407 */
17408
17409'use strict';
17410
17411exports.__esModule = true;
17412
17413function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17414
17415function _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; } }
17416
17417function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17418
17419var _utilsBrowserJs = _dereq_('../utils/browser.js');
17420
17421var browser = _interopRequireWildcard(_utilsBrowserJs);
17422
17423var _globalDocument = _dereq_('global/document');
17424
17425var _globalDocument2 = _interopRequireDefault(_globalDocument);
17426
17427var HtmlTrackElementList = (function () {
17428  function HtmlTrackElementList() {
17429    var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
17430
17431    _classCallCheck(this, HtmlTrackElementList);
17432
17433    var list = this;
17434
17435    if (browser.IS_IE8) {
17436      list = _globalDocument2['default'].createElement('custom');
17437
17438      for (var prop in HtmlTrackElementList.prototype) {
17439        if (prop !== 'constructor') {
17440          list[prop] = HtmlTrackElementList.prototype[prop];
17441        }
17442      }
17443    }
17444
17445    list.trackElements_ = [];
17446
17447    Object.defineProperty(list, 'length', {
17448      get: function get() {
17449        return this.trackElements_.length;
17450      }
17451    });
17452
17453    for (var i = 0, _length = trackElements.length; i < _length; i++) {
17454      list.addTrackElement_(trackElements[i]);
17455    }
17456
17457    if (browser.IS_IE8) {
17458      return list;
17459    }
17460  }
17461
17462  HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
17463    this.trackElements_.push(trackElement);
17464  };
17465
17466  HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
17467    var trackElement_ = undefined;
17468
17469    for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) {
17470      if (track === this.trackElements_[i].track) {
17471        trackElement_ = this.trackElements_[i];
17472
17473        break;
17474      }
17475    }
17476
17477    return trackElement_;
17478  };
17479
17480  HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
17481    for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) {
17482      if (trackElement === this.trackElements_[i]) {
17483        this.trackElements_.splice(i, 1);
17484
17485        break;
17486      }
17487    }
17488  };
17489
17490  return HtmlTrackElementList;
17491})();
17492
17493exports['default'] = HtmlTrackElementList;
17494module.exports = exports['default'];
17495
17496},{"../utils/browser.js":140,"global/document":1}],128:[function(_dereq_,module,exports){
17497/**
17498 * @file html-track-element.js
17499 */
17500
17501'use strict';
17502
17503exports.__esModule = true;
17504
17505function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17506
17507function _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; } }
17508
17509function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17510
17511function _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; }
17512
17513var _utilsBrowserJs = _dereq_('../utils/browser.js');
17514
17515var browser = _interopRequireWildcard(_utilsBrowserJs);
17516
17517var _globalDocument = _dereq_('global/document');
17518
17519var _globalDocument2 = _interopRequireDefault(_globalDocument);
17520
17521var _eventTarget = _dereq_('../event-target');
17522
17523var _eventTarget2 = _interopRequireDefault(_eventTarget);
17524
17525var _tracksTextTrack = _dereq_('../tracks/text-track');
17526
17527var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
17528
17529var NONE = 0;
17530var LOADING = 1;
17531var LOADED = 2;
17532var ERROR = 3;
17533
17534/**
17535 * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement
17536 *
17537 * interface HTMLTrackElement : HTMLElement {
17538 *   attribute DOMString kind;
17539 *   attribute DOMString src;
17540 *   attribute DOMString srclang;
17541 *   attribute DOMString label;
17542 *   attribute boolean default;
17543 *
17544 *   const unsigned short NONE = 0;
17545 *   const unsigned short LOADING = 1;
17546 *   const unsigned short LOADED = 2;
17547 *   const unsigned short ERROR = 3;
17548 *   readonly attribute unsigned short readyState;
17549 *
17550 *   readonly attribute TextTrack track;
17551 * };
17552 *
17553 * @param {Object} options TextTrack configuration
17554 * @class HTMLTrackElement
17555 */
17556
17557var HTMLTrackElement = (function (_EventTarget) {
17558  _inherits(HTMLTrackElement, _EventTarget);
17559
17560  function HTMLTrackElement() {
17561    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
17562
17563    _classCallCheck(this, HTMLTrackElement);
17564
17565    _EventTarget.call(this);
17566
17567    var readyState = undefined,
17568        trackElement = this;
17569
17570    if (browser.IS_IE8) {
17571      trackElement = _globalDocument2['default'].createElement('custom');
17572
17573      for (var prop in HTMLTrackElement.prototype) {
17574        if (prop !== 'constructor') {
17575          trackElement[prop] = HTMLTrackElement.prototype[prop];
17576        }
17577      }
17578    }
17579
17580    var track = new _tracksTextTrack2['default'](options);
17581
17582    trackElement.kind = track.kind;
17583    trackElement.src = track.src;
17584    trackElement.srclang = track.language;
17585    trackElement.label = track.label;
17586    trackElement['default'] = track['default'];
17587
17588    Object.defineProperty(trackElement, 'readyState', {
17589      get: function get() {
17590        return readyState;
17591      }
17592    });
17593
17594    Object.defineProperty(trackElement, 'track', {
17595      get: function get() {
17596        return track;
17597      }
17598    });
17599
17600    readyState = NONE;
17601
17602    track.addEventListener('loadeddata', function () {
17603      readyState = LOADED;
17604
17605      trackElement.trigger({
17606        type: 'load',
17607        target: trackElement
17608      });
17609    });
17610
17611    if (browser.IS_IE8) {
17612      return trackElement;
17613    }
17614  }
17615
17616  return HTMLTrackElement;
17617})(_eventTarget2['default']);
17618
17619HTMLTrackElement.prototype.allowedEvents_ = {
17620  load: 'load'
17621};
17622
17623HTMLTrackElement.NONE = NONE;
17624HTMLTrackElement.LOADING = LOADING;
17625HTMLTrackElement.LOADED = LOADED;
17626HTMLTrackElement.ERROR = ERROR;
17627
17628exports['default'] = HTMLTrackElement;
17629module.exports = exports['default'];
17630
17631},{"../event-target":104,"../tracks/text-track":134,"../utils/browser.js":140,"global/document":1}],129:[function(_dereq_,module,exports){
17632/**
17633 * @file text-track-cue-list.js
17634 */
17635'use strict';
17636
17637exports.__esModule = true;
17638
17639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17640
17641function _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; } }
17642
17643function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17644
17645var _utilsBrowserJs = _dereq_('../utils/browser.js');
17646
17647var browser = _interopRequireWildcard(_utilsBrowserJs);
17648
17649var _globalDocument = _dereq_('global/document');
17650
17651var _globalDocument2 = _interopRequireDefault(_globalDocument);
17652
17653/**
17654 * A List of text track cues as defined in:
17655 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist
17656 *
17657 * interface TextTrackCueList {
17658 *   readonly attribute unsigned long length;
17659 *   getter TextTrackCue (unsigned long index);
17660 *   TextTrackCue? getCueById(DOMString id);
17661 * };
17662 *
17663 * @param {Array} cues A list of cues to be initialized with
17664 * @class TextTrackCueList
17665 */
17666
17667var TextTrackCueList = (function () {
17668  function TextTrackCueList(cues) {
17669    _classCallCheck(this, TextTrackCueList);
17670
17671    var list = this;
17672
17673    if (browser.IS_IE8) {
17674      list = _globalDocument2['default'].createElement('custom');
17675
17676      for (var prop in TextTrackCueList.prototype) {
17677        if (prop !== 'constructor') {
17678          list[prop] = TextTrackCueList.prototype[prop];
17679        }
17680      }
17681    }
17682
17683    TextTrackCueList.prototype.setCues_.call(list, cues);
17684
17685    Object.defineProperty(list, 'length', {
17686      get: function get() {
17687        return this.length_;
17688      }
17689    });
17690
17691    if (browser.IS_IE8) {
17692      return list;
17693    }
17694  }
17695
17696  /**
17697   * A setter for cues in this list
17698   *
17699   * @param {Array} cues an array of cues
17700   * @method setCues_
17701   * @private
17702   */
17703
17704  TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
17705    var oldLength = this.length || 0;
17706    var i = 0;
17707    var l = cues.length;
17708
17709    this.cues_ = cues;
17710    this.length_ = cues.length;
17711
17712    var defineProp = function defineProp(index) {
17713      if (!('' + index in this)) {
17714        Object.defineProperty(this, '' + index, {
17715          get: function get() {
17716            return this.cues_[index];
17717          }
17718        });
17719      }
17720    };
17721
17722    if (oldLength < l) {
17723      i = oldLength;
17724
17725      for (; i < l; i++) {
17726        defineProp.call(this, i);
17727      }
17728    }
17729  };
17730
17731  /**
17732   * Get a cue that is currently in the Cue list by id
17733   *
17734   * @param {String} id
17735   * @method getCueById
17736   * @return {Object} a single cue
17737   */
17738
17739  TextTrackCueList.prototype.getCueById = function getCueById(id) {
17740    var result = null;
17741
17742    for (var i = 0, l = this.length; i < l; i++) {
17743      var cue = this[i];
17744
17745      if (cue.id === id) {
17746        result = cue;
17747        break;
17748      }
17749    }
17750
17751    return result;
17752  };
17753
17754  return TextTrackCueList;
17755})();
17756
17757exports['default'] = TextTrackCueList;
17758module.exports = exports['default'];
17759
17760},{"../utils/browser.js":140,"global/document":1}],130:[function(_dereq_,module,exports){
17761/**
17762 * @file text-track-display.js
17763 */
17764'use strict';
17765
17766exports.__esModule = true;
17767
17768function _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; } }
17769
17770function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17771
17772function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
17773
17774function _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, { c
17774onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
17775
17776var _component = _dereq_('../component');
17777
17778var _component2 = _interopRequireDefault(_component);
17779
17780var _menuMenuJs = _dereq_('../menu/menu.js');
17781
17782var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
17783
17784var _menuMenuItemJs = _dereq_('../menu/menu-item.js');
17785
17786var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
17787
17788var _menuMenuButtonJs = _dereq_('../menu/menu-button.js');
17789
17790var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
17791
17792var _utilsFnJs = _dereq_('../utils/fn.js');
17793
17794var Fn = _interopRequireWildcard(_utilsFnJs);
17795
17796var _globalDocument = _dereq_('global/document');
17797
17798var _globalDocument2 = _interopRequireDefault(_globalDocument);
17799
17800var _globalWindow = _dereq_('global/window');
17801
17802var _globalWindow2 = _interopRequireDefault(_globalWindow);
17803
17804var darkGray = '#222';
17805var lightGray = '#ccc';
17806var fontMap = {
17807  monospace: 'monospace',
17808  sansSerif: 'sans-serif',
17809  serif: 'serif',
17810  monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
17811  monospaceSerif: '"Courier New", monospace',
17812  proportionalSansSerif: 'sans-serif',
17813  proportionalSerif: 'serif',
17814  casual: '"Comic Sans MS", Impact, fantasy',
17815  script: '"Monotype Corsiva", cursive',
17816  smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
17817};
17818
17819/**
17820 * The component for displaying text track cues
17821 *
17822 * @param {Object} player  Main Player
17823 * @param {Object=} options Object of option names and values
17824 * @param {Function=} ready    Ready callback function
17825 * @extends Component
17826 * @class TextTrackDisplay
17827 */
17828
17829var TextTrackDisplay = (function (_Component) {
17830  _inherits(TextTrackDisplay, _Component);
17831
17832  function TextTrackDisplay(player, options, ready) {
17833    _classCallCheck(this, TextTrackDisplay);
17834
17835    _Component.call(this, player, options, ready);
17836
17837    player.on('loadstart', Fn.bind(this, this.toggleDisplay));
17838    player.on('texttrackchange', Fn.bind(this, this.updateDisplay));
17839
17840    // This used to be called during player init, but was causing an error
17841    // if a track should show by default and the display hadn't loaded yet.
17842    // Should probably be moved to an external track loader when we support
17843    // tracks that don't need a display.
17844    player.ready(Fn.bind(this, function () {
17845      if (player.tech_ && player.tech_['featuresNativeTextTracks']) {
17846        this.hide();
17847        return;
17848      }
17849
17850      player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
17851
17852      var tracks = this.options_.playerOptions['tracks'] || [];
17853      for (var i = 0; i < tracks.length; i++) {
17854        var track = tracks[i];
17855        this.player_.addRemoteTextTrack(track);
17856      }
17857
17858      var modes = { 'captions': 1, 'subtitles': 1 };
17859      var trackList = this.player_.textTracks();
17860      var firstDesc = undefined;
17861      var firstCaptions = undefined;
17862
17863      if (trackList) {
17864        for (var i = 0; i < trackList.length; i++) {
17865          var track = trackList[i];
17866          if (track['default']) {
17867            if (track.kind === 'descriptions' && !firstDesc) {
17868              firstDesc = track;
17869            } else if (track.kind in modes && !firstCaptions) {
17870              firstCaptions = track;
17871            }
17872          }
17873        }
17874
17875        // We want to show the first default track but captions and subtitles
17876        // take precedence over descriptions.
17877        // So, display the first default captions or subtitles track
17878        // and otherwise the first default descriptions track.
17879        if (firstCaptions) {
17880          firstCaptions.mode = 'showing';
17881        } else if (firstDesc) {
17882          firstDesc.mode = 'showing';
17883        }
17884      }
17885    }));
17886  }
17887
17888  /**
17889  * Add cue HTML to display
17890  *
17891  * @param {Number} color Hex number for color, like #f0e
17892  * @param {Number} opacity Value for opacity,0.0 - 1.0
17893  * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
17894  * @method constructColor
17895  */
17896
17897  /**
17898   * Toggle display texttracks
17899   *
17900   * @method toggleDisplay
17901   */
17902
17903  TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
17904    if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) {
17905      this.hide();
17906    } else {
17907      this.show();
17908    }
17909  };
17910
17911  /**
17912   * Create the component's DOM element
17913   *
17914   * @return {Element}
17915   * @method createEl
17916   */
17917
17918  TextTrackDisplay.prototype.createEl = function createEl() {
17919    return _Component.prototype.createEl.call(this, 'div', {
17920      className: 'vjs-text-track-display'
17921    }, {
17922      'aria-live': 'assertive',
17923      'aria-atomic': 'true'
17924    });
17925  };
17926
17927  /**
17928   * Clear display texttracks
17929   *
17930   * @method clearDisplay
17931   */
17932
17933  TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
17934    if (typeof _globalWindow2['default']['WebVTT'] === 'function') {
17935      _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_);
17936    }
17937  };
17938
17939  /**
17940   * Update display texttracks
17941   *
17942   * @method updateDisplay
17943   */
17944
17945  TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
17946    var tracks = this.player_.textTracks();
17947
17948    this.clearDisplay();
17949
17950    if (!tracks) {
17951      return;
17952    }
17953
17954    // Track display prioritization model: if multiple tracks are 'showing',
17955    //  display the first 'subtitles' or 'captions' track which is 'showing',
17956    //  otherwise display the first 'descriptions' track which is 'showing'
17957
17958    var descriptionsTrack = null;
17959    var captionsSubtitlesTrack = null;
17960
17961    var i = tracks.length;
17962    while (i--) {
17963      var track = tracks[i];
17964      if (track['mode'] === 'showing') {
17965        if (track['kind'] === 'descriptions') {
17966          descriptionsTrack = track;
17967        } else {
17968          captionsSubtitlesTrack = track;
17969        }
17970      }
17971    }
17972
17973    if (captionsSubtitlesTrack) {
17974      this.updateForTrack(captionsSubtitlesTrack);
17975    } else if (descriptionsTrack) {
17976      this.updateForTrack(descriptionsTrack);
17977    }
17978  };
17979
17980  /**
17981   * Add texttrack to texttrack list
17982   *
17983   * @param {TextTrackObject} track Texttrack object to be added to list
17984   * @method updateForTrack
17985   */
17986
17987  TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
17988    if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) {
17989      return;
17990    }
17991
17992    var overrides = this.player_['textTrackSettings'].getValues();
17993
17994    var cues = [];
17995    for (var _i = 0; _i < track['activeCues'].length; _i++) {
17996      cues.push(track['activeCues'][_i]);
17997    }
17998
17999    _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], cues, this.el_);
18000
18001    var i = cues.length;
18002    while (i--) {
18003      var cue = cues[i];
18004      if (!cue) {
18005        continue;
18006      }
18007
18008      var cueDiv = cue.displayState;
18009      if (overrides.color) {
18010        cueDiv.firstChild.style.color = overrides.color;
18011      }
18012      if (overrides.textOpacity) {
18013        tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
18014      }
18015      if (overrides.backgroundColor) {
18016        cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
18017      }
18018      if (overrides.backgroundOpacity) {
18019        tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
18020      }
18021      if (overrides.windowColor) {
18022        if (overrides.windowOpacity) {
18023          tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
18024        } else {
18025          cueDiv.style.backgroundColor = overrides.windowColor;
18026        }
18027      }
18028      if (overrides.edgeStyle) {
18029        if (overrides.edgeStyle === 'dropshadow') {
18030          cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
18031        } else if (overrides.edgeStyle === 'raised') {
18032          cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
18033        } else if (overrides.edgeStyle === 'depressed') {
18034          cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
18035        } else if (overrides.edgeStyle === 'uniform') {
18036          cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
18037        }
18038      }
18039      if (overrides.fontPercent && overrides.fontPercent !== 1) {
18040        var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize);
18041        cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
18042        cueDiv.style.height = 'auto';
18043        cueDiv.style.top = 'auto';
18044        cueDiv.style.bottom = '2px';
18045      }
18046      if (overrides.fontFamily && overrides.fontFamily !== 'default') {
18047        if (overrides.fontFamily === 'small-caps') {
18048          cueDiv.firstChild.style.fontVariant = 'small-caps';
18049        } else {
18050          cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
18051        }
18052      }
18053    }
18054  };
18055
18056  return TextTrackDisplay;
18057})(_component2['default']);
18058
18059function constructColor(color, opacity) {
18060  return 'rgba(' +
18061  // color looks like "#f0e"
18062  parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
18063}
18064
18065/**
18066 * Try to update style
18067 * Some style changes will throw an error, particularly in IE8. Those should be noops.
18068 *
18069 * @param {Element} el The element to be styles
18070 * @param {CSSProperty} style The CSS property to be styled
18071 * @param {CSSStyle} rule The actual style to be applied to the property
18072 * @method tryUpdateStyle
18073 */
18074function tryUpdateStyle(el, style, rule) {
18075  //
18076  try {
18077    el.style[style] = rule;
18078  } catch (e) {}
18079}
18080
18081_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
18082exports['default'] = TextTrackDisplay;
18083module.exports = exports['default'];
18084
18085},{"../component":67,"../menu/menu-button.js":109,"../menu/menu-item.js":110,"../menu/menu.js":111,"../utils/fn.js":145,"global/document":1,"global/window":2}],131:[function(_dereq_,module,exports){
18086/**
18087 * Utilities for capturing text track state and re-creating tracks
18088 * based on a capture.
18089 *
18090 * @file text-track-list-converter.js
18091 */
18092
18093/**
18094 * Examine a single text track and return a JSON-compatible javascript
18095 * object that represents the text track's state.
18096 * @param track {TextTrackObject} the text track to query
18097 * @return {Object} a serializable javascript representation of the
18098 * @private
18099 */
18100'use strict';
18101
18102exports.__esModule = true;
18103var trackToJson_ = function trackToJson_(track) {
18104  var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
18105    if (track[prop]) {
18106      acc[prop] = track[prop];
18107    }
18108
18109    return acc;
18110  }, {
18111    cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
18112      return {
18113        startTime: cue.startTime,
18114        endTime: cue.endTime,
18115        text: cue.text,
18116        id: cue.id
18117      };
18118    })
18119  });
18120
18121  return ret;
18122};
18123
18124/**
18125 * Examine a tech and return a JSON-compatible javascript array that
18126 * represents the state of all text tracks currently configured. The
18127 * return array is compatible with `jsonToTextTracks`.
18128 * @param tech {tech} the tech object to query
18129 * @return {Array} a serializable javascript representation of the
18130 * @function textTracksToJson
18131 */
18132var textTracksToJson = function textTracksToJson(tech) {
18133
18134  var trackEls = tech.$$('track');
18135
18136  var trackObjs = Array.prototype.map.call(trackEls, function (t) {
18137    return t.track;
18138  });
18139  var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
18140    var json = trackToJson_(trackEl.track);
18141    if (trackEl.src) {
18142      json.src = trackEl.src;
18143    }
18144    return json;
18145  });
18146
18147  return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
18148    return trackObjs.indexOf(track) === -1;
18149  }).map(trackToJson_));
18150};
18151
18152/**
18153 * Creates a set of remote text tracks on a tech based on an array of
18154 * javascript text track representations.
18155 * @param json {Array} an array of text track representation objects,
18156 * like those that would be produced by `textTracksToJson`
18157 * @param tech {tech} the tech to create text tracks on
18158 * @function jsonToTextTracks
18159 */
18160var jsonToTextTracks = function jsonToTextTracks(json, tech) {
18161  json.forEach(function (track) {
18162    var addedTrack = tech.addRemoteTextTrack(track).track;
18163    if (!track.src && track.cues) {
18164      track.cues.forEach(function (cue) {
18165        return addedTrack.addCue(cue);
18166      });
18167    }
18168  });
18169
18170  return tech.textTracks();
18171};
18172
18173exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
18174module.exports = exports['default'];
18175
18176},{}],132:[function(_dereq_,module,exports){
18177/**
18178 * @file text-track-list.js
18179 */
18180'use strict';
18181
18182exports.__esModule = true;
18183
18184function _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; } }
18185
18186function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18187
18188function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
18189
18190function _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; }
18191
18192var _trackList = _dereq_('./track-list');
18193
18194var _trackList2 = _interopRequireDefault(_trackList);
18195
18196var _utilsFnJs = _dereq_('../utils/fn.js');
18197
18198var Fn = _interopRequireWildcard(_utilsFnJs);
18199
18200var _utilsBrowserJs = _dereq_('../utils/browser.js');
18201
18202var browser = _interopRequireWildcard(_utilsBrowserJs);
18203
18204var _globalDocument = _dereq_('global/document');
18205
18206var _globalDocument2 = _interopRequireDefault(_globalDocument);
18207
18208/**
18209 * A list of possible text tracks. All functionality is in the
18210 * base class TrackList. The spec for TextTrackList is located at:
18211 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist
18212 *
18213 * interface TextTrackList : EventTarget {
18214 *   readonly attribute unsigned long length;
18215 *   getter TextTrack (unsigned long index);
18216 *   TextTrack? getTrackById(DOMString id);
18217 *
18218 *   attribute EventHandler onchange;
18219 *   attribute EventHandler onaddtrack;
18220 *   attribute EventHandler onremovetrack;
18221 * };
18222 *
18223 * @param {TextTrack[]} tracks A list of tracks to initialize the list with
18224 * @extends TrackList
18225 * @class TextTrackList
18226 */
18227
18228var TextTrackList = (function (_TrackList) {
18229  _inherits(TextTrackList, _TrackList);
18230
18231  function TextTrackList() {
18232    var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
18233
18234    _classCallCheck(this, TextTrackList);
18235
18236    var list = undefined;
18237
18238    // IE8 forces us to implement inheritance ourselves
18239    // as it does not support Object.defineProperty properly
18240    if (browser.IS_IE8) {
18241      list = _globalDocument2['default'].createElement('custom');
18242      for (var prop in _trackList2['default'].prototype) {
18243        if (prop !== 'constructor') {
18244          list[prop] = _trackList2['default'].prototype[prop];
18245        }
18246      }
18247      for (var prop in TextTrackList.prototype) {
18248        if (prop !== 'constructor') {
18249          list[prop] = TextTrackList.prototype[prop];
18250        }
18251      }
18252    }
18253
18254    list = _TrackList.call(this, tracks, list);
18255    return list;
18256  }
18257
18258  TextTrackList.prototype.addTrack_ = function addTrack_(track) {
18259    _TrackList.prototype.addTrack_.call(this, track);
18260    track.addEventListener('modechange', Fn.bind(this, function () {
18261      this.trigger('change');
18262    }));
18263  };
18264
18265  /**
18266   * Remove TextTrack from TextTrackList
18267   * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
18268   *
18269   * @param {TextTrack} rtrack
18270   * @method removeTrack_
18271   * @private
18272   */
18273
18274  TextTrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
18275    var track = undefined;
18276
18277    for (var i = 0, l = this.length; i < l; i++) {
18278      if (this[i] === rtrack) {
18279        track = this[i];
18280        if (track.off) {
18281          track.off();
18282        }
18283
18284        this.tracks_.splice(i, 1);
18285
18286        break;
18287      }
18288    }
18289
18290    if (!track) {
18291      return;
18292    }
18293
18294    this.trigger({
18295      track: track,
18296      type: 'removetrack'
18297    });
18298  };
18299
18300  /**
18301   * Get a TextTrack from TextTrackList by a tracks id
18302   *
18303   * @param {String} id - the id of the track to get
18304   * @method getTrackById
18305   * @return {TextTrack}
18306   * @private
18307   */
18308
18309  TextTrackList.prototype.getTrackById = function getTrackById(id) {
18310    var result = null;
18311
18312    for (var i = 0, l = this.length; i < l; i++) {
18313      var track = this[i];
18314
18315      if (track.id === id) {
18316        result = track;
18317        break;
18318      }
18319    }
18320
18321    return result;
18322  };
18323
18324  return TextTrackList;
18325})(_trackList2['default']);
18326
18327exports['default'] = TextTrackList;
18328module.exports = exports['default'];
18329
18330},{"../utils/browser.js":140,"../utils/fn.js":145,"./track-list":136,"global/document":1}],133:[function(_dereq_,module,exports){
18331/**
18332 * @file text-track-settings.js
18333 */
18334'use strict';
18335
18336exports.__esModule = true;
18337
18338function _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; } }
18339
18340function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18341
18342function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
18343
18344function _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, { c
18344onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18345
18346var _component = _dereq_('../component');
18347
18348var _component2 = _interopRequireDefault(_component);
18349
18350var _utilsEventsJs = _dereq_('../utils/events.js');
18351
18352var Events = _interopRequireWildcard(_utilsEventsJs);
18353
18354var _utilsFnJs = _dereq_('../utils/fn.js');
18355
18356var Fn = _interopRequireWildcard(_utilsFnJs);
18357
18358var _utilsLogJs = _dereq_('../utils/log.js');
18359
18360var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
18361
18362var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
18363
18364var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
18365
18366var _globalWindow = _dereq_('global/window');
18367
18368var _globalWindow2 = _interopRequireDefault(_globalWindow);
18369
18370/**
18371 * Manipulate settings of texttracks
18372 *
18373 * @param {Object} player  Main Player
18374 * @param {Object=} options Object of option names and values
18375 * @extends Component
18376 * @class TextTrackSettings
18377 */
18378
18379var TextTrackSettings = (function (_Component) {
18380  _inherits(TextTrackSettings, _Component);
18381
18382  function TextTrackSettings(player, options) {
18383    _classCallCheck(this, TextTrackSettings);
18384
18385    _Component.call(this, player, options);
18386    this.hide();
18387
18388    // Grab `persistTextTrackSettings` from the player options if not passed in child options
18389    if (options.persistTextTrackSettings === undefined) {
18390      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
18391    }
18392
18393    Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () {
18394      this.saveSettings();
18395      this.hide();
18396    }));
18397
18398    Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () {
18399      this.$('.vjs-fg-color > select').selectedIndex = 0;
18400      this.$('.vjs-bg-color > select').selectedIndex = 0;
18401      this.$('.window-color > select').selectedIndex = 0;
18402      this.$('.vjs-text-opacity > select').selectedIndex = 0;
18403      this.$('.vjs-bg-opacity > select').selectedIndex = 0;
18404      this.$('.vjs-window-opacity > select').selectedIndex = 0;
18405      this.$('.vjs-edge-style select').selectedIndex = 0;
18406      this.$('.vjs-font-family select').selectedIndex = 0;
18407      this.$('.vjs-font-percent select').selectedIndex = 2;
18408      this.updateDisplay();
18409    }));
18410
18411    Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
18412    Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
18413    Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
18414    Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
18415    Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
18416    Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
18417    Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
18418    Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
18419    Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
18420
18421    if (this.options_.persistTextTrackSettings) {
18422      this.restoreSettings();
18423    }
18424  }
18425
18426  /**
18427   * Create the component's DOM element
18428   *
18429   * @return {Element}
18430   * @method createEl
18431   */
18432
18433  TextTrackSettings.prototype.createEl = function createEl() {
18434    return _Component.prototype.createEl.call(this, 'div', {
18435      className: 'vjs-caption-settings vjs-modal-overlay',
18436      innerHTML: captionOptionsMenuTemplate()
18437    });
18438  };
18439
18440  /**
18441   * Get texttrack settings
18442   * Settings are
18443   * .vjs-edge-style
18444   * .vjs-font-family
18445   * .vjs-fg-color
18446   * .vjs-text-opacity
18447   * .vjs-bg-color
18448   * .vjs-bg-opacity
18449   * .window-color
18450   * .vjs-window-opacity
18451   *
18452   * @return {Object}
18453   * @method getValues
18454   */
18455
18456  TextTrackSettings.prototype.getValues = function getValues() {
18457    var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
18458    var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
18459    var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
18460    var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
18461    var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
18462    var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
18463    var windowColor = getSelectedOptionValue(this.$('.window-color > select'));
18464    var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
18465    var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));
18466
18467    var result = {
18468      'backgroundOpacity': bgOpacity,
18469      'textOpacity': textOpacity,
18470      'windowOpacity': windowOpacity,
18471      'edgeStyle': textEdge,
18472      'fontFamily': fontFamily,
18473      'color': fgColor,
18474      'backgroundColor': bgColor,
18475      'windowColor': windowColor,
18476      'fontPercent': fontPercent
18477    };
18478    for (var _name in result) {
18479      if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) {
18480        delete result[_name];
18481      }
18482    }
18483    return result;
18484  };
18485
18486  /**
18487   * Set texttrack settings
18488   * Settings are
18489   * .vjs-edge-style
18490   * .vjs-font-family
18491   * .vjs-fg-color
18492   * .vjs-text-opacity
18493   * .vjs-bg-color
18494   * .vjs-bg-opacity
18495   * .window-color
18496   * .vjs-window-opacity
18497   *
18498   * @param {Object} values Object with texttrack setting values
18499   * @method setValues
18500   */
18501
18502  TextTrackSettings.prototype.setValues = function setValues(values) {
18503    setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
18504    setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
18505    setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
18506    setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
18507    setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
18508    setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
18509    setSelectedOption(this.$('.window-color > select'), values.windowColor);
18510    setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);
18511
18512    var fontPercent = values.fontPercent;
18513
18514    if (fontPercent) {
18515      fontPercent = fontPercent.toFixed(2);
18516    }
18517
18518    setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
18519  };
18520
18521  /**
18522   * Restore texttrack settings
18523   *
18524   * @method restoreSettings
18525   */
18526
18527  TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
18528    var err = undefined,
18529        values = undefined;
18530
18531    try {
18532      var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings'));
18533
18534      err = _safeParseTuple[0];
18535      values = _safeParseTuple[1];
18536
18537      if (err) {
18538        _utilsLogJs2['default'].error(err);
18539      }
18540    } catch (e) {
18541      _utilsLogJs2['default'].warn(e);
18542    }
18543
18544    if (values) {
18545      this.setValues(values);
18546    }
18547  };
18548
18549  /**
18550   * Save texttrack settings to local storage
18551   *
18552   * @method saveSettings
18553   */
18554
18555  TextTrackSettings.prototype.saveSettings = function saveSettings() {
18556    if (!this.options_.persistTextTrackSettings) {
18557      return;
18558    }
18559
18560    var values = this.getValues();
18561    try {
18562      if (Object.getOwnPropertyNames(values).length > 0) {
18563        _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
18564      } else {
18565        _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings');
18566      }
18567    } catch (e) {
18568      _utilsLogJs2['default'].warn(e);
18569    }
18570  };
18571
18572  /**
18573   * Update display of texttrack settings
18574   *
18575   * @method updateDisplay
18576   */
18577
18578  TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
18579    var ttDisplay = this.player_.getChild('textTrackDisplay');
18580    if (ttDisplay) {
18581      ttDisplay.updateDisplay();
18582    }
18583  };
18584
18585  return TextTrackSettings;
18586})(_component2['default']);
18587
18588_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
18589
18590function getSelectedOptionValue(target) {
18591  var selectedOption = undefined;
18592  // not all browsers support selectedOptions, so, fallback to options
18593  if (target.selectedOptions) {
18594    selectedOption = target.selectedOptions[0];
18595  } else if (target.options) {
18596    selectedOption = target.options[target.options.selectedIndex];
18597  }
18598
18599  return selectedOption.value;
18600}
18601
18602function setSelectedOption(target, value) {
18603  if (!value) {
18604    return;
18605  }
18606
18607  var i = undefined;
18608  for (i = 0; i < target.options.length; i++) {
18609    var option = target.options[i];
18610    if (option.value === value) {
18611      break;
18612    }
18613  }
18614
18615  target.selectedIndex = i;
18616}
18617
18618function captionOptionsMenuTemplate() {
18619  var template = '<div class="vjs-tracksettings">\n      <div class="vjs-tracksettings-colors">\n        <div class="vjs-fg-color vjs-tracksetting">\n            <label class="vjs-label">Foreground</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>
18619\n            <span class="vjs-text-opacity vjs-opacity">\n              <select>\n                <option value="">---</option>\n                <option value="1">Opaque</option>\n                <option value="0.5">Semi-Opaque</option>\n              </select>\n            </span>\n        </div> <!-- vjs-fg-color -->\n        <div class="vjs-bg-color vjs-tracksetting">\n            <label class="vjs-label">Background</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-bg-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-bg-color -->\n        <div class="window-color vjs-tracksetting">\n            <label class="vjs-label">Window</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-window-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-window-color -->\n      </div> <!-- vjs-tracksettings -->\n      <div class="vjs-tracksettings-font">\n        <div class="vjs-font-percent vjs-tracksetting">\n          <label class="vjs-label">Font Size</label>\n          <select>\n            <option value="0.50">50%</option>\n            <option value="0.75">75%</option>\n            <option value="1.00" selected>100%</option>\n            <option value="1.25">125%</option>\n            <option value="1.50">150%</option>\n            <option value="1.75">175%</option>\n            <option value="2.00">200%</option>\n            <option value="3.00">300%</option>\n            <option value="4.00">400%</option>\n          </select>\n        </div> <!-- vjs-font-percent -->\n        <div class="vjs-edge-style vjs-tracksetting">\n          <label class="vjs-label">Text Edge Style</label>\n          <select>\n            <option value="none">None</option>\n            <option value="raised">Raised</option>\n            <option value="depressed">Depressed</option>\n            <option value="uniform">Uniform</option>\n            <option value="dropshadow">Dropshadow</option>\n          </select>\n        </div> <!-- vjs-edge-style -->\n        <div class="vjs-font-family vjs-tracksetting">\n          <label class="vjs-label">Font Family</label>\n          <select>\n            <option value="">Default</option>\n            <option value="monospaceSerif">Monospace Serif</option>\n            <option value="proportionalSerif">Proportional Serif</option>\n            <option value="monospaceSansSerif">Monospace Sans-Serif</option>\n            <option value="proportionalSansSerif">Proportional Sans-Serif</option>\n            <option value="casual">Casual</option>\n            <option value="script">Script</option>\n            <option value="small-caps">Small Caps</option>\n          </select>\n        </div> <!-- vjs-font-family -->\n      </div>\n    </div>\n    <div class="vjs-tracksettings-controls">\n      <button class="vjs-default-button">Defaults</button>\n      <button class="vjs-done-button">Done</button>\n    </div>';
18620
18621  return template;
18622}
18623
18624exports['default'] = TextTrackSettings;
18625module.exports = exports['default'];
18626
18627},{"../component":67,"../utils/events.js":144,"../utils/fn.js":145,"../utils/log.js":148,"global/window":2,"safe-json-parse/tuple":54}],134:[function(_dereq_,module,exports){
18628/**
18629 * @file text-track.js
18630 */
18631'use strict';
18632
18633exports.__esModule = true;
18634
18635function _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; } }
18636
18637function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18638
18639function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
18640
18641function _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, { c
18641onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18642
18643var _textTrackCueList = _dereq_('./text-track-cue-list');
18644
18645var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
18646
18647var _utilsFnJs = _dereq_('../utils/fn.js');
18648
18649var Fn = _interopRequireWildcard(_utilsFnJs);
18650
18651var _trackEnums = _dereq_('./track-enums');
18652
18653var _utilsLogJs = _dereq_('../utils/log.js');
18654
18655var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
18656
18657var _globalDocument = _dereq_('global/document');
18658
18659var _globalDocument2 = _interopRequireDefault(_globalDocument);
18660
18661var _globalWindow = _dereq_('global/window');
18662
18663var _globalWindow2 = _interopRequireDefault(_globalWindow);
18664
18665var _trackJs = _dereq_('./track.js');
18666
18667var _trackJs2 = _interopRequireDefault(_trackJs);
18668
18669var _utilsUrlJs = _dereq_('../utils/url.js');
18670
18671var _xhr = _dereq_('xhr');
18672
18673var _xhr2 = _interopRequireDefault(_xhr);
18674
18675var _utilsMergeOptions = _dereq_('../utils/merge-options');
18676
18677var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
18678
18679var _utilsBrowserJs = _dereq_('../utils/browser.js');
18680
18681var browser = _interopRequireWildcard(_utilsBrowserJs);
18682
18683/**
18684 * takes a webvtt file contents and parses it into cues
18685 *
18686 * @param {String} srcContent webVTT file contents
18687 * @param {Track} track track to addcues to
18688 */
18689var parseCues = function parseCues(srcContent, track) {
18690  var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder());
18691  var errors = [];
18692
18693  parser.oncue = function (cue) {
18694    track.addCue(cue);
18695  };
18696
18697  parser.onparsingerror = function (error) {
18698    errors.push(error);
18699  };
18700
18701  parser.onflush = function () {
18702    track.trigger({
18703      type: 'loadeddata',
18704      target: track
18705    });
18706  };
18707
18708  parser.parse(srcContent);
18709  if (errors.length > 0) {
18710    if (console.groupCollapsed) {
18711      console.groupCollapsed('Text Track parsing errors for ' + track.src);
18712    }
18713    errors.forEach(function (error) {
18714      return _utilsLogJs2['default'].error(error);
18715    });
18716    if (console.groupEnd) {
18717      console.groupEnd();
18718    }
18719  }
18720
18721  parser.flush();
18722};
18723
18724/**
18725 * load a track from a  specifed url
18726 *
18727 * @param {String} src url to load track from
18728 * @param {Track} track track to addcues to
18729 */
18730var loadTrack = function loadTrack(src, track) {
18731  var opts = {
18732    uri: src
18733  };
18734  var crossOrigin = _utilsUrlJs.isCrossOrigin(src);
18735
18736  if (crossOrigin) {
18737    opts.cors = crossOrigin;
18738  }
18739
18740  _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) {
18741    if (err) {
18742      return _utilsLogJs2['default'].error(err, response);
18743    }
18744
18745    track.loaded_ = true;
18746
18747    // Make sure that vttjs has loaded, otherwise, wait till it finished loading
18748    // NOTE: this is only used for the alt/video.novtt.js build
18749    if (typeof _globalWindow2['default'].WebVTT !== 'function') {
18750      if (track.tech_) {
18751        (function () {
18752          var loadHandler = function loadHandler() {
18753            return parseCues(responseBody, track);
18754          };
18755          track.tech_.on('vttjsloaded', loadHandler);
18756          track.tech_.on('vttjserror', function () {
18757            _utilsLogJs2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
18758            track.tech_.off('vttjsloaded', loadHandler);
18759          });
18760        })();
18761      }
18762    } else {
18763      parseCues(responseBody, track);
18764    }
18765  }));
18766};
18767
18768/**
18769 * A single text track as defined in:
18770 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
18771 *
18772 * interface TextTrack : EventTarget {
18773 *   readonly attribute TextTrackKind kind;
18774 *   readonly attribute DOMString label;
18775 *   readonly attribute DOMString language;
18776 *
18777 *   readonly attribute DOMString id;
18778 *   readonly attribute DOMString inBandMetadataTrackDispatchType;
18779 *
18780 *   attribute TextTrackMode mode;
18781 *
18782 *   readonly attribute TextTrackCueList? cues;
18783 *   readonly attribute TextTrackCueList? activeCues;
18784 *
18785 *   void addCue(TextTrackCue cue);
18786 *   void removeCue(TextTrackCue cue);
18787 *
18788 *   attribute EventHandler oncuechange;
18789 * };
18790 *
18791 * @param {Object=} options Object of option names and values
18792 * @extends Track
18793 * @class TextTrack
18794 */
18795
18796var TextTrack = (function (_Track) {
18797  _inherits(TextTrack, _Track);
18798
18799  function TextTrack() {
18800    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
18801
18802    _classCallCheck(this, TextTrack);
18803
18804    if (!options.tech) {
18805      throw new Error('A tech was not provided.');
18806    }
18807
18808    var settings = _utilsMergeOptions2['default'](options, {
18809      kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
18810      language: options.language || options.srclang || ''
18811    });
18812    var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
18813    var default_ = settings['default'];
18814
18815    if (settings.kind === 'metadata' || settings.kind === 'chapters') {
18816      mode = 'hidden';
18817    }
18818    // on IE8 this will be a document element
18819    // for every other browser this will be a normal object
18820    var tt = _Track.call(this, settings);
18821    tt.tech_ = settings.tech;
18822
18823    if (browser.IS_IE8) {
18824      for (var prop in TextTrack.prototype) {
18825        if (prop !== 'constructor') {
18826          tt[prop] = TextTrack.prototype[prop];
18827        }
18828      }
18829    }
18830
18831    tt.cues_ = [];
18832    tt.activeCues_ = [];
18833
18834    var cues = new _textTrackCueList2['default'](tt.cues_);
18835    var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
18836    var changed = false;
18837    var timeupdateHandler = Fn.bind(tt, function () {
18838      this.activeCues;
18839      if (changed) {
18840        this.trigger('cuechange');
18841        changed = false;
18842      }
18843    });
18844
18845    if (mode !== 'disabled') {
18846      tt.tech_.on('timeupdate', timeupdateHandler);
18847    }
18848
18849    Object.defineProperty(tt, 'default', {
18850      get: function get() {
18851        return default_;
18852      },
18853      set: function set() {}
18854    });
18855
18856    Object.defineProperty(tt, 'mode', {
18857      get: function get() {
18858        return mode;
18859      },
18860      set: function set(newMode) {
18861        if (!_trackEnums.TextTrackMode[newMode]) {
18862          return;
18863        }
18864        mode = newMode;
18865        if (mode === 'showing') {
18866          this.tech_.on('timeupdate', timeupdateHandler);
18867        }
18868        this.trigger('modechange');
18869      }
18870    });
18871
18872    Object.defineProperty(tt, 'cues', {
18873      get: function get() {
18874        if (!this.loaded_) {
18875          return null;
18876        }
18877
18878        return cues;
18879      },
18880      set: function set() {}
18881    });
18882
18883    Object.defineProperty(tt, 'activeCues', {
18884      get: function get() {
18885        if (!this.loaded_) {
18886          return null;
18887        }
18888
18889        // nothing to do
18890        if (this.cues.length === 0) {
18891          return activeCues;
18892        }
18893
18894        var ct = this.tech_.currentTime();
18895        var active = [];
18896
18897        for (var i = 0, l = this.cues.length; i < l; i++) {
18898          var cue = this.cues[i];
18899
18900          if (cue.startTime <= ct && cue.endTime >= ct) {
18901            active.push(cue);
18902          } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
18903            active.push(cue);
18904          }
18905        }
18906
18907        changed = false;
18908
18909        if (active.length !== this.activeCues_.length) {
18910          changed = true;
18911        } else {
18912          for (var i = 0; i < active.length; i++) {
18913            if (this.activeCues_.indexOf(active[i]) === -1) {
18914              changed = true;
18915            }
18916          }
18917        }
18918
18919        this.activeCues_ = active;
18920        activeCues.setCues_(this.activeCues_);
18921
18922        return activeCues;
18923      },
18924      set: function set() {}
18925    });
18926
18927    if (settings.src) {
18928      tt.src = settings.src;
18929      loadTrack(settings.src, tt);
18930    } else {
18931      tt.loaded_ = true;
18932    }
18933
18934    return tt;
18935  }
18936
18937  /**
18938   * cuechange - One or more cues in the track have become active or stopped being active.
18939   */
18940
18941  /**
18942   * add a cue to the internal list of cues
18943   *
18944   * @param {Object} cue the cue to add to our internal list
18945   * @method addCue
18946   */
18947
18948  TextTrack.prototype.addCue = function addCue(cue) {
18949    var tracks = this.tech_.textTracks();
18950
18951    if (tracks) {
18952      for (var i = 0; i < tracks.length; i++) {
18953        if (tracks[i] !== this) {
18954          tracks[i].removeCue(cue);
18955        }
18956      }
18957    }
18958
18959    this.cues_.push(cue);
18960    this.cues.setCues_(this.cues_);
18961  };
18962
18963  /**
18964   * remvoe a cue from our internal list
18965   *
18966   * @param {Object} removeCue the cue to remove from our internal list
18967   * @method removeCue
18968   */
18969
18970  TextTrack.prototype.removeCue = function removeCue(_removeCue) {
18971    var removed = false;
18972
18973    for (var i = 0, l = this.cues_.length; i < l; i++) {
18974      var cue = this.cues_[i];
18975
18976      if (cue === _removeCue) {
18977        this.cues_.splice(i, 1);
18978        removed = true;
18979      }
18980    }
18981
18982    if (removed) {
18983      this.cues.setCues_(this.cues_);
18984    }
18985  };
18986
18987  return TextTrack;
18988})(_trackJs2['default']);
18989
18990TextTrack.prototype.allowedEvents_ = {
18991  cuechange: 'cuechange'
18992};
18993
18994exports['default'] = TextTrack;
18995module.exports = exports['default'];
18996
18997},{"../utils/browser.js":140,"../utils/fn.js":145,"../utils/log.js":148,"../utils/merge-options":149,"../utils/url.js":153,"./text-track-cue-list":129,"./track-enums":135,"./track.js":137,"global/document":1,"global/window":2,"xhr":56}],135:[function(_dereq_,module,exports){
18998/**
18999 * @file track-kinds.js
19000 */
19001
19002/**
19003 * https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
19004 *
19005 * enum VideoTrackKind {
19006 *   "alternative",
19007 *   "captions",
19008 *   "main",
19009 *   "sign",
19010 *   "subtitles",
19011 *   "commentary",
19012 *   "",
19013 * };
19014 */
19015'use strict';
19016
19017exports.__esModule = true;
19018var VideoTrackKind = {
19019  alternative: 'alternative',
19020  captions: 'captions',
19021  main: 'main',
19022  sign: 'sign',
19023  subtitles: 'subtitles',
19024  commentary: 'commentary'
19025};
19026
19027/**
19028 * https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
19029 *
19030 * enum AudioTrackKind {
19031 *   "alternative",
19032 *   "descriptions",
19033 *   "main",
19034 *   "main-desc",
19035 *   "translation",
19036 *   "commentary",
19037 *   "",
19038 * };
19039 */
19040var AudioTrackKind = {
19041  alternative: 'alternative',
19042  descriptions: 'descriptions',
19043  main: 'main',
19044  'main-desc': 'main-desc',
19045  translation: 'translation',
19046  commentary: 'commentary'
19047};
19048
19049/**
19050 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind
19051 *
19052 * enum TextTrackKind {
19053 *   "subtitles",
19054 *   "captions",
19055 *   "descriptions",
19056 *   "chapters",
19057 *   "metadata"
19058 * };
19059 */
19060var TextTrackKind = {
19061  subtitles: 'subtitles',
19062  captions: 'captions',
19063  descriptions: 'descriptions',
19064  chapters: 'chapters',
19065  metadata: 'metadata'
19066};
19067
19068/**
19069 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
19070 *
19071 * enum TextTrackMode { "disabled",  "hidden",  "showing" };
19072 */
19073var TextTrackMode = {
19074  disabled: 'disabled',
19075  hidden: 'hidden',
19076  showing: 'showing'
19077};
19078
19079/* jshint ignore:start */
19080// we ignore jshint here because it does not see
19081// AudioTrackKind as defined here
19082exports['default'] = { VideoTrackKind: VideoTrackKind, AudioTrackKind: AudioTrackKind, TextTrackKind: TextTrackKind, TextTrackMode: TextTrackMode };
19083
19084/* jshint ignore:end */
19085module.exports = exports['default'];
19086
19087},{}],136:[function(_dereq_,module,exports){
19088/**
19089 * @file track-list.js
19090 */
19091'use strict';
19092
19093exports.__esModule = true;
19094
19095function _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; } }
19096
19097function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19098
19099function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
19100
19101function _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; }
19102
19103var _eventTarget = _dereq_('../event-target');
19104
19105var _eventTarget2 = _interopRequireDefault(_eventTarget);
19106
19107var _utilsFnJs = _dereq_('../utils/fn.js');
19108
19109var Fn = _interopRequireWildcard(_utilsFnJs);
19110
19111var _utilsBrowserJs = _dereq_('../utils/browser.js');
19112
19113var browser = _interopRequireWildcard(_utilsBrowserJs);
19114
19115var _globalDocument = _dereq_('global/document');
19116
19117var _globalDocument2 = _interopRequireDefault(_globalDocument);
19118
19119/**
19120 * Common functionaliy between Text, Audio, and Video TrackLists
19121 * Interfaces defined in the following spec:
19122 * @link https://html.spec.whatwg.org/multipage/embedded-content.html
19123 *
19124 * @param {Track[]} tracks A list of tracks to initialize the list with
19125 * @param {Object} list the child object with inheritance done manually for ie8
19126 * @extends EventTarget
19127 * @class TrackList
19128 */
19129
19130var TrackList = (function (_EventTarget) {
19131  _inherits(TrackList, _EventTarget);
19132
19133  function TrackList() {
19134    var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
19135    var list = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
19136
19137    _classCallCheck(this, TrackList);
19138
19139    _EventTarget.call(this);
19140    if (!list) {
19141      list = this;
19142      if (browser.IS_IE8) {
19143        list = _globalDocument2['default'].createElement('custom');
19144        for (var prop in TrackList.prototype) {
19145          if (prop !== 'constructor') {
19146            list[prop] = TrackList.prototype[prop];
19147          }
19148        }
19149      }
19150    }
19151
19152    list.tracks_ = [];
19153    Object.defineProperty(list, 'length', {
19154      get: function get() {
19155        return this.tracks_.length;
19156      }
19157    });
19158
19159    for (var i = 0; i < tracks.length; i++) {
19160      list.addTrack_(tracks[i]);
19161    }
19162
19163    return list;
19164  }
19165
19166  /**
19167   * change - One or more tracks in the track list have been enabled or disabled.
19168   * addtrack - A track has been added to the track list.
19169   * removetrack - A track has been removed from the track list.
19170   */
19171
19172  /**
19173   * Add a Track from TrackList
19174   *
19175   * @param {Mixed} track
19176   * @method addTrack_
19177   * @private
19178   */
19179
19180  TrackList.prototype.addTrack_ = function addTrack_(track) {
19181    var index = this.tracks_.length;
19182
19183    if (!('' + index in this)) {
19184      Object.defineProperty(this, index, {
19185        get: function get() {
19186          return this.tracks_[index];
19187        }
19188      });
19189    }
19190
19191    // Do not add duplicate tracks
19192    if (this.tracks_.indexOf(track) === -1) {
19193      this.tracks_.push(track);
19194      this.trigger({
19195        track: track,
19196        type: 'addtrack'
19197      });
19198    }
19199  };
19200
19201  /**
19202   * Remove a Track from TrackList
19203   *
19204   * @param {Track} rtrack track to be removed
19205   * @method removeTrack_
19206   * @private
19207   */
19208
19209  TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
19210    var track = undefined;
19211
19212    for (var i = 0, l = this.length; i < l; i++) {
19213      if (this[i] === rtrack) {
19214        track = this[i];
19215        if (track.off) {
19216          track.off();
19217        }
19218
19219        this.tracks_.splice(i, 1);
19220
19221        break;
19222      }
19223    }
19224
19225    if (!track) {
19226      return;
19227    }
19228
19229    this.trigger({
19230      track: track,
19231      type: 'removetrack'
19232    });
19233  };
19234
19235  /**
19236   * Get a Track from the TrackList by a tracks id
19237   *
19238   * @param {String} id - the id of the track to get
19239   * @method getTrackById
19240   * @return {Track}
19241   * @private
19242   */
19243
19244  TrackList.prototype.getTrackById = function getTrackById(id) {
19245    var result = null;
19246
19247    for (var i = 0, l = this.length; i < l; i++) {
19248      var track = this[i];
19249      if (track.id === id) {
19250        result = track;
19251        break;
19252      }
19253    }
19254
19255    return result;
19256  };
19257
19258  return TrackList;
19259})(_eventTarget2['default']);
19260
19261TrackList.prototype.allowedEvents_ = {
19262  change: 'change',
19263  addtrack: 'addtrack',
19264  removetrack: 'removetrack'
19265};
19266
19267// emulate attribute EventHandler support to allow for feature detection
19268for (var _event in TrackList.prototype.allowedEvents_) {
19269  TrackList.prototype['on' + _event] = null;
19270}
19271
19272exports['default'] = TrackList;
19273module.exports = exports['default'];
19274
19275},{"../event-target":104,"../utils/browser.js":140,"../utils/fn.js":145,"global/document":1}],137:[function(_dereq_,module,exports){
19276/**
19277 * @file track.js
19278 */
19279'use strict';
19280
19281exports.__esModule = true;
19282
19283function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19284
19285function _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; } }
19286
19287function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
19288
19289function _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, { c
19289onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
19290
19291var _utilsBrowserJs = _dereq_('../utils/browser.js');
19292
19293var browser = _interopRequireWildcard(_utilsBrowserJs);
19294
19295var _globalDocument = _dereq_('global/document');
19296
19297var _globalDocument2 = _interopRequireDefault(_globalDocument);
19298
19299var _utilsGuidJs = _dereq_('../utils/guid.js');
19300
19301var Guid = _interopRequireWildcard(_utilsGuidJs);
19302
19303var _eventTarget = _dereq_('../event-target');
19304
19305var _eventTarget2 = _interopRequireDefault(_eventTarget);
19306
19307/**
19308 * setup the common parts of an audio, video, or text track
19309 * @link https://html.spec.whatwg.org/multipage/embedded-content.html
19310 *
19311 * @param {String} type The type of track we are dealing with audio|video|text
19312 * @param {Object=} options Object of option names and values
19313 * @extends EventTarget
19314 * @class Track
19315 */
19316
19317var Track = (function (_EventTarget) {
19318  _inherits(Track, _EventTarget);
19319
19320  function Track() {
19321    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
19322
19323    _classCallCheck(this, Track);
19324
19325    _EventTarget.call(this);
19326
19327    var track = this;
19328    if (browser.IS_IE8) {
19329      track = _globalDocument2['default'].createElement('custom');
19330      for (var prop in Track.prototype) {
19331        if (prop !== 'constructor') {
19332          track[prop] = Track.prototype[prop];
19333        }
19334      }
19335    }
19336
19337    var trackProps = {
19338      id: options.id || 'vjs_track_' + Guid.newGUID(),
19339      kind: options.kind || '',
19340      label: options.label || '',
19341      language: options.language || ''
19342    };
19343
19344    var _loop = function (key) {
19345      Object.defineProperty(track, key, {
19346        get: function get() {
19347          return trackProps[key];
19348        },
19349        set: function set() {}
19350      });
19351    };
19352
19353    for (var key in trackProps) {
19354      _loop(key);
19355    }
19356
19357    return track;
19358  }
19359
19360  return Track;
19361})(_eventTarget2['default']);
19362
19363exports['default'] = Track;
19364module.exports = exports['default'];
19365
19366},{"../event-target":104,"../utils/browser.js":140,"../utils/guid.js":147,"global/document":1}],138:[function(_dereq_,module,exports){
19367/**
19368 * @file video-track-list.js
19369 */
19370'use strict';
19371
19372exports.__esModule = true;
19373
19374function _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; } }
19375
19376function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19377
19378function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
19379
19380function _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; }
19381
19382var _trackList = _dereq_('./track-list');
19383
19384var _trackList2 = _interopRequireDefault(_trackList);
19385
19386var _utilsBrowserJs = _dereq_('../utils/browser.js');
19387
19388var browser = _interopRequireWildcard(_utilsBrowserJs);
19389
19390var _globalDocument = _dereq_('global/document');
19391
19392var _globalDocument2 = _interopRequireDefault(_globalDocument);
19393
19394/**
19395 * disable other video tracks before selecting the new one
19396 *
19397 * @param {Array|VideoTrackList} list list to work on
19398 * @param {VideoTrack} track the track to skip
19399 */
19400var disableOthers = function disableOthers(list, track) {
19401  for (var i = 0; i < list.length; i++) {
19402    if (track.id === list[i].id) {
19403      continue;
19404    }
19405    // another audio track is enabled, disable it
19406    list[i].selected = false;
19407  }
19408};
19409
19410/**
19411* A list of possiblee video tracks. Most functionality is in the
19412 * base class Tracklist and the spec for VideoTrackList is located at:
19413 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
19414 *
19415 * interface VideoTrackList : EventTarget {
19416 *   readonly attribute unsigned long length;
19417 *   getter VideoTrack (unsigned long index);
19418 *   VideoTrack? getTrackById(DOMString id);
19419 *   readonly attribute long selectedIndex;
19420 *
19421 *   attribute EventHandler onchange;
19422 *   attribute EventHandler onaddtrack;
19423 *   attribute EventHandler onremovetrack;
19424 * };
19425 *
19426 * @param {VideoTrack[]} tracks a list of video tracks to instantiate the list with
19427 # @extends TrackList
19428 * @class VideoTrackList
19429 */
19430
19431var VideoTrackList = (function (_TrackList) {
19432  _inherits(VideoTrackList, _TrackList);
19433
19434  function VideoTrackList() {
19435    var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
19436
19437    _classCallCheck(this, VideoTrackList);
19438
19439    var list = undefined;
19440
19441    // make sure only 1 track is enabled
19442    // sorted from last index to first index
19443    for (var i = tracks.length - 1; i >= 0; i--) {
19444      if (tracks[i].selected) {
19445        disableOthers(tracks, tracks[i]);
19446        break;
19447      }
19448    }
19449
19450    // IE8 forces us to implement inheritance ourselves
19451    // as it does not support Object.defineProperty properly
19452    if (browser.IS_IE8) {
19453      list = _globalDocument2['default'].createElement('custom');
19454      for (var prop in _trackList2['default'].prototype) {
19455        if (prop !== 'constructor') {
19456          list[prop] = _trackList2['default'].prototype[prop];
19457        }
19458      }
19459      for (var prop in VideoTrackList.prototype) {
19460        if (prop !== 'constructor') {
19461          list[prop] = VideoTrackList.prototype[prop];
19462        }
19463      }
19464    }
19465
19466    list = _TrackList.call(this, tracks, list);
19467    list.changing_ = false;
19468
19469    Object.defineProperty(list, 'selectedIndex', {
19470      get: function get() {
19471        for (var i = 0; i < this.length; i++) {
19472          if (this[i].selected) {
19473            return i;
19474          }
19475        }
19476        return -1;
19477      },
19478      set: function set() {}
19479    });
19480
19481    return list;
19482  }
19483
19484  VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
19485    var _this = this;
19486
19487    if (track.selected) {
19488      disableOthers(this, track);
19489    }
19490
19491    _TrackList.prototype.addTrack_.call(this, track);
19492    // native tracks don't have this
19493    if (!track.addEventListener) {
19494      return;
19495    }
19496    track.addEventListener('selectedchange', function () {
19497      if (_this.changing_) {
19498        return;
19499      }
19500      _this.changing_ = true;
19501      disableOthers(_this, track);
19502      _this.changing_ = false;
19503      _this.trigger('change');
19504    });
19505  };
19506
19507  VideoTrackList.prototype.addTrack = function addTrack(track) {
19508    this.addTrack_(track);
19509  };
19510
19511  VideoTrackList.prototype.removeTrack = function removeTrack(track) {
19512    _TrackList.prototype.removeTrack_.call(this, track);
19513  };
19514
19515  return VideoTrackList;
19516})(_trackList2['default']);
19517
19518exports['default'] = VideoTrackList;
19519module.exports = exports['default'];
19520
19521},{"../utils/browser.js":140,"./track-list":136,"global/document":1}],139:[function(_dereq_,module,exports){
19522'use strict';
19523
19524exports.__esModule = true;
19525
19526function _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; } }
19527
19528function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19529
19530function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
19531
19532function _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; }
19533
19534var _trackEnums = _dereq_('./track-enums');
19535
19536var _track = _dereq_('./track');
19537
19538var _track2 = _interopRequireDefault(_track);
19539
19540var _utilsMergeOptions = _dereq_('../utils/merge-options');
19541
19542var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
19543
19544var _utilsBrowserJs = _dereq_('../utils/browser.js');
19545
19546var browser = _interopRequireWildcard(_utilsBrowserJs);
19547
19548/**
19549 * A single video text track as defined in:
19550 * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack
19551 *
19552 * interface VideoTrack {
19553 *   readonly attribute DOMString id;
19554 *   readonly attribute DOMString kind;
19555 *   readonly attribute DOMString label;
19556 *   readonly attribute DOMString language;
19557 *   attribute boolean selected;
19558 * };
19559 *
19560 * @param {Object=} options Object of option names and values
19561 * @class VideoTrack
19562 */
19563
19564var VideoTrack = (function (_Track) {
19565  _inherits(VideoTrack, _Track);
19566
19567  function VideoTrack() {
19568    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
19569
19570    _classCallCheck(this, VideoTrack);
19571
19572    var settings = _utilsMergeOptions2['default'](options, {
19573      kind: _trackEnums.VideoTrackKind[options.kind] || ''
19574    });
19575
19576    // on IE8 this will be a document element
19577    // for every other browser this will be a normal object
19578    var track = _Track.call(this, settings);
19579    var selected = false;
19580
19581    if (browser.IS_IE8) {
19582      for (var prop in VideoTrack.prototype) {
19583        if (prop !== 'constructor') {
19584          track[prop] = VideoTrack.prototype[prop];
19585        }
19586      }
19587    }
19588
19589    Object.defineProperty(track, 'selected', {
19590      get: function get() {
19591        return selected;
19592      },
19593      set: function set(newSelected) {
19594        // an invalid or unchanged value
19595        if (typeof newSelected !== 'boolean' || newSelected === selected) {
19596          return;
19597        }
19598        selected = newSelected;
19599        this.trigger('selectedchange');
19600      }
19601    });
19602
19603    // if the user sets this track to selected then
19604    // set selected to that true value otherwise
19605    // we keep it false
19606    if (settings.selected) {
19607      track.selected = settings.selected;
19608    }
19609
19610    return track;
19611  }
19612
19613  return VideoTrack;
19614})(_track2['default']);
19615
19616exports['default'] = VideoTrack;
19617module.exports = exports['default'];
19618
19619},{"../utils/browser.js":140,"../utils/merge-options":149,"./track":137,"./track-enums":135}],140:[function(_dereq_,module,exports){
19620/**
19621 * @file browser.js
19622 */
19623'use strict';
19624
19625exports.__esModule = true;
19626
19627function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19628
19629var _globalDocument = _dereq_('global/document');
19630
19631var _globalDocument2 = _interopRequireDefault(_globalDocument);
19632
19633var _globalWindow = _dereq_('global/window');
19634
19635var _globalWindow2 = _interopRequireDefault(_globalWindow);
19636
19637var USER_AGENT = _globalWindow2['default'].navigator.userAgent;
19638var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
19639var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
19640
19641/*
19642 * Device is an iPhone
19643 *
19644 * @type {Boolean}
19645 * @constant
19646 * @private
19647 */
19648var IS_IPAD = /iPad/i.test(USER_AGENT);
19649
19650exports.IS_IPAD = IS_IPAD;
19651// The Facebook app's UIWebView identifies as both an iPhone and iPad, so
19652// to identify iPhones, we need to exclude iPads.
19653// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
19654var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
19655exports.IS_IPHONE = IS_IPHONE;
19656var IS_IPOD = /iPod/i.test(USER_AGENT);
19657exports.IS_IPOD = IS_IPOD;
19658var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
19659
19660exports.IS_IOS = IS_IOS;
19661var IOS_VERSION = (function () {
19662  var match = USER_AGENT.match(/OS (\d+)_/i);
19663  if (match && match[1]) {
19664    return match[1];
19665  }
19666})();
19667
19668exports.IOS_VERSION = IOS_VERSION;
19669var IS_ANDROID = /Android/i.test(USER_AGENT);
19670exports.IS_ANDROID = IS_ANDROID;
19671var ANDROID_VERSION = (function () {
19672  // This matches Android Major.Minor.Patch versions
19673  // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
19674  var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
19675      major,
19676      minor;
19677
19678  if (!match) {
19679    return null;
19680  }
19681
19682  major = match[1] && parseFloat(match[1]);
19683  minor = match[2] && parseFloat(match[2]);
19684
19685  if (major && minor) {
19686    return parseFloat(match[1] + '.' + match[2]);
19687  } else if (major) {
19688    return major;
19689  } else {
19690    return null;
19691  }
19692})();
19693exports.ANDROID_VERSION = ANDROID_VERSION;
19694// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
19695var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
19696exports.IS_OLD_ANDROID = IS_OLD_ANDROID;
19697var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
19698
19699exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID;
19700var IS_FIREFOX = /Firefox/i.test(USER_AGENT);
19701exports.IS_FIREFOX = IS_FIREFOX;
19702var IS_EDGE = /Edge/i.test(USER_AGENT);
19703exports.IS_EDGE = IS_EDGE;
19704var IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
19705exports.IS_CHROME = IS_CHROME;
19706var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
19707
19708exports.IS_IE8 = IS_IE8;
19709var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch);
19710exports.TOUCH_ENABLED = TOUCH_ENABLED;
19711var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style);
19712exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED;
19713
19714},{"global/document":1,"global/window":2}],141:[function(_dereq_,module,exports){
19715/**
19716 * @file buffer.js
19717 */
19718'use strict';
19719
19720exports.__esModule = true;
19721exports.bufferedPercent = bufferedPercent;
19722
19723var _timeRangesJs = _dereq_('./time-ranges.js');
19724
19725/**
19726 * Compute how much your video has been buffered
19727 *
19728 * @param  {Object} Buffered object
19729 * @param  {Number} Total duration
19730 * @return {Number} Percent buffered of the total duration
19731 * @private
19732 * @function bufferedPercent
19733 */
19734
19735function bufferedPercent(buffered, duration) {
19736  var bufferedDuration = 0,
19737      start,
19738      end;
19739
19740  if (!duration) {
19741    return 0;
19742  }
19743
19744  if (!buffered || !buffered.length) {
19745    buffered = _timeRangesJs.createTimeRange(0, 0);
19746  }
19747
19748  for (var i = 0; i < buffered.length; i++) {
19749    start = buffered.start(i);
19750    end = buffered.end(i);
19751
19752    // buffered end can be bigger than duration by a very small fraction
19753    if (end > duration) {
19754      end = duration;
19755    }
19756
19757    bufferedDuration += end - start;
19758  }
19759
19760  return bufferedDuration / duration;
19761}
19762
19763},{"./time-ranges.js":151}],142:[function(_dereq_,module,exports){
19764'use strict';
19765
19766exports.__esModule = true;
19767
19768function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19769
19770var _logJs = _dereq_('./log.js');
19771
19772var _logJs2 = _interopRequireDefault(_logJs);
19773
19774/**
19775 * Object containing the default behaviors for available handler methods.
19776 *
19777 * @private
19778 * @type {Object}
19779 */
19780var defaultBehaviors = {
19781  get: function get(obj, key) {
19782    return obj[key];
19783  },
19784  set: function set(obj, key, value) {
19785    obj[key] = value;
19786    return true;
19787  }
19788};
19789
19790/**
19791 * Expose private objects publicly using a Proxy to log deprecation warnings.
19792 *
19793 * Browsers that do not support Proxy objects will simply return the `target`
19794 * object, so it can be directly exposed.
19795 *
19796 * @param {Object} target The target object.
19797 * @param {Object} messages Messages to display from a Proxy. Only operations
19798 *                          with an associated message will be proxied.
19799 * @param {String} [messages.get]
19800 * @param {String} [messages.set]
19801 * @return {Object} A Proxy if supported or the `target` argument.
19802 */
19803
19804exports['default'] = function (target) {
19805  var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
19806
19807  if (typeof Proxy === 'function') {
19808    var _ret = (function () {
19809      var handler = {};
19810
19811      // Build a handler object based on those keys that have both messages
19812      // and default behaviors.
19813      Object.keys(messages).forEach(function (key) {
19814        if (defaultBehaviors.hasOwnProperty(key)) {
19815          handler[key] = function () {
19816            _logJs2['default'].warn(messages[key]);
19817            return defaultBehaviors[key].apply(this, arguments);
19818          };
19819        }
19820      });
19821
19822      return {
19823        v: new Proxy(target, handler)
19824      };
19825    })();
19826
19827    if (typeof _ret === 'object') return _ret.v;
19828  }
19829  return target;
19830};
19831
19832module.exports = exports['default'];
19833
19834},{"./log.js":148}],143:[function(_dereq_,module,exports){
19835/**
19836 * @file dom.js
19837 */
19838'use strict';
19839
19840exports.__esModule = true;
19841exports.getEl = getEl;
19842exports.createEl = createEl;
19843exports.textContent = textContent;
19844exports.insertElFirst = insertElFirst;
19845exports.getElData = getElData;
19846exports.hasElData = hasElData;
19847exports.removeElData = removeElData;
19848exports.hasElClass = hasElClass;
19849exports.addElClass = addElClass;
19850exports.removeElClass = removeElClass;
19851exports.toggleElClass = toggleElClass;
19852exports.setElAttributes = setElAttributes;
19853exports.getElAttributes = getElAttributes;
19854exports.blockTextSelection = blockTextSelection;
19855exports.unblockTextSelection = unblockTextSelection;
19856exports.findElPosition = findElPosition;
19857exports.getPointerPosition = getPointerPosition;
19858exports.isEl = isEl;
19859exports.isTextNode = isTextNode;
19860exports.emptyEl = emptyEl;
19861exports.normalizeContent = normalizeContent;
19862exports.appendContent = appendContent;
19863exports.insertContent = insertContent;
19864
19865var _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 ', '.']);
19866
19867function _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; } }
19868
19869function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19870
19871function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
19872
19873var _globalDocument = _dereq_('global/document');
19874
19875var _globalDocument2 = _interopRequireDefault(_globalDocument);
19876
19877var _globalWindow = _dereq_('global/window');
19878
19879var _globalWindow2 = _interopRequireDefault(_globalWindow);
19880
19881var _guidJs = _dereq_('./guid.js');
19882
19883var Guid = _interopRequireWildcard(_guidJs);
19884
19885var _logJs = _dereq_('./log.js');
19886
19887var _logJs2 = _interopRequireDefault(_logJs);
19888
19889var _tsml = _dereq_('tsml');
19890
19891var _tsml2 = _interopRequireDefault(_tsml);
19892
19893/**
19894 * Detect if a value is a string with any non-whitespace characters.
19895 *
19896 * @param  {String} str
19897 * @return {Boolean}
19898 */
19899function isNonBlankString(str) {
19900  return typeof str === 'string' && /\S/.test(str);
19901}
19902
19903/**
19904 * Throws an error if the passed string has whitespace. This is used by
19905 * class methods to be relatively consistent with the classList API.
19906 *
19907 * @param  {String} str
19908 * @return {Boolean}
19909 */
19910function throwIfWhitespace(str) {
19911  if (/\s/.test(str)) {
19912    throw new Error('class has illegal whitespace characters');
19913  }
19914}
19915
19916/**
19917 * Produce a regular expression for matching a class name.
19918 *
19919 * @param  {String} className
19920 * @return {RegExp}
19921 */
19922function classRegExp(className) {
19923  return new RegExp('(^|\\s)' + className + '($|\\s)');
19924}
19925
19926/**
19927 * Creates functions to query the DOM using a given method.
19928 *
19929 * @function createQuerier
19930 * @private
19931 * @param  {String} method
19932 * @return {Function}
19933 */
19934function createQuerier(method) {
19935  return function (selector, context) {
19936    if (!isNonBlankString(selector)) {
19937      return _globalDocument2['default'][method](null);
19938    }
19939    if (isNonBlankString(context)) {
19940      context = _globalDocument2['default'].querySelector(context);
19941    }
19942    return (isEl(context) ? context : _globalDocument2['default'])[method](selector);
19943  };
19944}
19945
19946/**
19947 * Shorthand for document.getElementById()
19948 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
19949 *
19950 * @param  {String} id  Element ID
19951 * @return {Element}    Element with supplied ID
19952 * @function getEl
19953 */
19954
19955function getEl(id) {
19956  if (id.indexOf('#') === 0) {
19957    id = id.slice(1);
19958  }
19959
19960  return _globalDocument2['default'].getElementById(id);
19961}
19962
19963/**
19964 * Creates an element and applies properties.
19965 *
19966 * @param  {String} [tagName='div'] Name of tag to be created.
19967 * @param  {Object} [properties={}] Element properties to be applied.
19968 * @param  {Object} [attributes={}] Element attributes to be applied.
19969 * @return {Element}
19970 * @function createEl
19971 */
19972
19973function createEl() {
19974  var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
19975  var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
19976  var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
19977
19978  var el = _globalDocument2['default'].createElement(tagName);
19979
vendor: 4,103 bytes, lines 19980-20164
19980  Object.getOwnPropertyNames(properties).forEach(function (propName) {
19981    var val = properties[propName];
19982
19983    // See #2176
19984    // We originally were accepting both properties and attributes in the
19985    // same object, but that doesn't work so well.
19986    if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
19987      _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val));
19988      el.setAttribute(propName, val);
19989    } else {
19990      el[propName] = val;
19991    }
19992  });
19993
19994  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
19995    var val = attributes[attrName];
19996    el.setAttribute(attrName, attributes[attrName]);
19997  });
19998
19999  return el;
20000}
20001
20002/**
20003 * Injects text into an element, replacing any existing contents entirely.
20004 *
20005 * @param  {Element} el
20006 * @param  {String} text
20007 * @return {Element}
20008 * @function textContent
20009 */
20010
20011function textContent(el, text) {
20012  if (typeof el.textContent === 'undefined') {
20013    el.innerText = text;
20014  } else {
20015    el.textContent = text;
20016  }
20017}
20018
20019/**
20020 * Insert an element as the first child node of another
20021 *
20022 * @param  {Element} child   Element to insert
20023 * @param  {Element} parent Element to insert child into
20024 * @private
20025 * @function insertElFirst
20026 */
20027
20028function insertElFirst(child, parent) {
20029  if (parent.firstChild) {
20030    parent.insertBefore(child, parent.firstChild);
20031  } else {
20032    parent.appendChild(child);
20033  }
20034}
20035
20036/**
20037 * Element Data Store. Allows for binding data to an element without putting it directly on the element.
20038 * Ex. Event listeners are stored here.
20039 * (also from jsninja.com, slightly modified and updated for closure compiler)
20040 *
20041 * @type {Object}
20042 * @private
20043 */
20044var elData = {};
20045
20046/*
20047 * Unique attribute name to store an element's guid in
20048 *
20049 * @type {String}
20050 * @constant
20051 * @private
20052 */
20053var elIdAttr = 'vdata' + new Date().getTime();
20054
20055/**
20056 * Returns the cache object where data for an element is stored
20057 *
20058 * @param  {Element} el Element to store data for.
20059 * @return {Object}
20060 * @function getElData
20061 */
20062
20063function getElData(el) {
20064  var id = el[elIdAttr];
20065
20066  if (!id) {
20067    id = el[elIdAttr] = Guid.newGUID();
20068  }
20069
20070  if (!elData[id]) {
20071    elData[id] = {};
20072  }
20073
20074  return elData[id];
20075}
20076
20077/**
20078 * Returns whether or not an element has cached data
20079 *
20080 * @param  {Element} el A dom element
20081 * @return {Boolean}
20082 * @private
20083 * @function hasElData
20084 */
20085
20086function hasElData(el) {
20087  var id = el[elIdAttr];
20088
20089  if (!id) {
20090    return false;
20091  }
20092
20093  return !!Object.getOwnPropertyNames(elData[id]).length;
20094}
20095
20096/**
20097 * Delete data for the element from the cache and the guid attr from getElementById
20098 *
20099 * @param  {Element} el Remove data for an element
20100 * @private
20101 * @function removeElData
20102 */
20103
20104function removeElData(el) {
20105  var id = el[elIdAttr];
20106
20107  if (!id) {
20108    return;
20109  }
20110
20111  // Remove all stored data
20112  delete elData[id];
20113
20114  // Remove the elIdAttr property from the DOM node
20115  try {
20116    delete el[elIdAttr];
20117  } catch (e) {
20118    if (el.removeAttribute) {
20119      el.removeAttribute(elIdAttr);
20120    } else {
20121      // IE doesn't appear to support removeAttribute on the document element
20122      el[elIdAttr] = null;
20123    }
20124  }
20125}
20126
20127/**
20128 * Check if an element has a CSS class
20129 *
20130 * @function hasElClass
20131 * @param {Element} element Element to check
20132 * @param {String} classToCheck Classname to check
20133 */
20134
20135function hasElClass(element, classToCheck) {
20136  if (element.classList) {
20137    return element.classList.contains(classToCheck);
20138  } else {
20139    throwIfWhitespace(classToCheck);
20140    return classRegExp(classToCheck).test(element.className);
20141  }
20142}
20143
20144/**
20145 * Add a CSS class name to an element
20146 *
20147 * @function addElClass
20148 * @param {Element} element    Element to add class name to
20149 * @param {String} classToAdd Classname to add
20150 */
20151
20152function addElClass(element, classToAdd) {
20153  if (element.classList) {
20154    element.classList.add(classToAdd);
20155
20156    // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
20157    // in the case of classList not being supported.
20158  } else if (!hasElClass(element, classToAdd)) {
20159      element.className = (element.className + ' ' + classToAdd).trim();
20160    }
20161
20162  return element;
20163}
20164
20165/**
20166 * Remove a CSS class name from an element
20167 *
20168 * @function removeElClass
20169 * @param {Element} element    Element to remove from class name
20170 * @param {String} classToRemove Classname to remove
20171 */
20172
20173function removeElClass(element, classToRemove) {
20174  if (element.classList) {
20175    element.classList.remove(classToRemove);
20176  } else {
20177    throwIfWhitespace(classToRemove);
20178    element.className = element.className.split(/\s+/).filter(function (c) {
20179      return c !== classToRemove;
20180    }).join(' ');
20181  }
20182
20183  return element;
20184}
20185
20186/**
20187 * Adds or removes a CSS class name on an element depending on an optional
20188 * condition or the presence/absence of the class name.
20189 *
20190 * @function toggleElClass
20191 * @param    {Element} element
20192 * @param    {String} classToToggle
20193 * @param    {Boolean|Function} [predicate]
20194 *           Can be a function that returns a Boolean. If `true`, the class
20195 *           will be added; if `false`, the class will be removed. If not
20196 *           given, the class will be added if not present and vice versa.
20197 */
20198
20199function toggleElClass(element, classToToggle, predicate) {
20200
20201  // This CANNOT use `classList` internally because IE does not support the
20202  // second parameter to the `classList.toggle()` method! Which is fine because
20203  // `classList` will be used by the add/remove functions.
20204  var has = hasElClass(element, classToToggle);
20205
20206  if (typeof predicate === 'function') {
20207    predicate = predicate(element, classToToggle);
20208  }
20209
20210  if (typeof predicate !== 'boolean') {
20211    predicate = !has;
20212  }
20213
20214  // If the necessary class operation matches the current state of the
20215  // element, no action is required.
20216  if (predicate === has) {
20217    return;
20218  }
20219
20220  if (predicate) {
20221    addElClass(element, classToToggle);
20222  } else {
20223    removeElClass(element, classToToggle);
20224  }
20225
20226  return element;
20227}
20228
20229/**
20230 * Apply attributes to an HTML element.
20231 *
20232 * @param  {Element} el         Target element.
20233 * @param  {Object=} attributes Element attributes to be applied.
20234 * @private
20235 * @function setElAttributes
20236 */
20237
20238function setElAttributes(el, attributes) {
20239  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
20240    var attrValue = attributes[attrName];
20241
20242    if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
20243      el.removeAttribute(attrName);
20244    } else {
20245      el.setAttribute(attrName, attrValue === true ? '' : attrValue);
20246    }
20247  });
20248}
20249
20250/**
20251 * Get an element's attribute values, as defined on the HTML tag
20252 * Attributes are not the same as properties. They're defined on the tag
20253 * or with setAttribute (which shouldn't be used with HTML)
20254 * This will return true or false for boolean attributes.
20255 *
20256 * @param  {Element} tag Element from which to get tag attributes
20257 * @return {Object}
20258 * @private
20259 * @function getElAttributes
20260 */
20261
20262function getElAttributes(tag) {
20263  var obj, knownBooleans, attrs, attrName, attrVal;
20264
20265  obj = {};
20266
20267  // known boolean attributes
20268  // we can check for matching boolean properties, but older browsers
20269  // won't know about HTML5 boolean attributes that we still read from
20270  knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
20271
20272  if (tag && tag.attributes && tag.attributes.length > 0) {
20273    attrs = tag.attributes;
20274
20275    for (var i = attrs.length - 1; i >= 0; i--) {
20276      attrName = attrs[i].name;
20277      attrVal = attrs[i].value;
20278
20279      // check for known booleans
20280      // the matching element property will return a value for typeof
20281      if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
20282        // the value of an included boolean attribute is typically an empty
20283        // string ('') which would equal false if we just check for a false value.
20284        // we also don't want support bad code like autoplay='false'
20285        attrVal = attrVal !== null ? true : false;
20286      }
20287
20288      obj[attrName] = attrVal;
20289    }
20290  }
20291
20292  return obj;
20293}
20294
20295/**
20296 * Attempt to block the ability to select text while dragging controls
20297 *
20298 * @return {Boolean}
20299 * @function blockTextSelection
20300 */
20301
20302function blockTextSelection() {
20303  _globalDocument2['default'].body.focus();
20304  _globalDocument2['default'].onselectstart = function () {
20305    return false;
20306  };
20307}
20308
20309/**
20310 * Turn off text selection blocking
20311 *
20312 * @return {Boolean}
20313 * @function unblockTextSelection
20314 */
20315
20316function unblockTextSelection() {
20317  _globalDocument2['default'].onselectstart = function () {
20318    return true;
20319  };
20320}
20321
20322/**
20323 * Offset Left
20324 * getBoundingClientRect technique from
20325 * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
20326 *
20327 * @function findElPosition
20328 * @param {Element} el Element from which to get offset
20329 * @return {Object}
20330 */
20331
20332function findElPosition(el) {
20333  var box = undefined;
20334
20335  if (el.getBoundingClientRect && el.parentNode) {
20336    box = el.getBoundingClientRect();
20337  }
20338
20339  if (!box) {
20340    return {
20341      left: 0,
20342      top: 0
20343    };
20344  }
20345
20346  var docEl = _globalDocument2['default'].documentElement;
20347  var body = _globalDocument2['default'].body;
20348
20349  var clientLeft = docEl.clientLeft || body.clientLeft || 0;
20350  var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft;
20351  var left = box.left + scrollLeft - clientLeft;
20352
20353  var clientTop = docEl.clientTop || body.clientTop || 0;
20354  var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop;
20355  var top = box.top + scrollTop - clientTop;
20356
20357  // Android sometimes returns slightly off decimal values, so need to round
20358  return {
20359    left: Math.round(left),
20360    top: Math.round(top)
20361  };
20362}
20363
20364/**
20365 * Get pointer position in element
20366 * Returns an object with x and y coordinates.
20367 * The base on the coordinates are the bottom left of the element.
20368 *
20369 * @function getPointerPosition
20370 * @param {Element} el Element on which to get the pointer position on
20371 * @param {Event} event Event object
20372 * @return {Object} This object will have x and y coordinates corresponding to the mouse position
20373 */
20374
20375function getPointerPosition(el, event) {
20376  var position = {};
20377  var box = findElPosition(el);
20378  var boxW = el.offsetWidth;
20379  var boxH = el.offsetHeight;
20380
20381  var boxY = box.top;
20382  var boxX = box.left;
20383  var pageY = event.pageY;
20384  var pageX = event.pageX;
20385
20386  if (event.changedTouches) {
20387    pageX = event.changedTouches[0].pageX;
20388    pageY = event.changedTouches[0].pageY;
20389  }
20390
20391  position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
20392  position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
20393
20394  return position;
20395}
20396
20397/**
20398 * Determines, via duck typing, whether or not a value is a DOM element.
20399 *
20400 * @function isEl
20401 * @param    {Mixed} value
20402 * @return   {Boolean}
20403 */
20404
20405function isEl(value) {
20406  return !!value && typeof value === 'object' && value.nodeType === 1;
20407}
20408
20409/**
20410 * Determines, via duck typing, whether or not a value is a text node.
20411 *
20412 * @param  {Mixed} value
20413 * @return {Boolean}
20414 */
20415
20416function isTextNode(value) {
20417  return !!value && typeof value === 'object' && value.nodeType === 3;
20418}
20419
20420/**
20421 * Empties the contents of an element.
20422 *
20423 * @function emptyEl
20424 * @param    {Element} el
20425 * @return   {Element}
20426 */
20427
20428function emptyEl(el) {
20429  while (el.firstChild) {
20430    el.removeChild(el.firstChild);
20431  }
20432  return el;
20433}
20434
20435/**
20436 * Normalizes content for eventual insertion into the DOM.
20437 *
20438 * This allows a wide range of content definition methods, but protects
20439 * from falling into the trap of simply writing to `innerHTML`, which is
20440 * an XSS concern.
20441 *
20442 * The content for an element can be passed in multiple types and
20443 * combinations, whose behavior is as follows:
20444 *
20445 * - String
20446 *   Normalized into a text node.
20447 *
20448 * - Element, TextNode
20449 *   Passed through.
20450 *
20451 * - Array
20452 *   A one-dimensional array of strings, elements, nodes, or functions (which
20453 *   return single strings, elements, or nodes).
20454 *
20455 * - Function
20456 *   If the sole argument, is expected to produce a string, element,
20457 *   node, or array.
20458 *
20459 * @function normalizeContent
20460 * @param    {String|Element|TextNode|Array|Function} content
20461 * @return   {Array}
20462 */
20463
20464function normalizeContent(content) {
20465
20466  // First, invoke content if it is a function. If it produces an array,
20467  // that needs to happen before normalization.
20468  if (typeof content === 'function') {
20469    content = content();
20470  }
20471
20472  // Next up, normalize to an array, so one or many items can be normalized,
20473  // filtered, and returned.
20474  return (Array.isArray(content) ? content : [content]).map(function (value) {
20475
20476    // First, invoke value if it is a function to produce a new value,
20477    // which will be subsequently normalized to a Node of some kind.
20478    if (typeof value === 'function') {
20479      value = value();
20480    }
20481
20482    if (isEl(value) || isTextNode(value)) {
20483      return value;
20484    }
20485
20486    if (typeof value === 'string' && /\S/.test(value)) {
20487      return _globalDocument2['default'].createTextNode(value);
20488    }
20489  }).filter(function (value) {
20490    return value;
20491  });
20492}
20493
20494/**
20495 * Normalizes and appends content to an element.
20496 *
20497 * @function appendContent
20498 * @param    {Element} el
20499 * @param    {String|Element|TextNode|Array|Function} content
20500 *           See: `normalizeContent`
20501 * @return   {Element}
20502 */
20503
20504function appendContent(el, content) {
20505  normalizeContent(content).forEach(function (node) {
20506    return el.appendChild(node);
20507  });
20508  return el;
20509}
20510
20511/**
20512 * Normalizes and inserts content into an element; this is identical to
20513 * `appendContent()`, except it empties the element first.
20514 *
20515 * @function insertContent
20516 * @param    {Element} el
20517 * @param    {String|Element|TextNode|Array|Function} content
20518 *           See: `normalizeContent`
20519 * @return   {Element}
20520 */
20521
20522function insertContent(el, content) {
20523  return appendContent(emptyEl(el), content);
20524}
20525
20526/**
20527 * Finds a single DOM element matching `selector` within the optional
20528 * `context` of another DOM element (defaulting to `document`).
20529 *
20530 * @function $
20531 * @param    {String} selector
20532 *           A valid CSS selector, which will be passed to `querySelector`.
20533 *
20534 * @param    {Element|String} [context=document]
20535 *           A DOM element within which to query. Can also be a selector
20536 *           string in which case the first matching element will be used
20537 *           as context. If missing (or no element matches selector), falls
20538 *           back to `document`.
20539 *
20540 * @return   {Element|null}
20541 */
20542var $ = createQuerier('querySelector');
20543
20544exports.$ = $;
20545/**
20546 * Finds a all DOM elements matching `selector` within the optional
20547 * `context` of another DOM element (defaulting to `document`).
20548 *
20549 * @function $$
20550 * @param    {String} selector
20551 *           A valid CSS selector, which will be passed to `querySelectorAll`.
20552 *
20553 * @param    {Element|String} [context=document]
20554 *           A DOM element within which to query. Can also be a selector
20555 *           string in which case the first matching element will be used
20556 *           as context. If missing (or no element matches selector), falls
20557 *           back to `document`.
20558 *
20559 * @return   {NodeList}
20560 */
20561var $$ = createQuerier('querySelectorAll');
20562exports.$$ = $$;
20563
20564},{"./guid.js":147,"./log.js":148,"global/document":1,"global/window":2,"tsml":55}],144:[function(_dereq_,module,exports){
20565/**
20566 * @file events.js
20567 *
20568 * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
20569 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
20570 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
20571 * robust as jquery's, so there's probably some differences.
20572 */
20573
20574'use strict';
20575
20576exports.__esModule = true;
20577exports.on = on;
20578exports.off = off;
20579exports.trigger = trigger;
20580exports.one = one;
20581exports.fixEvent = fixEvent;
20582
20583function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20584
20585function _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; } }
20586
20587var _domJs = _dereq_('./dom.js');
20588
20589var Dom = _interopRequireWildcard(_domJs);
20590
20591var _guidJs = _dereq_('./guid.js');
20592
20593var Guid = _interopRequireWildcard(_guidJs);
20594
20595var _globalWindow = _dereq_('global/window');
20596
20597var _globalWindow2 = _interopRequireDefault(_globalWindow);
20598
20599var _globalDocument = _dereq_('global/document');
20600
20601var _globalDocument2 = _interopRequireDefault(_globalDocument);
20602
20603/**
20604 * Add an event listener to element
20605 * It stores the handler function in a separate cache object
20606 * and adds a generic handler to the element's event,
20607 * along with a unique id (guid) to the element.
20608 *
20609 * @param  {Element|Object}   elem Element or object to bind listeners to
20610 * @param  {String|Array}   type Type of event to bind to.
20611 * @param  {Function} fn   Event listener.
20612 * @method on
20613 */
20614
20615function on(elem, type, fn) {
20616  if (Array.isArray(type)) {
20617    return _handleMultipleEvents(on, elem, type, fn);
20618  }
20619
20620  var data = Dom.getElData(elem);
20621
20622  // We need a place to store all our handler data
20623  if (!data.handlers) data.handlers = {};
20624
20625  if (!data.handlers[type]) data.handlers[type] = [];
20626
20627  if (!fn.guid) fn.guid = Guid.newGUID();
20628
20629  data.handlers[type].push(fn);
20630
20631  if (!data.dispatcher) {
20632    data.disabled = false;
20633
20634    data.dispatcher = function (event, hash) {
20635
20636      if (data.disabled) return;
20637      event = fixEvent(event);
20638
20639      var handlers = data.handlers[event.type];
20640
20641      if (handlers) {
20642        // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
20643        var handlersCopy = handlers.slice(0);
20644
20645        for (var m = 0, n = handlersCopy.length; m < n; m++) {
20646          if (event.isImmediatePropagationStopped()) {
20647            break;
20648          } else {
20649            handlersCopy[m].call(elem, event, hash);
20650          }
20651        }
20652      }
20653    };
20654  }
20655
20656  if (data.handlers[type].length === 1) {
20657    if (elem.addEventListener) {
20658      elem.addEventListener(type, data.dispatcher, false);
20659    } else if (elem.attachEvent) {
20660      elem.attachEvent('on' + type, data.dispatcher);
20661    }
20662  }
20663}
20664
20665/**
20666 * Removes event listeners from an element
20667 *
20668 * @param  {Element|Object}   elem Object to remove listeners from
20669 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
20670 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
20671 * @method off
20672 */
20673
20674function off(elem, type, fn) {
20675  // Don't want to add a cache object through getElData if not needed
20676  if (!Dom.hasElData(elem)) return;
20677
20678  var data = Dom.getElData(elem);
20679
20680  // If no events exist, nothing to unbind
20681  if (!data.handlers) {
20682    return;
20683  }
20684
20685  if (Array.isArray(type)) {
20686    return _handleMultipleEvents(off, elem, type, fn);
20687  }
20688
20689  // Utility function
20690  var removeType = function removeType(t) {
20691    data.handlers[t] = [];
20692    _cleanUpEvents(elem, t);
20693  };
20694
20695  // Are we removing all bound events?
20696  if (!type) {
20697    for (var t in data.handlers) {
20698      removeType(t);
20699    }return;
20700  }
20701
20702  var handlers = data.handlers[type];
20703
20704  // If no handlers exist, nothing to unbind
20705  if (!handlers) return;
20706
20707  // If no listener was provided, remove all listeners for type
20708  if (!fn) {
20709    removeType(type);
20710    return;
20711  }
20712
20713  // We're only removing a single handler
20714  if (fn.guid) {
20715    for (var n = 0; n < handlers.length; n++) {
20716      if (handlers[n].guid === fn.guid) {
20717        handlers.splice(n--, 1);
20718      }
20719    }
20720  }
20721
20722  _cleanUpEvents(elem, type);
20723}
20724
20725/**
20726 * Trigger an event for an element
20727 *
20728 * @param  {Element|Object}      elem  Element to trigger an event on
20729 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
20730 * @param  {Object} [hash] data hash to pass along with the event
20731 * @return {Boolean=} Returned only if default was prevented
20732 * @method trigger
20733 */
20734
20735function trigger(elem, event, hash) {
20736  // Fetches element data and a reference to the parent (for bubbling).
20737  // Don't want to add a data object to cache for every parent,
20738  // so checking hasElData first.
20739  var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
20740  var parent = elem.parentNode || elem.ownerDocument;
20741  // type = event.type || event,
20742  // handler;
20743
20744  // If an event name was passed as a string, creates an event out of it
20745  if (typeof event === 'string') {
20746    event = { type: event, target: elem };
20747  }
20748  // Normalizes the event properties.
20749  event = fixEvent(event);
20750
20751  // If the passed element has a dispatcher, executes the established handlers.
20752  if (elemData.dispatcher) {
20753    elemData.dispatcher.call(elem, event, hash);
20754  }
20755
20756  // Unless explicitly stopped or the event does not bubble (e.g. media events)
20757  // recursively calls this function to bubble the event up the DOM.
20758  if (parent && !event.isPropagationStopped() && event.bubbles === true) {
20759    trigger.call(null, parent, event, hash);
20760
20761    // If at the top of the DOM, triggers the default action unless disabled.
20762  } else if (!parent && !event.defaultPrevented) {
20763      var targetData = Dom.getElData(event.target);
20764
20765      // Checks if the target has a default action for this event.
20766      if (event.target[event.type]) {
20767        // Temporarily disables event dispatching on the target as we have already executed the handler.
20768        targetData.disabled = true;
20769        // Executes the default action.
20770        if (typeof event.target[event.type] === 'function') {
20771          event.target[event.type]();
20772        }
20773        // Re-enables event dispatching.
20774        targetData.disabled = false;
vendor: 4,549 bytes, lines 20775-20916
20775      }
20776    }
20777
20778  // Inform the triggerer if the default was prevented by returning false
20779  return !event.defaultPrevented;
20780}
20781
20782/**
20783 * Trigger a listener only once for an event
20784 *
20785 * @param  {Element|Object}   elem Element or object to
20786 * @param  {String|Array}   type Name/type of event
20787 * @param  {Function} fn Event handler function
20788 * @method one
20789 */
20790
20791function one(elem, type, fn) {
20792  if (Array.isArray(type)) {
20793    return _handleMultipleEvents(one, elem, type, fn);
20794  }
20795  var func = function func() {
20796    off(elem, type, func);
20797    fn.apply(this, arguments);
20798  };
20799  // copy the guid to the new function so it can removed using the original function's ID
20800  func.guid = fn.guid = fn.guid || Guid.newGUID();
20801  on(elem, type, func);
20802}
20803
20804/**
20805 * Fix a native event to have standard property values
20806 *
20807 * @param  {Object} event Event object to fix
20808 * @return {Object}
20809 * @private
20810 * @method fixEvent
20811 */
20812
20813function fixEvent(event) {
20814
20815  function returnTrue() {
20816    return true;
20817  }
20818  function returnFalse() {
20819    return false;
20820  }
20821
20822  // Test if fixing up is needed
20823  // Used to check if !event.stopPropagation instead of isPropagationStopped
20824  // But native events return true for stopPropagation, but don't have
20825  // other expected methods like isPropagationStopped. Seems to be a problem
20826  // with the Javascript Ninja code. So we're just overriding all events now.
20827  if (!event || !event.isPropagationStopped) {
20828    var old = event || _globalWindow2['default'].event;
20829
20830    event = {};
20831    // Clone the old object so that we can modify the values event = {};
20832    // IE8 Doesn't like when you mess with native event properties
20833    // Firefox returns false for event.hasOwnProperty('type') and other props
20834    //  which makes copying more difficult.
20835    // TODO: Probably best to create a whitelist of event props
20836    for (var key in old) {
20837      // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
20838      // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
20839      // and webkitMovementX/Y
20840      if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
20841        // Chrome 32+ warns if you try to copy deprecated returnValue, but
20842        // we still want to if preventDefault isn't supported (IE8).
20843        if (!(key === 'returnValue' && old.preventDefault)) {
20844          event[key] = old[key];
20845        }
20846      }
20847    }
20848
20849    // The event occurred on this element
20850    if (!event.target) {
20851      event.target = event.srcElement || _globalDocument2['default'];
20852    }
20853
20854    // Handle which other element the event is related to
20855    if (!event.relatedTarget) {
20856      event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
20857    }
20858
20859    // Stop the default browser action
20860    event.preventDefault = function () {
20861      if (old.preventDefault) {
20862        old.preventDefault();
20863      }
20864      event.returnValue = false;
20865      old.returnValue = false;
20866      event.defaultPrevented = true;
20867    };
20868
20869    event.defaultPrevented = false;
20870
20871    // Stop the event from bubbling
20872    event.stopPropagation = function () {
20873      if (old.stopPropagation) {
20874        old.stopPropagation();
20875      }
20876      event.cancelBubble = true;
20877      old.cancelBubble = true;
20878      event.isPropagationStopped = returnTrue;
20879    };
20880
20881    event.isPropagationStopped = returnFalse;
20882
20883    // Stop the event from bubbling and executing other handlers
20884    event.stopImmediatePropagation = function () {
20885      if (old.stopImmediatePropagation) {
20886        old.stopImmediatePropagation();
20887      }
20888      event.isImmediatePropagationStopped = returnTrue;
20889      event.stopPropagation();
20890    };
20891
20892    event.isImmediatePropagationStopped = returnFalse;
20893
20894    // Handle mouse position
20895    if (event.clientX != null) {
20896      var doc = _globalDocument2['default'].documentElement,
20897          body = _globalDocument2['default'].body;
20898
20899      event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
20900      event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
20901    }
20902
20903    // Handle key presses
20904    event.which = event.charCode || event.keyCode;
20905
20906    // Fix button for mouse clicks:
20907    // 0 == left; 1 == middle; 2 == right
20908    if (event.button != null) {
20909      event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
20910    }
20911  }
20912
20913  // Returns fixed-up instance
20914  return event;
20915}
20916
20917/**
20918 * Clean up the listener cache and dispatchers
20919*
20920 * @param  {Element|Object} elem Element to clean up
20921 * @param  {String} type Type of event to clean up
20922 * @private
20923 * @method _cleanUpEvents
20924 */
20925function _cleanUpEvents(elem, type) {
20926  var data = Dom.getElData(elem);
20927
20928  // Remove the events of a particular type if there are none left
20929  if (data.handlers[type].length === 0) {
20930    delete data.handlers[type];
20931    // data.handlers[type] = null;
20932    // Setting to null was causing an error with data.handlers
20933
20934    // Remove the meta-handler from the element
20935    if (elem.removeEventListener) {
20936      elem.removeEventListener(type, data.dispatcher, false);
20937    } else if (elem.detachEvent) {
20938      elem.detachEvent('on' + type, data.dispatcher);
20939    }
20940  }
20941
20942  // Remove the events object if there are no types left
20943  if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
20944    delete data.handlers;
20945    delete data.dispatcher;
20946    delete data.disabled;
20947  }
20948
20949  // Finally remove the element data if there is no data left
20950  if (Object.getOwnPropertyNames(data).length === 0) {
20951    Dom.removeElData(elem);
20952  }
20953}
20954
20955/**
20956 * Loops through an array of event types and calls the requested method for each type.
20957 *
20958 * @param  {Function} fn   The event method we want to use.
20959 * @param  {Element|Object} elem Element or object to bind listeners to
20960 * @param  {String}   type Type of event to bind to.
20961 * @param  {Function} callback   Event listener.
20962 * @private
20963 * @function _handleMultipleEvents
20964 */
20965function _handleMultipleEvents(fn, elem, types, callback) {
20966  types.forEach(function (type) {
20967    //Call the event method for each one of the types
20968    fn(elem, type, callback);
20969  });
20970}
20971
20972},{"./dom.js":143,"./guid.js":147,"global/document":1,"global/window":2}],145:[function(_dereq_,module,exports){
20973/**
20974 * @file fn.js
20975 */
20976'use strict';
20977
20978exports.__esModule = true;
20979
20980var _guidJs = _dereq_('./guid.js');
20981
20982/**
20983 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
20984 * It also stores a unique id on the function so it can be easily removed from events
20985 *
20986 * @param  {*}   context The object to bind as scope
20987 * @param  {Function} fn      The function to be bound to a scope
20988 * @param  {Number=}   uid     An optional unique ID for the function to be set
20989 * @return {Function}
20990 * @private
20991 * @method bind
20992 */
20993var bind = function bind(context, fn, uid) {
20994  // Make sure the function has a unique ID
20995  if (!fn.guid) {
20996    fn.guid = _guidJs.newGUID();
20997  }
20998
20999  // Create the new function that changes the context
21000  var ret = function ret() {
21001    return fn.apply(context, arguments);
21002  };
21003
21004  // Allow for the ability to individualize this function
21005  // Needed in the case where multiple objects might share the same prototype
21006  // IF both items add an event listener with the same function, then you try to remove just one
21007  // it will remove both because they both have the same guid.
21008  // when using this, you need to use the bind method when you remove the listener as well.
21009  // currently used in text tracks
21010  ret.guid = uid ? uid + '_' + fn.guid : fn.guid;
21011
21012  return ret;
21013};
21014exports.bind = bind;
21015
21016},{"./guid.js":147}],146:[function(_dereq_,module,exports){
21017/**
21018 * @file format-time.js
21019 *
21020 * Format seconds as a time string, H:MM:SS or M:SS
21021 * Supplying a guide (in seconds) will force a number of leading zeros
21022 * to cover the length of the guide
21023 *
21024 * @param  {Number} seconds Number of seconds to be turned into a string
21025 * @param  {Number} guide   Number (in seconds) to model the string after
21026 * @return {String}         Time formatted as H:MM:SS or M:SS
21027 * @private
21028 * @function formatTime
21029 */
21030'use strict';
21031
21032exports.__esModule = true;
21033function formatTime(seconds) {
21034  var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1];
21035  return (function () {
21036    seconds = seconds < 0 ? 0 : seconds;
21037    var s = Math.floor(seconds % 60);
21038    var m = Math.floor(seconds / 60 % 60);
21039    var h = Math.floor(seconds / 3600);
21040    var gm = Math.floor(guide / 60 % 60);
21041    var gh = Math.floor(guide / 3600);
21042
21043    // handle invalid times
21044    if (isNaN(seconds) || seconds === Infinity) {
21045      // '-' is false for all relational operators (e.g. <, >
21045=) so this setting
21046      // will add the minimum number of fields specified by the guide
21047      h = m = s = '-';
21048    }
21049
21050    // Check if we need to show hours
21051    h = h > 0 || gh > 0 ? h + ':' : '';
21052
21053    // If hours are showing, we may need to add a leading zero.
21054    // Always show at least one digit of minutes.
21055    m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
21056
21057    // Check if leading zero is need for seconds
21058    s = s < 10 ? '0' + s : s;
21059
21060    return h + m + s;
21061  })();
21062}
21063
21064exports['default'] = formatTime;
21065module.exports = exports['default'];
21066
21067},{}],147:[function(_dereq_,module,exports){
21068/**
21069 * @file guid.js
21070 *
21071 * Unique ID for an element or function
21072 * @type {Number}
21073 * @private
21074 */
21075"use strict";
21076
21077exports.__esModule = true;
21078exports.newGUID = newGUID;
21079var _guid = 1;
21080
21081/**
21082 * Get the next unique ID
21083 *
21084 * @return {String} 
21085 * @function newGUID
21086 */
21087
21088function newGUID() {
21089  return _guid++;
21090}
21091
21092},{}],148:[function(_dereq_,module,exports){
21093/**
21094 * @file log.js
21095 */
21096'use strict';
21097
21098exports.__esModule = true;
21099
21100function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21101
21102var _globalWindow = _dereq_('global/window');
21103
21104var _globalWindow2 = _interopRequireDefault(_globalWindow);
21105
21106/**
21107 * Log plain debug messages
21108 */
21109var log = function log() {
21110  _logType(null, arguments);
21111};
21112
21113/**
21114 * Keep a history of log messages
21115 * @type {Array}
21116 */
21117log.history = [];
21118
21119/**
21120 * Log error messages
21121 */
21122log.error = function () {
21123  _logType('error', arguments);
21124};
21125
21126/**
21127 * Log warning messages
21128 */
21129log.warn = function () {
21130  _logType('warn', arguments);
21131};
21132
21133/**
21134 * Log messages to the console and history based on the type of message
21135 *
21136 * @param  {String} type The type of message, or `null` for `log`
21137 * @param  {Object} args The args to be passed to the log
21138 * @private
21139 * @method _logType
21140 */
21141function _logType(type, args) {
21142  // convert args to an array to get array functions
21143  var argsArray = Array.prototype.slice.call(args);
21144  // if there's no console then don't try to output messages
21145  // they will still be stored in log.history
21146  // Was setting these once outside of this function, but containing them
21147  // in the function makes it easier to test cases where console doesn't exist
21148  var noop = function noop() {};
21149
21150  var console = _globalWindow2['default']['console'] || {
21151    'log': noop,
21152    'warn': noop,
21153    'error': noop
21154  };
21155
21156  if (type) {
21157    // add the type to the front of the message
21158    argsArray.unshift(type.toUpperCase() + ':');
21159  } else {
21160    // default to log with no prefix
21161    type = 'log';
21162  }
21163
21164  // add to history
21165  log.history.push(argsArray);
21166
21167  // add console prefix after adding to history
21168  argsArray.unshift('VIDEOJS:');
21169
21170  // call appropriate log function
21171  if (console[type].apply) {
21172    console[type].apply(console, argsArray);
21173  } else {
21174    // ie8 doesn't allow error.apply, but it will just join() the array anyway
21175    console[type](argsArray.join(' '));
21176  }
21177}
21178
21179exports['default'] = log;
21180module.exports = exports['default'];
21181
21182},{"global/window":2}],149:[function(_dereq_,module,exports){
21183/**
21184 * @file merge-options.js
21185 */
21186'use strict';
21187
21188exports.__esModule = true;
21189exports['default'] = mergeOptions;
21190
21191function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21192
21193var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
21194
21195var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
21196
21197function isPlain(obj) {
21198  return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object;
21199}
21200
21201/**
21202 * Merge customizer. video.js simply overwrites non-simple objects
21203 * (like arrays) instead of attempting to overlay them.
21204 * @see https://lodash.com/docs#merge
21205 */
21206var customizer = function customizer(destination, source) {
21207  // If we're not working with a plain object, copy the value as is
21208  // If source is an array, for instance, it will replace destination
21209  if (!isPlain(source)) {
21210    return source;
21211  }
21212
21213  // If the new value is a plain object but the first object value is not
21214  // we need to create a new object for the first object to merge with.
21215  // This makes it consistent with how merge() works by default
21216  // and also protects from later changes the to first object affecting
21217  // the second object's values.
21218  if (!isPlain(destination)) {
21219    return mergeOptions(source);
21220  }
21221};
21222
21223/**
21224 * Merge one or more options objects, recursively merging **only**
21225 * plain object properties.  Previously `deepMerge`.
21226 *
21227 * @param  {...Object} source One or more objects to merge
21228 * @returns {Object}          a new object that is the union of all
21229 * provided objects
21230 * @function mergeOptions
21231 */
21232
21233function mergeOptions() {
21234  // contruct the call dynamically to handle the variable number of
21235  // objects to merge
21236  var args = Array.prototype.slice.call(arguments);
21237
21238  // unshift an empty object into the front of the call as the target
21239  // of the merge
21240  args.unshift({});
21241
21242  // customize conflict resolution to match our historical merge behavior
21243  args.push(customizer);
21244
21245  _lodashCompatObjectMerge2['default'].apply(null, args);
21246
21247  // return the mutated result object
21248  return args[0];
21249}
21250
21251module.exports = exports['default'];
21252
21253},{"lodash-compat/object/merge":40}],150:[function(_dereq_,module,exports){
21254'use strict';
21255
21256exports.__esModule = true;
21257
21258function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21259
21260var _globalDocument = _dereq_('global/document');
21261
21262var _globalDocument2 = _interopRequireDefault(_globalDocument);
21263
21264var createStyleElement = function createStyleElement(className) {
21265  var style = _globalDocument2['default'].createElement('style');
21266  style.className = className;
21267
21268  return style;
21269};
21270
21271exports.createStyleElement = createStyleElement;
21272var setTextContent = function setTextContent(el, content) {
21273  if (el.styleSheet) {
21274    el.styleSheet.cssText = content;
21275  } else {
21276    el.textContent = content;
21277  }
21278};
21279exports.setTextContent = setTextContent;
21280
21281},{"global/document":1}],151:[function(_dereq_,module,exports){
21282'use strict';
21283
21284exports.__esModule = true;
21285exports.createTimeRanges = createTimeRanges;
21286
21287function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21288
21289var _logJs = _dereq_('./log.js');
21290
21291var _logJs2 = _interopRequireDefault(_logJs);
21292
21293/**
21294 * @file time-ranges.js
21295 *
21296 * Should create a fake TimeRange object
21297 * Mimics an HTML5 time range instance, which has functions that
21298 * return the start and end times for a range
21299 * TimeRanges are returned by the buffered() method
21300 *
21301 * @param  {(Number|Array)} Start of a single range or an array of ranges
21302 * @param  {Number} End of a single range
21303 * @private
21304 * @method createTimeRanges
21305 */
21306
21307function createTimeRanges(start, end) {
21308  if (Array.isArray(start)) {
21309    return createTimeRangesObj(start);
21310  } else if (start === undefined || end === undefined) {
21311    return createTimeRangesObj();
21312  }
21313  return createTimeRangesObj([[start, end]]);
21314}
21315
21316exports.createTimeRange = createTimeRanges;
21317
21318function createTimeRangesObj(ranges) {
21319  if (ranges === undefined || ranges.length === 0) {
21320    return {
21321      length: 0,
21322      start: function start() {
21323        throw new Error('This TimeRanges object is empty');
21324      },
21325      end: function end() {
21326        throw new Error('This TimeRanges object is empty');
21327      }
21328    };
21329  }
21330  return {
21331    length: ranges.length,
21332    start: getRange.bind(null, 'start', 0, ranges),
21333    end: getRange.bind(null, 'end', 1, ranges)
21334  };
21335}
21336
21337function getRange(fnName, valueIndex, ranges, rangeIndex) {
21338  if (rangeIndex === undefined) {
21339    _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
21340    rangeIndex = 0;
21341  }
21342  rangeCheck(fnName, rangeIndex, ranges.length - 1);
21343  return ranges[rangeIndex][valueIndex];
21344}
21345
21346function rangeCheck(fnName, index, maxIndex) {
21347  if (index < 0 || index > maxIndex) {
21348    throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
21349  }
21350}
21351
21352},{"./log.js":148}],152:[function(_dereq_,module,exports){
21353/**
21354 * @file to-title-case.js
21355 *
21356 * Uppercase the first letter of a string
21357 *
21358 * @param  {String} string String to be uppercased
21359 * @return {String}
21360 * @private
21361 * @method toTitleCase
21362 */
21363"use strict";
21364
21365exports.__esModule = true;
21366function toTitleCase(string) {
21367  return string.charAt(0).toUpperCase() + string.slice(1);
21368}
21369
21370exports["default"] = toTitleCase;
21371module.exports = exports["default"];
21372
21373},{}],153:[function(_dereq_,module,exports){
21374/**
21375 * @file url.js
21376 */
21377'use strict';
21378
21379exports.__esModule = true;
21380
21381function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21382
21383var _globalDocument = _dereq_('global/document');
21384
21385var _globalDocument2 = _interopRequireDefault(_globalDocument);
21386
21387var _globalWindow = _dereq_('global/window');
21388
21389var _globalWindow2 = _interopRequireDefault(_globalWindow);
21390
21391/**
21392 * Resolve and parse the elements of a URL
21393 *
21394 * @param  {String} url The url to parse
21395 * @return {Object}     An object of url details
21396 * @method parseUrl
21397 */
21398var parseUrl = function parseUrl(url) {
21399  var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
21400
21401  // add the url to an anchor and let the browser parse the URL
21402  var a = _globalDocument2['default'].createElement('a');
21403  a.href = url;
21404
21405  // IE8 (and 9?) Fix
21406  // ie8 doesn't parse the URL correctly until the anchor is actually
21407  // added to the body, and an innerHTML is needed to trigger the parsing
21408  var addToBody = a.host === '' && a.protocol !== 'file:';
21409  var div = undefined;
21410  if (addToBody) {
21411    div = _globalDocument2['default'].createElement('div');
21412    div.innerHTML = '<a href="' + url + '"></a>';
21413    a = div.firstChild;
21414    // prevent the div from affecting layout
21415    div.setAttribute('style', 'display:none; position:absolute;');
21416    _globalDocument2['default'].body.appendChild(div);
21417  }
21418
21419  // Copy the specific URL properties to a new object
21420  // This is also needed for IE8 because the anchor loses its
21421  // properties when it's removed from the dom
21422  var details = {};
21423  for (var i = 0; i < props.length; i++) {
21424    details[props[i]] = a[props[i]];
21425  }
21426
21427  // IE9 adds the port to the host property unlike everyone else. If
21428  // a port identifier is added for standard ports, strip it.
21429  if (details.protocol === 'http:') {
21430    details.host = details.host.replace(/:80$/, '');
21431  }
21432  if (details.protocol === 'https:') {
21433    details.host = details.host.replace(/:443$/, '');
21434  }
21435
21436  if (addToBody) {
21437    _globalDocument2['default'].body.removeChild(div);
21438  }
21439
21440  return details;
21441};
21442
21443exports.parseUrl = parseUrl;
21444/**
21445 * Get absolute version of relative URL. Used to tell flash correct URL.
21446 * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
21447 *
21448 * @param  {String} url URL to make absolute
21449 * @return {String}     Absolute URL
21450 * @private
21451 * @method getAbsoluteURL
21452 */
21453var getAbsoluteURL = function getAbsoluteURL(url) {
21454  // Check if absolute URL
21455  if (!url.match(/^https?:\/\//)) {
21456    // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
21457    var div = _globalDocument2['default'].createElement('div');
21458    div.innerHTML = '<a href="' + url + '">x</a>';
21459    url = div.firstChild.href;
21460  }
21461
21462  return url;
21463};
21464
21465exports.getAbsoluteURL = getAbsoluteURL;
21466/**
21467 * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path
21468 *
21469 * @param {String}    path    The fileName path like '/path/to/file.mp4'
21470 * @returns {String}          The extension in lower case or an empty string if no extension could be found.
21471 * @method getFileExtension
21472 */
21473var getFileExtension = function getFileExtension(path) {
21474  if (typeof path === 'string') {
21475    var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
21476    var pathParts = splitPathRe.exec(path);
21477
21478    if (pathParts) {
21479      return pathParts.pop().toLowerCase();
21480    }
21481  }
21482
21483  return '';
21484};
21485
21486exports.getFileExtension = getFileExtension;
21487/**
21488 * Returns whether the url passed is a cross domain request or not.
21489 *
21490 * @param {String} url The url to check
21491 * @return {Boolean}   Whether it is a cross domain request or not
21492 * @method isCrossOrigin
21493 */
21494var isCrossOrigin = function isCrossOrigin(url) {
21495  var winLoc = _globalWindow2['default'].location;
21496  var urlInfo = parseUrl(url);
21497
21498  // IE8 protocol relative urls will return ':' for protocol
21499  var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
21500
21501  // Check if url is for another domain/origin
21502  // IE8 doesn't know location.origin, so we won't rely on it here
21503  var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
21504
21505  return crossOrigin;
21506};
21507exports.isCrossOrigin = isCrossOrigin;
21508
21509},{"global/document":1,"global/window":2}],154:[function(_dereq_,module,exports){
21510/**
21511 * @file video.js
21512 */
21513'use strict';
21514
21515exports.__esModule = true;
21516
21517function _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; } }
21518
21519function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21520
21521var _globalWindow = _dereq_('global/window');
21522
21523var _globalWindow2 = _interopRequireDefault(_globalWindow);
21524
21525var _globalDocument = _dereq_('global/document');
21526
21527var _globalDocument2 = _interopRequireDefault(_globalDocument);
21528
21529var _setup = _dereq_('./setup');
21530
21531var setup = _interopRequireWildcard(_setup);
21532
21533var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
21534
21535var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
21536
21537var _component = _dereq_('./component');
21538
21539var _component2 = _interopRequireDefault(_component);
21540
21541var _eventTarget = _dereq_('./event-target');
21542
21543var _eventTarget2 = _interopRequireDefault(_eventTarget);
21544
21545var _utilsEventsJs = _dereq_('./utils/events.js');
21546
21547var Events = _interopRequireWildcard(_utilsEventsJs);
21548
21549var _player = _dereq_('./player');
21550
21551var _player2 = _interopRequireDefault(_player);
21552
21553var _pluginsJs = _dereq_('./plugins.js');
21554
21555var _pluginsJs2 = _interopRequireDefault(_pluginsJs);
21556
21557var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js');
21558
21559var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs);
21560
21561var _utilsFnJs = _dereq_('./utils/fn.js');
21562
21563var Fn = _interopRequireWildcard(_utilsFnJs);
21564
21565var _tracksTextTrackJs = _dereq_('./tracks/text-track.js');
21566
21567var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs);
21568
21569var _tracksAudioTrackJs = _dereq_('./tracks/audio-track.js');
21570
21571var _tracksAudioTrackJs2 = _interopRequireDefault(_tracksAudioTrackJs);
21572
21573var _tracksVideoTrackJs = _dereq_('./tracks/video-track.js');
21574
21575var _tracksVideoTrackJs2 = _interopRequireDefault(_tracksVideoTrackJs);
21576
21577var _objectAssign = _dereq_('object.assign');
21578
21579var _objectAssign2 = _interopRequireDefault(_objectAssign);
21580
21581var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
21582
21583var _utilsFormatTimeJs = _dereq_('./utils/format-time.js');
21584
21585var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
21586
21587var _utilsLogJs = _dereq_('./utils/log.js');
21588
21589var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
21590
21591var _utilsDomJs = _dereq_('./utils/dom.js');
21592
21593var Dom = _interopRequireWildcard(_utilsDomJs);
21594
21595var _utilsBrowserJs = _dereq_('./utils/browser.js');
21596
21597var browser = _interopRequireWildcard(_utilsBrowserJs);
21598
21599var _utilsUrlJs = _dereq_('./utils/url.js');
21600
21601var Url = _interopRequireWildcard(_utilsUrlJs);
21602
21603var _extendJs = _dereq_('./extend.js');
21604
21605var _extendJs2 = _interopRequireDefault(_extendJs);
21606
21607var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
21608
21609var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
21610
21611var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js');
21612
21613var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs);
21614
21615var _xhr = _dereq_('xhr');
21616
21617var _xhr2 = _interopRequireDefault(_xhr);
21618
21619// Include the built-in techs
21620
21621var _techTechJs = _dereq_('./tech/tech.js');
21622
21623var _techTechJs2 = _interopRequireDefault(_techTechJs);
21624
21625var _techHtml5Js = _dereq_('./tech/html5.js');
21626
21627var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
21628
21629var _techFlashJs = _dereq_('./tech/flash.js');
21630
21631var _techFlashJs2 = _interopRequireDefault(_techFlashJs);
21632
21633// HTML5 Element Shim for IE8
21634if (typeof HTMLVideoElement === 'undefined') {
21635  _globalDocument2['default'].createElement('video');
21636  _globalDocument2['default'].createElement('audio');
21637  _globalDocument2['default'].createElement('track');
21638}
21639
21640/**
21641 * Doubles as the main function for users to create a player instance and also
21642 * the main library object.
21643 * The `videojs` function can be used to initialize or retrieve a player.
21644 * ```js
21645 *     var myPlayer = videojs('my_video_id');
21646 * ```
21647 *
21648 * @param  {String|Element} id      Video element or video element ID
21649 * @param  {Object=} options        Optional options object for config/settings
21650 * @param  {Function=} ready        Optional ready callback
21651 * @return {Player}                 A player instance
21652 * @mixes videojs
21653 * @method videojs
21654 */
21655function videojs(id, options, ready) {
21656  var tag = undefined; // Element of ID
21657
21658  // Allow for element or ID to be passed in
21659  // String ID
21660  if (typeof id === 'string') {
21661
21662    // Adjust for jQuery ID syntax
21663    if (id.indexOf('#') === 0) {
21664      id = id.slice(1);
21665    }
21666
21667    // If a player instance has already been created for this ID return it.
21668    if (videojs.getPlayers()[id]) {
21669
21670      // If options or ready funtion are passed, warn
21671      if (options) {
21672        _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
21673      }
21674
21675      if (ready) {
21676        videojs.getPlayers()[id].ready(ready);
21677      }
21678
21679      return videojs.getPlayers()[id];
21680
21681      // Otherwise get element for ID
21682    } else {
21683        tag = Dom.getEl(id);
21684      }
21685
21686    // ID is a media element
21687  } else {
21688      tag = id;
21689    }
21690
21691  // Check for a useable element
21692  if (!tag || !tag.nodeName) {
21693    // re: nodeName, could be a box div also
21694    throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns
21695  }
21696
21697  // Element may have a player attr referring to an already created player instance.
21698  // If not, set up a new player and return the instance.
21699  return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready);
21700}
21701
21702// Add default styles
21703if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
21704  var style = Dom.$('.vjs-styles-defaults');
21705
21706  if (!style) {
21707    style = stylesheet.createStyleElement('vjs-styles-defaults');
21708    var head = Dom.$('head');
21709    head.insertBefore(style, head.firstChild);
21710    stylesheet.setTextContent(style, '\n      .video-js {\n        width: 300px;\n        height: 150px;\n      }\n\n      .vjs-fluid {\n        padding-top: 56.25%\n      }\n    ');
21711  }
21712}
21713
21714// Run Auto-load players
21715// You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version)
21716setup.autoSetupTimeout(1, videojs);
21717
21718/*
21719 * Current software version (semver)
21720 *
21721 * @type {String}
21722 */
21723videojs.VERSION = '5.10.5';
21724
21725/**
21726 * The global options object. These are the settings that take effect
21727 * if no overrides are specified when the player is created.
21728 *
21729 * ```js
21730 *     videojs.options.autoplay = true
21731 *     // -> all players will autoplay by default
21732 * ```
21733 *
21734 * @type {Object}
21735 */
21736videojs.options = _player2['default'].prototype.options_;
21737
21738/**
21739 * Get an object with the currently created players, keyed by player ID
21740 *
21741 * @return {Object} The created players
21742 * @mixes videojs
21743 * @method getPlayers
21744 */
21745videojs.getPlayers = function () {
21746  return _player2['default'].players;
21747};
21748
21749/**
21750 * For backward compatibility, expose players object.
21751 *
21752 * @deprecated
21753 * @memberOf videojs
21754 * @property {Object|Proxy} players
21755 */
21756videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, {
21757  get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead',
21758  set: 'Modification of videojs.players is deprecated'
21759});
21760
21761/**
21762 * Get a component class object by name
21763 * ```js
21764 *     var VjsButton = videojs.getComponent('Button');
21765 *     // Create a new instance of the component
21766 *     var myButton = new VjsButton(myPlayer);
21767 * ```
21768 *
21769 * @return {Component} Component identified by name
21770 * @mixes videojs
21771 * @method getComponent
21772 */
21773videojs.getComponent = _component2['default'].getComponent;
21774
21775/**
21776 * Register a component so it can referred to by name
21777 * Used when adding to other
21778 * components, either through addChild
21779 * `component.addChild('myComponent')`
21780 * or through default children options
21781 * `{ children: ['myComponent'] }`.
21782 * ```js
21783 *     // Get a component to subclass
21784 *     var VjsButton = videojs.getComponent('Button');
21785 *     // Subclass the component (see 'extend' doc for more info)
21786 *     var MySpecialButton = videojs.extend(VjsButton, {});
21787 *     // Register the new component
21788 *     VjsButton.registerComponent('MySepcialButton', MySepcialButton);
21789 *     // (optionally) add the new component as a default player child
21790 *     myPlayer.addChild('MySepcialButton');
21791 * ```
21792 * NOTE: You could also just initialize the component before adding.
21793 * `component.addChild(new MyComponent());`
21794 *
21795 * @param {String} The class name of the component
21796 * @param {Component} The component class
21797 * @return {Component} The newly registered component
21798 * @mixes videojs
21799 * @method registerComponent
21800 */
21801videojs.registerComponent = function (name, comp) {
21802  if (_techTechJs2['default'].isTech(comp)) {
21803    _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
21804  }
21805
21806  _component2['default'].registerComponent.call(_component2['default'], name, comp);
21807};
21808
21809/**
21810 * Get a Tech class object by name
21811 * ```js
21812 *     var Html5 = videojs.getTech('Html5');
21813 *     // Create a new instance of the component
21814 *     var html5 = new Html5(options);
21815 * ```
21816 *
21817 * @return {Tech} Tech identified by name
21818 * @mixes videojs
21819 * @method getComponent
21820 */
21821videojs.getTech = _techTechJs2['default'].getTech;
21822
21823/**
21824 * Register a Tech so it can referred to by name.
21825 * This is used in the tech order for the player.
21826 *
21827 * ```js
21828 *     // get the Html5 Tech
21829 *     var Html5 = videojs.getTech('Html5');
21830 *     var MyTech = videojs.extend(Html5, {});
21831 *     // Register the new Tech
21832 *     VjsButton.registerTech('Tech', MyTech);
21833 *     var player = videojs('myplayer', {
21834 *       techOrder: ['myTech', 'html5']
21835 *     });
21836 * ```
21837 *
21838 * @param {String} The class name of the tech
21839 * @param {Tech} The tech class
21840 * @return {Tech} The newly registered Tech
21841 * @mixes videojs
21842 * @method registerTech
21843 */
21844videojs.registerTech = _techTechJs2['default'].registerTech;
21845
21846/**
21847 * A suite of browser and device tests
21848 *
21849 * @type {Object}
21850 * @private
21851 */
21852videojs.browser = browser;
21853
21854/**
21855 * Whether or not the browser supports touch events. Included for backward
21856 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
21857 * instead going forward.
21858 *
21859 * @deprecated
21860 * @type {Boolean}
21861 */
21862videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
21863
21864/**
21865 * Subclass an existing class
21866 * Mimics ES6 subclassing with the `extend` keyword
21867 * ```js
21868 *     // Create a basic javascript 'class'
21869 *     function MyClass(name){
21870 *       // Set a property at initialization
21871 *       this.myName = name;
21872 *     }
21873 *     // Create an instance method
21874 *     MyClass.prototype.sayMyName = function(){
21875 *       alert(this.myName);
21876 *     };
21877 *     // Subclass the exisitng class and change the name
21878 *     // when initializing
21879 *     var MySubClass = videojs.extend(MyClass, {
21880 *       constructor: function(name) {
21881 *         // Call the super class constructor for the subclass
21882 *         MyClass.call(this, name)
21883 *       }
21884 *     });
21885 *     // Create an instance of the new sub class
21886 *     var myInstance = new MySubClass('John');
21887 *     myInstance.sayMyName(); // -> should alert "John"
21888 * ```
21889 *
21890 * @param {Function} The Class to subclass
21891 * @param {Object} An object including instace methods for the new class
21892 *                   Optionally including a `constructor` function
21893 * @return {Function} The newly created subclass
21894 * @mixes videojs
21895 * @method extend
21896 */
21897videojs.extend = _extendJs2['default'];
21898
21899/**
21900 * Merge two options objects recursively
21901 * Performs a deep merge like lodash.merge but **only merges plain objects**
21902 * (not arrays, elements, anything else)
21903 * Other values will be copied directly from the second object.
21904 * ```js
21905 *     var defaultOptions = {
21906 *       foo: true,
21907 *       bar: {
21908 *         a: true,
21909 *         b: [1,2,3]
21910 *       }
21911 *     };
21912 *     var newOptions = {
21913 *       foo: false,
21914 *       bar: {
21915 *         b: [4,5,6]
21916 *       }
21917 *     };
21918 *     var result = videojs.mergeOptions(defaultOptions, newOptions);
21919 *     // result.foo = false;
21920 *     // result.bar.a = true;
21921 *     // result.bar.b = [4,5,6];
21922 * ```
21923 *
21924 * @param {Object} defaults  The options object whose values will be overriden
21925 * @param {Object} overrides The options object with values to override the first
21926 * @param {Object} etc       Any number of additional options objects
21927 *
21928 * @return {Object} a new object with the merged values
21929 * @mixes videojs
21930 * @method mergeOptions
21931 */
21932videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default'];
21933
21934/**
21935 * Change the context (this) of a function
21936 *
21937 *     videojs.bind(newContext, function(){
21938 *       this === newContext
21939 *     });
21940 *
21941 * NOTE: as of v5.0 we require an ES5 shim, so you should use the native
21942 * `function(){}.bind(newContext);` instead of this.
21943 *
21944 * @param  {*}        context The object to bind as scope
21945 * @param  {Function} fn      The function to be bound to a scope
21946 * @param  {Number=}  uid     An optional unique ID for the function to be set
21947 * @return {Function}
21948 */
21949videojs.bind = Fn.bind;
21950
21951/**
21952 * Create a Video.js player plugin
21953 * Plugins are only initialized when options for the plugin are included
21954 * in the player options, or the plugin function on the player instance is
21955 * called.
21956 * **See the plugin guide in the docs for a more detailed example**
21957 * ```js
21958 *     // Make a plugin that alerts when the player plays
21959 *     videojs.plugin('myPlugin', function(myPluginOptions) {
21960 *       myPluginOptions = myPluginOptions || {};
21961 *
21962 *       var player = this;
21963 *       var alertText = myPluginOptions.text || 'Player is playing!'
21964 *
21965 *       player.on('play', function(){
21966 *         alert(alertText);
21967 *       });
21968 *     });
21969 *     // USAGE EXAMPLES
21970 *     // EXAMPLE 1: New player with plugin options, call plugin immediately
21971 *     var player1 = videojs('idOne', {
21972 *       myPlugin: {
21973 *         text: 'Custom text!'
21974 *       }
21975 *     });
21976 *     // Click play
21977 *     // --> Should alert 'Custom text!'
21978 *     // EXAMPLE 3: New player, initialize plugin later
21979 *     var player3 = videojs('idThree');
21980 *     // Click play
21981 *     // --> NO ALERT
21982 *     // Click pause
21983 *     // Initialize plugin using the plugin function on the player instance
21984 *     player3.myPlugin({
21985 *       text: 'Plugin added later!'
21986 *     });
21987 *     // Click play
21988 *     // --> Should alert 'Plugin added later!'
21989 * ```
21990 *
21991 * @param {String} name The plugin name
21992 * @param {Function} fn The plugin function that will be called with options
21993 * @mixes videojs
21994 * @method plugin
21995 */
21996videojs.plugin = _pluginsJs2['default'];
21997
21998/**
21999 * Adding languages so that they're available to all players.
22000 * ```js
22001 *     videojs.addLanguage('es', { 'Hello': 'Hola' });
22002 * ```
22003 *
22004 * @param  {String} code The language code or dictionary property
22005 * @param  {Object} data The data values to be translated
22006 * @return {Object} The resulting language dictionary object
22007 * @mixes videojs
22008 * @method addLanguage
22009 */
22010videojs.addLanguage = function (code, data) {
22011  var _merge;
22012
22013  code = ('' + code).toLowerCase();
22014  return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code];
22015};
22016
22017/**
22018 * Log debug messages.
22019 *
22020 * @param {...Object} messages One or more messages to log
22021 */
22022videojs.log = _utilsLogJs2['default'];
22023
22024/**
22025 * Creates an emulated TimeRange object.
22026 *
22027 * @param  {Number|Array} start Start time in seconds or an array of ranges
22028 * @param  {Number} end   End time in seconds
22029 * @return {Object}       Fake TimeRange object
22030 * @method createTimeRange
22031 */
22032videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges;
22033
22034/**
22035 * Format seconds as a time string, H:MM:SS or M:SS
22036 * Supplying a guide (in seconds) will force a number of leading zeros
22037 * to cover the length of the guide
22038 *
22039 * @param  {Number} seconds Number of seconds to be turned into a string
22040 * @param  {Number} guide   Number (in seconds) to model the string after
22041 * @return {String}         Time formatted as H:MM:SS or M:SS
22042 * @method formatTime
22043 */
22044videojs.formatTime = _utilsFormatTimeJs2['default'];
22045
22046/**
22047 * Resolve and parse the elements of a URL
22048 *
22049 * @param  {String} url The url to parse
22050 * @return {Object}     An object of url details
22051 * @method parseUrl
22052 */
22053videojs.parseUrl = Url.parseUrl;
22054
22055/**
22056 * Returns whether the url passed is a cross domain request or not.
22057 *
22058 * @param {String} url The url to check
22059 * @return {Boolean}   Whether it is a cross domain request or not
22060 * @method isCrossOrigin
22061 */
22062videojs.isCrossOrigin = Url.isCrossOrigin;
22063
22064/**
22065 * Event target class.
22066 *
22067 * @type {Function}
22068 */
22069videojs.EventTarget = _eventTarget2['default'];
22070
22071/**
22072 * Add an event listener to element
22073 * It stores the handler function in a separate cache object
22074 * and adds a generic handler to the element's event,
22075 * along with a unique id (guid) to the element.
22076 *
22077 * @param  {Element|Object}   elem Element or object to bind listeners to
22078 * @param  {String|Array}   type Type of event to bind to.
22079 * @param  {Function} fn   Event listener.
22080 * @method on
22081 */
22082videojs.on = Events.on;
22083
22084/**
22085 * Trigger a listener only once for an event
22086 *
22087 * @param  {Element|Object}   elem Element or object to
22088 * @param  {String|Array}   type Name/type of event
22089 * @param  {Function} fn Event handler function
22090 * @method one
22091 */
22092videojs.one = Events.one;
22093
22094/**
22095 * Removes event listeners from an element
22096 *
22097 * @param  {Element|Object}   elem Object to remove listeners from
22098 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
22099 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
22100 * @method off
22101 */
22102videojs.off = Events.off;
22103
22104/**
22105 * Trigger an event for an element
22106 *
22107 * @param  {Element|Object}      elem  Element to trigger an event on
22108 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
22109 * @param  {Object} [hash] data hash to pass along with the event
22110 * @return {Boolean=} Returned only if default was prevented
22111 * @method trigger
22112 */
22113videojs.trigger = Events.trigger;
22114
22115/**
22116 * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
22117 *
22118 *     videojs.xhr({
22119 *       body: someJSONString,
22120 *       uri: "/foo",
22121 *       headers: {
22122 *         "Content-Type": "application/json"
22123 *       }
22124 *     }, function (err, resp, body) {
22125 *       // check resp.statusCode
22126 *     });
22127 *
22128 * Check out the [full
22129 * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md)
22130 * for more options.
22131 *
22132 * @param {Object} options settings for the request.
22133 * @return {XMLHttpRequest|XDomainRequest} the request object.
22134 * @see https://github.com/Raynos/xhr
22135 */
22136videojs.xhr = _xhr2['default'];
22137
22138/**
22139 * TextTrack class
22140 *
22141 * @type {Function}
22142 */
22143videojs.TextTrack = _tracksTextTrackJs2['default'];
22144
22145/**
22146 * export the AudioTrack class so that source handlers can create
22147 * AudioTracks and then add them to the players AudioTrackList
22148 *
22149 * @type {Function}
22150 */
22151videojs.AudioTrack = _tracksAudioTrackJs2['default'];
22152
22153/**
22154 * export the VideoTrack class so that source handlers can create
22155 * VideoTracks and then add them to the players VideoTrackList
22156 *
22157 * @type {Function}
22158 */
22159videojs.VideoTrack = _tracksVideoTrackJs2['default'];
22160
22161/**
22162 * Determines, via duck typing, whether or not a value is a DOM element.
22163 *
22164 * @method isEl
22165 * @param  {Mixed} value
22166 * @return {Boolean}
22167 */
22168videojs.isEl = Dom.isEl;
22169
22170/**
22171 * Determines, via duck typing, whether or not a value is a text node.
22172 *
22173 * @method isTextNode
22174 * @param  {Mixed} value
22175 * @return {Boolean}
22176 */
22177videojs.isTextNode = Dom.isTextNode;
22178
22179/**
22180 * Creates an element and applies properties.
22181 *
22182 * @method createEl
22183 * @param  {String} [tagName='div'] Name of tag to be created.
22184 * @param  {Object} [properties={}] Element properties to be applied.
22185 * @param  {Object} [attributes={}] Element attributes to be applied.
22186 * @return {Element}
22187 */
22188videojs.createEl = Dom.createEl;
22189
22190/**
22191 * Check if an element has a CSS class
22192 *
22193 * @method hasClass
22194 * @param {Element} element Element to check
22195 * @param {String} classToCheck Classname to check
22196 */
22197videojs.hasClass = Dom.hasElClass;
22198
22199/**
22200 * Add a CSS class name to an element
22201 *
22202 * @method addClass
22203 * @param {Element} element    Element to add class name to
22204 * @param {String} classToAdd Classname to add
22205 */
22206videojs.addClass = Dom.addElClass;
22207
22208/**
22209 * Remove a CSS class name from an element
22210 *
22211 * @method removeClass
22212 * @param {Element} element    Element to remove from class name
22213 * @param {String} classToRemove Classname to remove
22214 */
22215videojs.removeClass = Dom.removeElClass;
22216
22217/**
22218 * Adds or removes a CSS class name on an element depending on an optional
22219 * condition or the presence/absence of the class name.
22220 *
22221 * @method toggleElClass
22222 * @param  {Element} element
22223 * @param  {String} classToToggle
22224 * @param  {Boolean|Function} [predicate]
22225 *         Can be a function that returns a Boolean. If `true`, the class
22226 *         will be added; if `false`, the class will be removed. If not
22227 *         given, the class will be added if not present and vice versa.
22228 */
22229videojs.toggleClass = Dom.toggleElClass;
22230
22231/**
22232 * Apply attributes to an HTML element.
22233 *
22234 * @method setAttributes
22235 * @param  {Element} el         Target element.
22236 * @param  {Object=} attributes Element attributes to be applied.
22237 */
22238videojs.setAttributes = Dom.setElAttributes;
22239
22240/**
22241 * Get an element's attribute values, as defined on the HTML tag
22242 * Attributes are not the same as properties. They're defined on the tag
22243 * or with setAttribute (which shouldn't be used with HTML)
22244 * This will return true or false for boolean attributes.
22245 *
22246 * @method getAttributes
22247 * @param  {Element} tag Element from which to get tag attributes
22248 * @return {Object}
22249 */
22250videojs.getAttributes = Dom.getElAttributes;
22251
22252/**
22253 * Empties the contents of an element.
22254 *
22255 * @method emptyEl
22256 * @param  {Element} el
22257 * @return {Element}
22258 */
22259videojs.emptyEl = Dom.emptyEl;
22260
22261/**
22262 * Normalizes and appends content to an element.
22263 *
22264 * The content for an element can be passed in multiple types and
22265 * combinations, whose behavior is as follows:
22266 *
22267 * - String
22268 *   Normalized into a text node.
22269 *
22270 * - Element, TextNode
22271 *   Passed through.
22272 *
22273 * - Array
22274 *   A one-dimensional array of strings, elements, nodes, or functions (which
22275 *   return single strings, elements, or nodes).
22276 *
22277 * - Function
22278 *   If the sole argument, is expected to produce a string, element,
22279 *   node, or array.
22280 *
22281 * @method appendContent
22282 * @param  {Element} el
22283 * @param  {String|Element|TextNode|Array|Function} content
22284 * @return {Element}
22285 */
22286videojs.appendContent = Dom.appendContent;
22287
22288/**
22289 * Normalizes and inserts content into an element; this is identical to
22290 * `appendContent()`, except it empties the element first.
22291 *
22292 * The content for an element can be passed in multiple types and
22293 * combinations, whose behavior is as follows:
22294 *
22295 * - String
22296 *   Normalized into a text node.
22297 *
22298 * - Element, TextNode
22299 *   Passed through.
22300 *
22301 * - Array
22302 *   A one-dimensional array of strings, elements, nodes, or functions (which
22303 *   return single strings, elements, or nodes).
22304 *
22305 * - Function
22306 *   If the sole argument, is expected to produce a string, element,
22307 *   node, or array.
22308 *
22309 * @method insertContent
22310 * @param  {Element} el
22311 * @param  {String|Element|TextNode|Array|Function} content
22312 * @return {Element}
22313 */
22314videojs.insertContent = Dom.insertContent;
22315
22316/*
22317 * Custom Universal Module Definition (UMD)
22318 *
22319 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
22320 * still support requirejs and browserify. This also needs to be closure
22321 * compiler compatible, so string keys are used.
22322 */
22323if (typeof define === 'function' && define['amd']) {
22324  define('videojs', [], function () {
22325    return videojs;
22326  });
22327
22328  // checking that module is an object too because of umdjs/umd#35
22329} else if (typeof exports === 'object' && typeof module === 'object') {
22330    module['exports'] = videojs;
22331  }
22332
22333exports['default'] = videojs;
22334module.exports = exports['default'];
22335
22336},{"../../src/js/utils/merge-options.js":149,"./component":67,"./event-target":104,"./extend.js":105,"./player":113,"./plugins.js":114,"./setup":118,"./tech/flash.js":121,"./tech/html5.js":122,"./tech/tech.js":124,"./tracks/audio-track.js":126,"./tracks/text-track.js":134,"./tracks/video-track.js":139,"./utils/browser.js":140,"./utils/create-deprecation-proxy.js":142,"./utils/dom.js":143,"./utils/events.js":144,"./utils/fn.js":145,"./utils/format-time.js":146,"./utils/log.js":148,"./utils/stylesheet.js":150,"./utils/time-ranges.js":151,"./utils/url.js":153,"global/document":1,"global/window":2,"lodash-compat/object/merge":40,"object.assign":45,"xhr":56}]},{},[154])(154)
22337});
22338
22339
22340//# sourceMappingURL=video.js.map
22341/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */
22342
22343(function(root) {
22344  var vttjs = root.vttjs = {};
22345  var cueShim = vttjs.VTTCue;
22346  var regionShim = vttjs.VTTRegion;
22347  var oldVTTCue = root.VTTCue;
22348  var oldVTTRegion = root.VTTRegion;
22349
22350  vttjs.shim = function() {
22351    vttjs.VTTCue = cueShim;
22352    vttjs.VTTRegion = regionShim;
22353  };
22354
22355  vttjs.restore = function() {
22356    vttjs.VTTCue = oldVTTCue;
22357    vttjs.VTTRegion = oldVTTRegion;
22358  };
22359}(this));
22360
22361/**
22362 * Copyright 2013 vtt.js Contributors
22363 *
22364 * Licensed under the Apache License, Version 2.0 (the "License");
22365 * you may not use this file except in compliance with the License.
22366 * You may obtain a copy of the License at
22367 *
22368 *   http://www.apache.org/licenses/LICENSE-2.0
22369 *
22370 * Unless required by applicable law or agreed to in writing, software
22371 * distributed under the License is distributed on an "AS IS" BASIS,
22372 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22373 * See the License for the specific language governing permissions and
22374 * limitations under the License.
22375 */
22376
22377(function(root, vttjs) {
22378
22379  var autoKeyword = "auto";
22380  var directionSetting = {
22381    "": true,
22382    "lr": true,
22383    "rl": true
22384  };
22385  var alignSetting = {
22386    "start": true,
22387    "middle": true,
22388    "end": true,
22389    "left": true,
22390    "right": true
22391  };
22392
22393  function findDirectionSetting(value) {
22394    if (typeof value !== "string") {
22395      return false;
22396    }
22397    var dir = directionSetting[value.toLowerCase()];
22398    return dir ? value.toLowerCase() : false;
22399  }
22400
22401  function findAlignSetting(value) {
22402    if (typeof value !== "string") {
22403      return false;
22404    }
22405    var align = alignSetting[value.toLowerCase()];
22406    return align ? value.toLowerCase() : false;
22407  }
22408
22409  function extend(obj) {
22410    var i = 1;
22411    for (; i < arguments.length; i++) {
22412      var cobj = arguments[i];
22413      for (var p in cobj) {
22414        obj[p] = cobj[p];
22415      }
22416    }
22417
22418    return obj;
22419  }
22420
22421  function VTTCue(startTime, endTime, text) {
22422    var cue = this;
22423    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
22424    var baseObj = {};
22425
22426    if (isIE8) {
22427      cue = document.createElement('custom');
22428    } else {
22429      baseObj.enumerable = true;
22430    }
22431
22432    /**
22433     * Shim implementation specific properties. These properties are not in
22434     * the spec.
22435     */
22436
22437    // Lets us know when the VTTCue's data has changed in such a way that we need
22438    // to recompute its display state. This lets us compute its display state
22439    // lazily.
22440    cue.hasBeenReset = false;
22441
22442    /**
22443     * VTTCue and TextTrackCue properties
22444     * http://dev.w3.org/html5/webvtt/#vttcue-interface
22445     */
22446
22447    var _id = "";
22448    var _pauseOnExit = false;
22449    var _startTime = startTime;
22450    var _endTime = endTime;
22451    var _text = text;
22452    var _region = null;
22453    var _vertical = "";
22454    var _snapToLines = true;
22455    var _line = "auto";
22456    var _lineAlign = "start";
22457    var _position = 50;
22458    var _positionAlign = "middle";
22459    var _size = 50;
22460    var _align = "middle";
22461
22462    Object.defineProperty(cue,
22463      "id", extend({}, baseObj, {
22464        get: function() {
22465          return _id;
22466        },
22467        set: function(value) {
22468          _id = "" + value;
22469        }
22470      }));
22471
22472    Object.defineProperty(cue,
22473      "pauseOnExit", extend({}, baseObj, {
22474        get: function() {
22475          return _pauseOnExit;
22476        },
22477        set: function(value) {
22478          _pauseOnExit = !!value;
22479        }
22480      }));
22481
22482    Object.defineProperty(cue,
22483      "startTime", extend({}, baseObj, {
22484        get: function() {
22485          return _startTime;
22486        },
22487        set: function(value) {
22488          if (typeof value !== "number") {
22489            throw new TypeError("Start time must be set to a number.");
22490          }
22491          _startTime = value;
22492          this.hasBeenReset = true;
22493        }
22494      }));
22495
22496    Object.defineProperty(cue,
22497      "endTime", extend({}, baseObj, {
22498        get: function() {
22499          return _endTime;
22500        },
22501        set: function(value) {
22502          if (typeof value !== "number") {
22503            throw new TypeError("End time must be set to a number.");
22504          }
22505          _endTime = value;
22506          this.hasBeenReset = true;
22507        }
22508      }));
22509
22510    Object.defineProperty(cue,
22511      "text", extend({}, baseObj, {
22512        get: function() {
22513          return _text;
22514        },
22515        set: function(value) {
22516          _text = "" + value;
22517          this.hasBeenReset = true;
22518        }
22519      }));
22520
22521    Object.defineProperty(cue,
22522      "region", extend({}, baseObj, {
22523        get: function() {
22524          return _region;
22525        },
22526        set: function(value) {
22527          _region = value;
22528          this.hasBeenReset = true;
22529        }
22530      }));
22531
22532    Object.defineProperty(cue,
22533      "vertical", extend({}, baseObj, {
22534        get: function() {
22535          return _vertical;
22536        },
22537        set: function(value) {
22538          var setting = findDirectionSetting(value);
22539          // Have to check for false because the setting an be an empty string.
22540          if (setting === false) {
22541            throw new SyntaxError("An invalid or illegal string was specified.");
22542          }
22543          _vertical = setting;
22544          this.hasBeenReset = true;
22545        }
22546      }));
22547
22548    Object.defineProperty(cue,
22549      "snapToLines", extend({}, baseObj, {
22550        get: function() {
22551          return _snapToLines;
22552        },
22553        set: function(value) {
22554          _snapToLines = !!value;
22555          this.hasBeenReset = true;
22556        }
22557      }));
22558
22559    Object.defineProperty(cue,
22560      "line", extend({}, baseObj, {
22561        get: function() {
22562          return _line;
22563        },
22564        set: function(value) {
22565          if (typeof value !== "number" && value !== autoKeyword) {
22566            throw new SyntaxError("An invalid number or illegal string was specified.");
22567          }
22568          _line = value;
22569          this.hasBeenReset = true;
22570        }
22571      }));
22572
22573    Object.defineProperty(cue,
22574      "lineAlign", extend({}, baseObj, {
22575        get: function() {
22576          return _lineAlign;
22577        },
22578        set: function(value) {
22579          var setting = findAlignSetting(value);
22580          if (!setting) {
22581            throw new SyntaxError("An invalid or illegal string was specified.");
22582          }
22583          _lineAlign = setting;
22584          this.hasBeenReset = true;
22585        }
22586      }));
22587
22588    Object.defineProperty(cue,
22589      "position", extend({}, baseObj, {
22590        get: function() {
22591          return _position;
22592        },
22593        set: function(value) {
22594          if (value < 0 || value > 100) {
22595            throw new Error("Position must be between 0 and 100.");
22596          }
22597          _position = value;
22598          this.hasBeenReset = true;
22599        }
22600      }));
22601
22602    Object.defineProperty(cue,
22603      "positionAlign", extend({}, baseObj, {
22604        get: function() {
22605          return _positionAlign;
22606        },
22607        set: function(value) {
22608          var setting = findAlignSetting(value);
22609          if (!setting) {
22610            throw new SyntaxError("An invalid or illegal string was specified.");
22611          }
22612          _positionAlign = setting;
22613          this.hasBeenReset = true;
22614        }
22615      }));
22616
22617    Object.defineProperty(cue,
22618      "size", extend({}, baseObj, {
22619        get: function() {
22620          return _size;
22621        },
22622        set: function(value) {
22623          if (value < 0 || value > 100) {
22624            throw new Error("Size must be between 0 and 100.");
22625          }
22626          _size = value;
22627          this.hasBeenReset = true;
22628        }
22629      }));
22630
22631    Object.defineProperty(cue,
22632      "align", extend({}, baseObj, {
22633        get: function() {
22634          return _align;
22635        },
22636        set: function(value) {
22637          var setting = findAlignSetting(value);
22638          if (!setting) {
22639            throw new SyntaxError("An invalid or illegal string was specified.");
22640          }
22641          _align = setting;
22642          this.hasBeenReset = true;
22643        }
22644      }));
22645
22646    /**
22647     * Other <track> spec defined properties
22648     */
22649
22650    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
22651    cue.displayState = undefined;
22652
22653    if (isIE8) {
22654      return cue;
22655    }
22656  }
22657
22658  /**
22659   * VTTCue methods
22660   */
22661
22662  VTTCue.prototype.getCueAsHTML = function() {
22663    // Assume WebVTT.convertCueToDOMTree is on the global.
22664    return WebVTT.convertCueToDOMTree(window, this.text);
22665  };
22666
22667  root.VTTCue = root.VTTCue || VTTCue;
22668  vttjs.VTTCue = VTTCue;
22669}(this, (this.vttjs || {})));
22670
22671/**
22672 * Copyright 2013 vtt.js Contributors
22673 *
22674 * Licensed under the Apache License, Version 2.0 (the "License");
22675 * you may not use this file except in compliance with the License.
22676 * You may obtain a copy of the License at
22677 *
22678 *   http://www.apache.org/licenses/LICENSE-2.0
22679 *
22680 * Unless required by applicable law or agreed to in writing, software
22681 * distributed under the License is distributed on an "AS IS" BASIS,
22682 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22683 * See the License for the specific language governing permissions and
22684 * limitations under the License.
22685 */
22686
22687(function(root, vttjs) {
22688
22689  var scrollSetting = {
22690    "": true,
22691    "up": true
22692  };
22693
22694  function findScrollSetting(value) {
22695    if (typeof value !== "string") {
22696      return false;
22697    }
22698    var scroll = scrollSetting[value.toLowerCase()];
22699    return scroll ? value.toLowerCase() : false;
22700  }
22701
22702  function isValidPercentValue(value) {
22703    return typeof value === "number" && (value >= 0 && value <= 100);
22704  }
22705
22706  // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
22707  function VTTRegion() {
22708    var _width = 100;
22709    var _lines = 3;
22710    var _regionAnchorX = 0;
22711    var _regionAnchorY = 100;
22712    var _viewportAnchorX = 0;
22713    var _viewportAnchorY = 100;
22714    var _scroll = "";
22715
22716    Object.defineProperties(this, {
22717      "width": {
22718        enumerable: true,
22719        get: function() {
22720          return _width;
22721        },
22722        set: function(value) {
22723          if (!isValidPercentValue(value)) {
22724            throw new Error("Width must be between 0 and 100.");
22725          }
22726          _width = value;
22727        }
22728      },
22729      "lines": {
22730        enumerable: true,
22731        get: function() {
22732          return _lines;
22733        },
22734        set: function(value) {
vendor: 16,471 bytes, lines 22735-23239
22735          if (typeof value !== "number") {
22736            throw new TypeError("Lines must be set to a number.");
22737          }
22738          _lines = value;
22739        }
22740      },
22741      "regionAnchorY": {
22742        enumerable: true,
22743        get: function() {
22744          return _regionAnchorY;
22745        },
22746        set: function(value) {
22747          if (!isValidPercentValue(value)) {
22748            throw new Error("RegionAnchorX must be between 0 and 100.");
22749          }
22750          _regionAnchorY = value;
22751        }
22752      },
22753      "regionAnchorX": {
22754        enumerable: true,
22755        get: function() {
22756          return _regionAnchorX;
22757        },
22758        set: function(value) {
22759          if(!isValidPercentValue(value)) {
22760            throw new Error("RegionAnchorY must be between 0 and 100.");
22761          }
22762          _regionAnchorX = value;
22763        }
22764      },
22765      "viewportAnchorY": {
22766        enumerable: true,
22767        get: function() {
22768          return _viewportAnchorY;
22769        },
22770        set: function(value) {
22771          if (!isValidPercentValue(value)) {
22772            throw new Error("ViewportAnchorY must be between 0 and 100.");
22773          }
22774          _viewportAnchorY = value;
22775        }
22776      },
22777      "viewportAnchorX": {
22778        enumerable: true,
22779        get: function() {
22780          return _viewportAnchorX;
22781        },
22782        set: function(value) {
22783          if (!isValidPercentValue(value)) {
22784            throw new Error("ViewportAnchorX must be between 0 and 100.");
22785          }
22786          _viewportAnchorX = value;
22787        }
22788      },
22789      "scroll": {
22790        enumerable: true,
22791        get: function() {
22792          return _scroll;
22793        },
22794        set: function(value) {
22795          var setting = findScrollSetting(value);
22796          // Have to check for false as an empty string is a legal value.
22797          if (setting === false) {
22798            throw new SyntaxError("An invalid or illegal string was specified.");
22799          }
22800          _scroll = setting;
22801        }
22802      }
22803    });
22804  }
22805
22806  root.VTTRegion = root.VTTRegion || VTTRegion;
22807  vttjs.VTTRegion = VTTRegion;
22808}(this, (this.vttjs || {})));
22809
22810/**
22811 * Copyright 2013 vtt.js Contributors
22812 *
22813 * Licensed under the Apache License, Version 2.0 (the "License");
22814 * you may not use this file except in compliance with the License.
22815 * You may obtain a copy of the License at
22816 *
22817 *   http://www.apache.org/licenses/LICENSE-2.0
22818 *
22819 * Unless required by applicable law or agreed to in writing, software
22820 * distributed under the License is distributed on an "AS IS" BASIS,
22821 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22822 * See the License for the specific language governing permissions and
22823 * limitations under the License.
22824 */
22825
22826/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
22827/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
22828
22829(function(global) {
22830
22831  var _objCreate = Object.create || (function() {
22832    function F() {}
22833    return function(o) {
22834      if (arguments.length !== 1) {
22835        throw new Error('Object.create shim only accepts one parameter.');
22836      }
22837      F.prototype = o;
22838      return new F();
22839    };
22840  })();
22841
22842  // Creates a new ParserError object from an errorData object. The errorData
22843  // object should have default code and message properties. The default message
22844  // property can be overriden by passing in a message parameter.
22845  // See ParsingError.Errors below for acceptable errors.
22846  function ParsingError(errorData, message) {
22847    this.name = "ParsingError";
22848    this.code = errorData.code;
22849    this.message = message || errorData.message;
22850  }
22851  ParsingError.prototype = _objCreate(Error.prototype);
22852  ParsingError.prototype.constructor = ParsingError;
22853
22854  // ParsingError metadata for acceptable ParsingErrors.
22855  ParsingError.Errors = {
22856    BadSignature: {
22857      code: 0,
22858      message: "Malformed WebVTT signature."
22859    },
22860    BadTimeStamp: {
22861      code: 1,
22862      message: "Malformed time stamp."
22863    }
22864  };
22865
22866  // Try to parse input as a time stamp.
22867  function parseTimeStamp(input) {
22868
22869    function computeSeconds(h, m, s, f) {
22870      return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
22871    }
22872
22873    var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
22874    if (!m) {
22875      return null;
22876    }
22877
22878    if (m[3]) {
22879      // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
22880      return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
22881    } else if (m[1] > 59) {
22882      // Timestamp takes the form of [hours]:[minutes].[milliseconds]
22883      // First position is hours as it's over 59.
22884      return computeSeconds(m[1], m[2], 0,  m[4]);
22885    } else {
22886      // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
22887      return computeSeconds(0, m[1], m[2], m[4]);
22888    }
22889  }
22890
22891  // A settings object holds key/value pairs and will ignore anything but the first
22892  // assignment to a specific key.
22893  function Settings() {
22894    this.values = _objCreate(null);
22895  }
22896
22897  Settings.prototype = {
22898    // Only accept the first assignment to any key.
22899    set: function(k, v) {
22900      if (!this.get(k) && v !== "") {
22901        this.values[k] = v;
22902      }
22903    },
22904    // Return the value for a key, or a default value.
22905    // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
22906    // a number of possible default values as properties where 'defaultKey' is
22907    // the key of the property that will be chosen; otherwise it's assumed to be
22908    // a single value.
22909    get: function(k, dflt, defaultKey) {
22910      if (defaultKey) {
22911        return this.has(k) ? this.values[k] : dflt[defaultKey];
22912      }
22913      return this.has(k) ? this.values[k] : dflt;
22914    },
22915    // Check whether we have a value for a key.
22916    has: function(k) {
22917      return k in this.values;
22918    },
22919    // Accept a setting if its one of the given alternatives.
22920    alt: function(k, v, a) {
22921      for (var n = 0; n < a.length; ++n) {
22922        if (v === a[n]) {
22923          this.set(k, v);
22924          break;
22925        }
22926      }
22927    },
22928    // Accept a setting if its a valid (signed) integer.
22929    integer: function(k, v) {
22930      if (/^-?\d+$/.test(v)) { // integer
22931        this.set(k, parseInt(v, 10));
22932      }
22933    },
22934    // Accept a setting if its a valid percentage.
22935    percent: function(k, v) {
22936      var m;
22937      if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
22938        v = parseFloat(v);
22939        if (v >= 0 && v <= 100) {
22940          this.set(k, v);
22941          return true;
22942        }
22943      }
22944      return false;
22945    }
22946  };
22947
22948  // Helper function to parse input into groups separated by 'groupDelim', and
22949  // interprete each group as a key/value pair separated by 'keyValueDelim'.
22950  function parseOptions(input, callback, keyValueDelim, groupDelim) {
22951    var groups = groupDelim ? input.split(groupDelim) : [input];
22952    for (var i in groups) {
22953      if (typeof groups[i] !== "string") {
22954        continue;
22955      }
22956      var kv = groups[i].split(keyValueDelim);
22957      if (kv.length !== 2) {
22958        continue;
22959      }
22960      var k = kv[0];
22961      var v = kv[1];
22962      callback(k, v);
22963    }
22964  }
22965
22966  function parseCue(input, cue, regionList) {
22967    // Remember the original input if we need to throw an error.
22968    var oInput = input;
22969    // 4.1 WebVTT timestamp
22970    function consumeTimeStamp() {
22971      var ts = parseTimeStamp(input);
22972      if (ts === null) {
22973        throw new ParsingError(ParsingError.Errors.BadTimeStamp,
22974                              "Malformed timestamp: " + oInput);
22975      }
22976      // Remove time stamp from input.
22977      input = input.replace(/^[^\sa-zA-Z-]+/, "");
22978      return ts;
22979    }
22980
22981    // 4.4.2 WebVTT cue settings
22982    function consumeCueSettings(input, cue) {
22983      var settings = new Settings();
22984
22985      parseOptions(input, function (k, v) {
22986        switch (k) {
22987        case "region":
22988          // Find the last region we parsed with the same region id.
22989          for (var i = regionList.length - 1; i >= 0; i--) {
22990            if (regionList[i].id === v) {
22991              settings.set(k, regionList[i].region);
22992              break;
22993            }
22994          }
22995          break;
22996        case "vertical":
22997          settings.alt(k, v, ["rl", "lr"]);
22998          break;
22999        case "line":
23000          var vals = v.split(","),
23001              vals0 = vals[0];
23002          settings.integer(k, vals0);
23003          settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
23004          settings.alt(k, vals0, ["auto"]);
23005          if (vals.length === 2) {
23006            settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
23007          }
23008          break;
23009        case "position":
23010          vals = v.split(",");
23011          settings.percent(k, vals[0]);
23012          if (vals.length === 2) {
23013            settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
23014          }
23015          break;
23016        case "size":
23017          settings.percent(k, v);
23018          break;
23019        case "align":
23020          settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
23021          break;
23022        }
23023      }, /:/, /\s/);
23024
23025      // Apply default values for any missing fields.
23026      cue.region = settings.get("region", null);
23027      cue.vertical = settings.get("vertical", "");
23028      cue.line = settings.get("line", "auto");
23029      cue.lineAlign = settings.get("lineAlign", "start");
23030      cue.snapToLines = settings.get("snapToLines", true);
23031      cue.size = settings.get("size", 100);
23032      cue.align = settings.get("align", "middle");
23033      cue.position = settings.get("position", {
23034        start: 0,
23035        left: 0,
23036        middle: 50,
23037        end: 100,
23038        right: 100
23039      }, cue.align);
23040      cue.positionAlign = settings.get("positionAlign", {
23041        start: "start",
23042        left: "start",
23043        middle: "middle",
23044        end: "end",
23045        right: "end"
23046      }, cue.align);
23047    }
23048
23049    function skipWhitespace() {
23050      input = input.replace(/^\s+/, "");
23051    }
23052
23053    // 4.1 WebVTT cue timings.
23054    skipWhitespace();
23055    cue.startTime = consumeTimeStamp();   // (1) collect cue start time
23056    skipWhitespace();
23057    if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
23058      throw new ParsingError(ParsingError.Errors.BadTimeStamp,
23059                             "Malformed time stamp (time stamps must be separated by '-->'): " +
23060                             oInput);
23061    }
23062    input = input.substr(3);
23063    skipWhitespace();
23064    cue.endTime = consumeTimeStamp();     // (5) collect cue end time
23065
23066    // 4.1 WebVTT cue settings list.
23067    skipWhitespace();
23068    consumeCueSettings(input, cue);
23069  }
23070
23071  var ESCAPE = {
23072    "&amp;": "&",
23073    "&lt;": "<",
23074    "&gt;": ">",
23075    "&lrm;": "\u200e",
23076    "&rlm;": "\u200f",
23077    "&nbsp;": "\u00a0"
23078  };
23079
23080  var TAG_NAME = {
23081    c: "span",
23082    i: "i",
23083    b: "b",
23084    u: "u",
23085    ruby: "ruby",
23086    rt: "rt",
23087    v: "span",
23088    lang: "span"
23089  };
23090
23091  var TAG_ANNOTATION = {
23092    v: "title",
23093    lang: "lang"
23094  };
23095
23096  var NEEDS_PARENT = {
23097    rt: "ruby"
23098  };
23099
23100  // Parse content into a document fragment.
23101  function parseContent(window, input) {
23102    function nextToken() {
23103      // Check for end-of-string.
23104      if (!input) {
23105        return null;
23106      }
23107
23108      // Consume 'n' characters from the input.
23109      function consume(result) {
23110        input = input.substr(result.length);
23111        return result;
23112      }
23113
23114      var m = input.match(/^([^<]*)(<[^>]+>?)?/);
23115      // If there is some text before the next tag, return it, otherwise return
23116      // the tag.
23117      return consume(m[1] ? m[1] : m[2]);
23118    }
23119
23120    // Unescape a string 's'.
23121    function unescape1(e) {
23122      return ESCAPE[e];
23123    }
23124    function unescape(s) {
23125      while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
23126        s = s.replace(m[0], unescape1);
23127      }
23128      return s;
23129    }
23130
23131    function shouldAdd(current, element) {
23132      return !NEEDS_PARENT[element.localName] ||
23133             NEEDS_PARENT[element.localName] === current.localName;
23134    }
23135
23136    // Create an element for this tag.
23137    function createElement(type, annotation) {
23138      var tagName = TAG_NAME[type];
23139      if (!tagName) {
23140        return null;
23141      }
23142      var element = window.document.createElement(tagName);
23143      element.localName = tagName;
23144      var name = TAG_ANNOTATION[type];
23145      if (name && annotation) {
23146        element[name] = annotation.trim();
23147      }
23148      return element;
23149    }
23150
23151    var rootDiv = window.document.createElement("div"),
23152        current = rootDiv,
23153        t,
23154        tagStack = [];
23155
23156    while ((t = nextToken()) !== null) {
23157      if (t[0] === '<') {
23158        if (t[1] === "/") {
23159          // If the closing tag matches, move back up to the parent node.
23160          if (tagStack.length &&
23161              tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
23162            tagStack.pop();
23163            current = current.parentNode;
23164          }
23165          // Otherwise just ignore the end tag.
23166          continue;
23167        }
23168        var ts = parseTimeStamp(t.substr(1, t.length - 2));
23169        var node;
23170        if (ts) {
23171          // Timestamps are lead nodes as well.
23172          node = window.document.createProcessingInstruction("timestamp", ts);
23173          current.appendChild(node);
23174          continue;
23175        }
23176        var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
23177        // If we can't parse the tag, skip to the next tag.
23178        if (!m) {
23179          continue;
23180        }
23181        // Try to construct an element, and ignore the tag if we couldn't.
23182        node = createElement(m[1], m[3]);
23183        if (!node) {
23184          continue;
23185        }
23186        // Determine if the tag should be added based on the context of where it
23187        // is placed in the cuetext.
23188        if (!shouldAdd(current, node)) {
23189          continue;
23190        }
23191        // Set the class list (as a list of classes, separated by space).
23192        if (m[2]) {
23193          node.className = m[2].substr(1).replace('.', ' ');
23194        }
23195        // Append the node to the current node, and enter the scope of the new
23196        // node.
23197        tagStack.push(m[1]);
23198        current.appendChild(node);
23199        current = node;
23200        continue;
23201      }
23202
23203      // Text nodes are leaf nodes.
23204      current.appendChild(window.document.createTextNode(unescape(t)));
23205    }
23206
23207    return rootDiv;
23208  }
23209
23210  // This is a list of all the Unicode characters that have a strong
23211  // right-to-left category. What this means is that these characters are
23212  // written right-to-left for sure. It was generated by pulling all the strong
23213  // right-to-left characters out of the Unicode data table. That table can
23214  // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
23215  var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
23216      0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
23217      0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
23218      0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
23219      0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
23220      0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
23221      0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
23222      0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
23223      0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
23224      0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
23225      0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
23226      0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
23227      0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
23228      0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
23229      0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
23230      0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
23231      0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
23232      0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
23233      0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
23234      0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
23235      0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
23236      0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
23237      0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
23238      0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
23239      0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
23240      0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
23241      0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
23242      0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
23243      0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
23244      0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
23245      0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
23246      0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
23247      0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
23248      0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
23249      0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
23250      0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
23251      0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
23252      0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
23253      0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
23254      0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
23255      0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
23256      0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
23257      0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
23258      0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
23259      0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
23260      0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
23261      0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
23262      0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
23263      0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
23264      0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
23265      0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
23266      0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
23267      0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
23268      0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
23269      0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
23270      0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
23271      0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
23272      0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
23273      0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
23274      0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
23275      0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
23276      0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
23277      0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
23278      0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
23279      0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
23280      0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
23281      0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
23282      0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
23283      0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
23284      0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
23285      0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
23286      0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
23287      0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
23288      0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
23289      0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
23290      0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
23291      0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
23292      0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
23293      0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
23294      0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
23295      0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
23296      0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
23297      0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
23298      0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
23299      0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
23300      0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
23301      0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
23302      0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
23303      0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
23304      0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
23305      0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
23306      0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
23307      0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
23308      0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
23309      0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
23310      0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
23311      0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
23312      0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
23313      0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
23314      0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
23315      0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
23316      0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
23317      0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
23318      0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
23319      0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
23320      0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
23321      0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
23322      0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
23323      0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
23324      0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
23325      0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
23326      0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
23327      0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
23328      0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
23329      0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
23330      0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
23331      0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
23332      0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
23333      0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
23334      0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
23335      0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
23336      0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
23337      0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
23338      0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
23339      0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
23340      0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
23341      0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
23342      0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
23343      0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
23344      0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
23345      0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
23346      0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
23347      0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
23348      0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
23349      0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
23350      0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
23351      0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
23352      0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
23353      0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
23354      0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
23355      0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
23356      0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
23357      0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
23358      0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
23359      0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
23360      0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
23361      0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
23362      0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
23363      0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
23364      0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
23365      0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
23366      0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
23367      0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
23368      0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
23369      0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
23370      0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
23371      0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
23372      0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
23373      0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
23374      0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
23375      0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
23376      0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
23377      0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
23378      0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
23379      0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
23380      0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
23381      0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
23382      0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
23383      0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
23384      0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
23385      0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
23386      0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
23387      0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
23388      0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
23389      0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
23390      0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
23391      0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
23392      0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
23393      0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
23394      0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
23395      0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
23396      0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
23397      0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
23398      0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
23399      0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
23400      0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
23401      0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
23402      0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
23403      0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
23404      0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
23405      0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
23406      0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
23407      0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
23408      0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
23409      0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
23410      0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
23411      0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
23412      0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
23413      0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
23414      0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
23415      0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
23416      0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
23417      0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
23418      0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
23419      0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
23420      0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
23421      0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
23422      0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
23423      0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
23424      0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
23425      0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
23426      0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
23427      0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
23428      0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
23429      0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
23430      0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];
23431
23432  function determineBidi(cueDiv) {
23433    var nodeStack = [],
23434        text = "",
vendor: 6,425 bytes, lines 23435-23638
23435        charCode;
23436
23437    if (!cueDiv || !cueDiv.childNodes) {
23438      return "ltr";
23439    }
23440
23441    function pushNodes(nodeStack, node) {
23442      for (var i = node.childNodes.length - 1; i >= 0; i--) {
23443        nodeStack.push(node.childNodes[i]);
23444      }
23445    }
23446
23447    function nextTextNode(nodeStack) {
23448      if (!nodeStack || !nodeStack.length) {
23449        return null;
23450      }
23451
23452      var node = nodeStack.pop(),
23453          text = node.textContent || node.innerText;
23454      if (text) {
23455        // TODO: This should match all unicode type B characters (paragraph
23456        // separator characters). See issue #115.
23457        var m = text.match(/^.*(\n|\r)/);
23458        if (m) {
23459          nodeStack.length = 0;
23460          return m[0];
23461        }
23462        return text;
23463      }
23464      if (node.tagName === "ruby") {
23465        return nextTextNode(nodeStack);
23466      }
23467      if (node.childNodes) {
23468        pushNodes(nodeStack, node);
23469        return nextTextNode(nodeStack);
23470      }
23471    }
23472
23473    pushNodes(nodeStack, cueDiv);
23474    while ((text = nextTextNode(nodeStack))) {
23475      for (var i = 0; i < text.length; i++) {
23476        charCode = text.charCodeAt(i);
23477        for (var j = 0; j < strongRTLChars.length; j++) {
23478          if (strongRTLChars[j] === charCode) {
23479            return "rtl";
23480          }
23481        }
23482      }
23483    }
23484    return "ltr";
23485  }
23486
23487  function computeLinePos(cue) {
23488    if (typeof cue.line === "number" &&
23489        (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
23490      return cue.line;
23491    }
23492    if (!cue.track || !cue.track.textTrackList ||
23493        !cue.track.textTrackList.mediaElement) {
23494      return -1;
23495    }
23496    var track = cue.track,
23497        trackList = track.textTrackList,
23498        count = 0;
23499    for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
23500      if (trackList[i].mode === "showing") {
23501        count++;
23502      }
23503    }
23504    return ++count * -1;
23505  }
23506
23507  function StyleBox() {
23508  }
23509
23510  // Apply styles to a div. If there is no div passed then it defaults to the
23511  // div on 'this'.
23512  StyleBox.prototype.applyStyles = function(styles, div) {
23513    div = div || this.div;
23514    for (var prop in styles) {
23515      if (styles.hasOwnProperty(prop)) {
23516        div.style[prop] = styles[prop];
23517      }
23518    }
23519  };
23520
23521  StyleBox.prototype.formatStyle = function(val, unit) {
23522    return val === 0 ? 0 : val + unit;
23523  };
23524
23525  // Constructs the computed display state of the cue (a div). Places the div
23526  // into the overlay which should be a block level element (usually a div).
23527  function CueStyleBox(window, cue, styleOptions) {
23528    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
23529    var color = "rgba(255, 255, 255, 1)";
23530    var backgroundColor = "rgba(0, 0, 0, 0.8)";
23531
23532    if (isIE8) {
23533      color = "rgb(255, 255, 255)";
23534      backgroundColor = "rgb(0, 0, 0)";
23535    }
23536
23537    StyleBox.call(this);
23538    this.cue = cue;
23539
23540    // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
23541    // have inline positioning and will function as the cue background box.
23542    this.cueDiv = parseContent(window, cue.text);
23543    var styles = {
23544      color: color,
23545      backgroundColor: backgroundColor,
23546      position: "relative",
23547      left: 0,
23548      right: 0,
23549      top: 0,
23550      bottom: 0,
23551      display: "inline"
23552    };
23553
23554    if (!isIE8) {
23555      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
23556                                               : cue.vertical === "lr" ? "vertical-lr"
23557                                                                       : "vertical-rl";
23558      styles.unicodeBidi = "plaintext";
23559    }
23560    this.applyStyles(styles, this.cueDiv);
23561
23562    // Create an absolutely positioned div that will be used to position the cue
23563    // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
23564    // mirrors of them except "middle" which is "center" in CSS.
23565    this.div = window.document.createElement("div");
23566    styles = {
23567      textAlign: cue.align === "middle" ? "center" : cue.align,
23568      font: styleOptions.font,
23569      whiteSpace: "pre-line",
23570      position: "absolute"
23571    };
23572
23573    if (!isIE8) {
23574      styles.direction = determineBidi(this.cueDiv);
23575      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
23576                                               : cue.vertical === "lr" ? "vertical-lr"
23577                                                                       : "vertical-rl".
23578      stylesunicodeBidi =  "plaintext";
23579    }
23580
23581    this.applyStyles(styles);
23582
23583    this.div.appendChild(this.cueDiv);
23584
23585    // Calculate the distance from the reference edge of the viewport to the text
23586    // position of the cue box. The reference edge will be resolved later when
23587    // the box orientation styles are applied.
23588    var textPos = 0;
23589    switch (cue.positionAlign) {
23590    case "start":
23591      textPos = cue.position;
23592      break;
23593    case "middle":
23594      textPos = cue.position - (cue.size / 2);
23595      break;
23596    case "end":
23597      textPos = cue.position - cue.size;
23598      break;
23599    }
23600
23601    // Horizontal box orientation; textPos is the distance from the left edge of the
23602    // area to the left edge of the box and cue.size is the distance extending to
23603    // the right from there.
23604    if (cue.vertical === "") {
23605      this.applyStyles({
23606        left:  this.formatStyle(textPos, "%"),
23607        width: this.formatStyle(cue.size, "%")
23608      });
23609    // Vertical box orientation; textPos is the distance from the top edge of the
23610    // area to the top edge of the box and cue.size is the height extending
23611    // downwards from there.
23612    } else {
23613      this.applyStyles({
23614        top: this.formatStyle(textPos, "%"),
23615        height: this.formatStyle(cue.size, "%")
23616      });
23617    }
23618
23619    this.move = function(box) {
23620      this.applyStyles({
23621        top: this.formatStyle(box.top, "px"),
23622        bottom: this.formatStyle(box.bottom, "px"),
23623        left: this.formatStyle(box.left, "px"),
23624        right: this.formatStyle(box.right, "px"),
23625        height: this.formatStyle(box.height, "px"),
23626        width: this.formatStyle(box.width, "px")
23627      });
23628    };
23629  }
23630  CueStyleBox.prototype = _objCreate(StyleBox.prototype);
23631  CueStyleBox.prototype.constructor = CueStyleBox;
23632
23633  // Represents the co-ordinates of an Element in a way that we can easily
23634  // compute things with such as if it overlaps or intersects with another Element.
23635  // Can initialize it with either a StyleBox or another BoxPosition.
23636  function BoxPosition(obj) {
23637    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
23638
vendor: 11,730 bytes, lines 23639-23976
23639    // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
23640    // was passed in and we need to copy the results of 'getBoundingClientRect'
23641    // as the object returned is readonly. All co-ordinate values are in reference
23642    // to the viewport origin (top left).
23643    var lh, height, width, top;
23644    if (obj.div) {
23645      height = obj.div.offsetHeight;
23646      width = obj.div.offsetWidth;
23647      top = obj.div.offsetTop;
23648
23649      var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
23650                  rects.getClientRects && rects.getClientRects();
23651      obj = obj.div.getBoundingClientRect();
23652      // In certain cases the outter div will be slightly larger then the sum of
23653      // the inner div's lines. This could be due to bold text, etc, on some platforms.
23654      // In this case we should get the average line height and use that. This will
23655      // result in the desired behaviour.
23656      lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
23657                 : 0;
23658
23659    }
23660    this.left = obj.left;
23661    this.right = obj.right;
23662    this.top = obj.top || top;
23663    this.height = obj.height || height;
23664    this.bottom = obj.bottom || (top + (obj.height || height));
23665    this.width = obj.width || width;
23666    this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
23667
23668    if (isIE8 && !this.lineHeight) {
23669      this.lineHeight = 13;
23670    }
23671  }
23672
23673  // Move the box along a particular axis. Optionally pass in an amount to move
23674  // the box. If no amount is passed then the default is the line height of the
23675  // box.
23676  BoxPosition.prototype.move = function(axis, toMove) {
23677    toMove = toMove !== undefined ? toMove : this.lineHeight;
23678    switch (axis) {
23679    case "+x":
23680      this.left += toMove;
23681      this.right += toMove;
23682      break;
23683    case "-x":
23684      this.left -= toMove;
23685      this.right -= toMove;
23686      break;
23687    case "+y":
23688      this.top += toMove;
23689      this.bottom += toMove;
23690      break;
23691    case "-y":
23692      this.top -= toMove;
23693      this.bottom -= toMove;
23694      break;
23695    }
23696  };
23697
23698  // Check if this box overlaps another box, b2.
23699  BoxPosition.prototype.overlaps = function(b2) {
23700    return this.left < b2.right &&
23701           this.right > b2.left &&
23702           this.top < b2.bottom &&
23703           this.bottom > b2.top;
23704  };
23705
23706  // Check if this box overlaps any other boxes in boxes.
23707  BoxPosition.prototype.overlapsAny = function(boxes) {
23708    for (var i = 0; i < boxes.length; i++) {
23709      if (this.overlaps(boxes[i])) {
23710        return true;
23711      }
23712    }
23713    return false;
23714  };
23715
23716  // Check if this box is within another box.
23717  BoxPosition.prototype.within = function(container) {
23718    return this.top >= container.top &&
23719           this.bottom <= container.bottom &&
23720           this.left >= container.left &&
23721           this.right <= container.right;
23722  };
23723
23724  // Check if this box is entirely within the container or it is overlapping
23725  // on the edge opposite of the axis direction passed. For example, if "+x" is
23726  // passed and the box is overlapping on the left edge of the container, then
23727  // return true.
23728  BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
23729    switch (axis) {
23730    case "+x":
23731      return this.left < container.left;
23732    case "-x":
23733      return this.right > container.right;
23734    case "+y":
23735      return this.top < container.top;
23736    case "-y":
23737      return this.bottom > container.bottom;
23738    }
23739  };
23740
23741  // Find the percentage of the area that this box is overlapping with another
23742  // box.
23743  BoxPosition.prototype.intersectPercentage = function(b2) {
23744    var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
23745        y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
23746        intersectArea = x * y;
23747    return intersectArea / (this.height * this.width);
23748  };
23749
23750  // Convert the positions from this box to CSS compatible positions using
23751  // the reference container's positions. This has to be done because this
23752  // box's positions are in reference to the viewport origin, whereas, CSS
23753  // values are in referecne to their respective edges.
23754  BoxPosition.prototype.toCSSCompatValues = function(reference) {
23755    return {
23756      top: this.top - reference.top,
23757      bottom: reference.bottom - this.bottom,
23758      left: this.left - reference.left,
23759      right: reference.right - this.right,
23760      height: this.height,
23761      width: this.width
23762    };
23763  };
23764
23765  // Get an object that represents the box's position without anything extra.
23766  // Can pass a StyleBox, HTMLElement, or another BoxPositon.
23767  BoxPosition.getSimpleBoxPosition = function(obj) {
23768    var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
23769    var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
23770    var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
23771
23772    obj = obj.div ? obj.div.getBoundingClientRect() :
23773                  obj.tagName ? obj.getBoundingClientRect() : obj;
23774    var ret = {
23775      left: obj.left,
23776      right: obj.right,
23777      top: obj.top || top,
23778      height: obj.height || height,
23779      bottom: obj.bottom || (top + (obj.height || height)),
23780      width: obj.width || width
23781    };
23782    return ret;
23783  };
23784
23785  // Move a StyleBox to its specified, or next best, position. The containerBox
23786  // is the box that contains the StyleBox, such as a div. boxPositions are
23787  // a list of other boxes that the styleBox can't overlap with.
23788  function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
23789
23790    // Find the best position for a cue box, b, on the video. The axis parameter
23791    // is a list of axis, the order of which, it will move the box along. For example:
23792    // Passing ["+x", "-x"] will move the box first along the x axis in the positive
23793    // direction. If it doesn't find a good position for it there it will then move
23794    // it along the x axis in the negative direction.
23795    function findBestPosition(b, axis) {
23796      var bestPosition,
23797          specifiedPosition = new BoxPosition(b),
23798          percentage = 1; // Highest possible so the first thing we get is better.
23799
23800      for (var i = 0; i < axis.length; i++) {
23801        while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
23802               (b.within(containerBox) && b.overlapsAny(boxPositions))) {
23803          b.move(axis[i]);
23804        }
23805        // We found a spot where we aren't overlapping anything. This is our
23806        // best position.
23807        if (b.within(containerBox)) {
23808          return b;
23809        }
23810        var p = b.intersectPercentage(containerBox);
23811        // If we're outside the container box less then we were on our last try
23812        // then remember this position as the best position.
23813        if (percentage > p) {
23814          bestPosition = new BoxPosition(b);
23815          percentage = p;
23816        }
23817        // Reset the box position to the specified position.
23818        b = new BoxPosition(specifiedPosition);
23819      }
23820      return bestPosition || specifiedPosition;
23821    }
23822
23823    var boxPosition = new BoxPosition(styleBox),
23824        cue = styleBox.cue,
23825        linePos = computeLinePos(cue),
23826        axis = [];
23827
23828    // If we have a line number to align the cue to.
23829    if (cue.snapToLines) {
23830      var size;
23831      switch (cue.vertical) {
23832      case "":
23833        axis = [ "+y", "-y" ];
23834        size = "height";
23835        break;
23836      case "rl":
23837        axis = [ "+x", "-x" ];
23838        size = "width";
23839        break;
23840      case "lr":
23841        axis = [ "-x", "+x" ];
23842        size = "width";
23843        break;
23844      }
23845
23846      var step = boxPosition.lineHeight,
23847          position = step * Math.round(linePos),
23848          maxPosition = containerBox[size] + step,
23849          initialAxis = axis[0];
23850
23851      // If the specified intial position is greater then the max position then
23852      // clamp the box to the amount of steps it would take for the box to
23853      // reach the max position.
23854      if (Math.abs(position) > maxPosition) {
23855        position = position < 0 ? -1 : 1;
23856        position *= Math.ceil(maxPosition / step) * step;
23857      }
23858
23859      // If computed line position returns negative then line numbers are
23860      // relative to the bottom of the video instead of the top. Therefore, we
23861      // need to increase our initial position by the length or width of the
23862      // video, depending on the writing direction, and reverse our axis directions.
23863      if (linePos < 0) {
23864        position += cue.vertical === "" ? containerBox.height : containerBox.width;
23865        axis = axis.reverse();
23866      }
23867
23868      // Move the box to the specified position. This may not be its best
23869      // position.
23870      boxPosition.move(initialAxis, position);
23871
23872    } else {
23873      // If we have a percentage line value for the cue.
23874      var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
23875
23876      switch (cue.lineAlign) {
23877      case "middle":
23878        linePos -= (calculatedPercentage / 2);
23879        break;
23880      case "end":
23881        linePos -= calculatedPercentage;
23882        break;
23883      }
23884
23885      // Apply initial line position to the cue box.
23886      switch (cue.vertical) {
23887      case "":
23888        styleBox.applyStyles({
23889          top: styleBox.formatStyle(linePos, "%")
23890        });
23891        break;
23892      case "rl":
23893        styleBox.applyStyles({
23894          left: styleBox.formatStyle(linePos, "%")
23895        });
23896        break;
23897      case "lr":
23898        styleBox.applyStyles({
23899          right: styleBox.formatStyle(linePos, "%")
23900        });
23901        break;
23902      }
23903
23904      axis = [ "+y", "-x", "+x", "-y" ];
23905
23906      // Get the box position again after we've applied the specified positioning
23907      // to it.
23908      boxPosition = new BoxPosition(styleBox);
23909    }
23910
23911    var bestPosition = findBestPosition(boxPosition, axis);
23912    styleBox.move(bestPosition.toCSSCompatValues(containerBox));
23913  }
23914
23915  function WebVTT() {
23916    // Nothing
23917  }
23918
23919  // Helper to allow strings to be decoded instead of the default binary utf8 data.
23920  WebVTT.StringDecoder = function() {
23921    return {
23922      decode: function(data) {
23923        if (!data) {
23924          return "";
23925        }
23926        if (typeof data !== "string") {
23927          throw new Error("Error - expected string data.");
23928        }
23929        return decodeURIComponent(encodeURIComponent(data));
23930      }
23931    };
23932  };
23933
23934  WebVTT.convertCueToDOMTree = function(window, cuetext) {
23935    if (!window || !cuetext) {
23936      return null;
23937    }
23938    return parseContent(window, cuetext);
23939  };
23940
23941  var FONT_SIZE_PERCENT = 0.05;
23942  var FONT_STYLE = "sans-serif";
23943  var CUE_BACKGROUND_PADDING = "1.5%";
23944
23945  // Runs the processing model over the cues and regions passed to it.
23946  // @param overlay A block level element (usually a div) that the computed cues
23947  //                and regions will be placed into.
23948  WebVTT.processCues = function(window, cues, overlay) {
23949    if (!window || !cues || !overlay) {
23950      return null;
23951    }
23952
23953    // Remove all previous children.
23954    while (overlay.firstChild) {
23955      overlay.removeChild(overlay.firstChild);
23956    }
23957
23958    var paddedOverlay = window.document.createElement("div");
23959    paddedOverlay.style.position = "absolute";
23960    paddedOverlay.style.left = "0";
23961    paddedOverlay.style.right = "0";
23962    paddedOverlay.style.top = "0";
23963    paddedOverlay.style.bottom = "0";
23964    paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
23965    overlay.appendChild(paddedOverlay);
23966
23967    // Determine if we need to compute the display states of the cues. This could
23968    // be the case if a cue's state has been changed since the last computation or
23969    // if it has not been computed yet.
23970    function shouldCompute(cues) {
23971      for (var i = 0; i < cues.length; i++) {
23972        if (cues[i].hasBeenReset || !cues[i].displayState) {
23973          return true;
23974        }
23975      }
23976      return false;
vendor: 9,362 bytes, lines 23977-24266
23977    }
23978
23979    // We don't need to recompute the cues' display states. Just reuse them.
23980    if (!shouldCompute(cues)) {
23981      for (var i = 0; i < cues.length; i++) {
23982        paddedOverlay.appendChild(cues[i].displayState);
23983      }
23984      return;
23985    }
23986
23987    var boxPositions = [],
23988        containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
23989        fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
23990    var styleOptions = {
23991      font: fontSize + "px " + FONT_STYLE
23992    };
23993
23994    (function() {
23995      var styleBox, cue;
23996
23997      for (var i = 0; i < cues.length; i++) {
23998        cue = cues[i];
23999
24000        // Compute the intial position and styles of the cue div.
24001        styleBox = new CueStyleBox(window, cue, styleOptions);
24002        paddedOverlay.appendChild(styleBox.div);
24003
24004        // Move the cue div to it's correct line position.
24005        moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
24006
24007        // Remember the computed div so that we don't have to recompute it later
24008        // if we don't have too.
24009        cue.displayState = styleBox.div;
24010
24011        boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
24012      }
24013    })();
24014  };
24015
24016  WebVTT.Parser = function(window, vttjs, decoder) {
24017    if (!decoder) {
24018      decoder = vttjs;
24019      vttjs = {};
24020    }
24021    if (!vttjs) {
24022      vttjs = {};
24023    }
24024
24025    this.window = window;
24026    this.vttjs = vttjs;
24027    this.state = "INITIAL";
24028    this.buffer = "";
24029    this.decoder = decoder || new TextDecoder("utf8");
24030    this.regionList = [];
24031  };
24032
24033  WebVTT.Parser.prototype = {
24034    // If the error is a ParsingError then report it to the consumer if
24035    // possible. If it's not a ParsingError then throw it like normal.
24036    reportOrThrowError: function(e) {
24037      if (e instanceof ParsingError) {
24038        this.onparsingerror && this.onparsingerror(e);
24039      } else {
24040        throw e;
24041      }
24042    },
24043    parse: function (data) {
24044      var self = this;
24045
24046      // If there is no data then we won't decode it, but will just try to parse
24047      // whatever is in buffer already. This may occur in circumstances, for
24048      // example when flush() is called.
24049      if (data) {
24050        // Try to decode the data that we received.
24051        self.buffer += self.decoder.decode(data, {stream: true});
24052      }
24053
24054      function collectNextLine() {
24055        var buffer = self.buffer;
24056        var pos = 0;
24057        while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
24058          ++pos;
24059        }
24060        var line = buffer.substr(0, pos);
24061        // Advance the buffer early in case we fail below.
24062        if (buffer[pos] === '\r') {
24063          ++pos;
24064        }
24065        if (buffer[pos] === '\n') {
24066          ++pos;
24067        }
24068        self.buffer = buffer.substr(pos);
24069        return line;
24070      }
24071
24072      // 3.4 WebVTT region and WebVTT region settings syntax
24073      function parseRegion(input) {
24074        var settings = new Settings();
24075
24076        parseOptions(input, function (k, v) {
24077          switch (k) {
24078          case "id":
24079            settings.set(k, v);
24080            break;
24081          case "width":
24082            settings.percent(k, v);
24083            break;
24084          case "lines":
24085            settings.integer(k, v);
24086            break;
24087          case "regionanchor":
24088          case "viewportanchor":
24089            var xy = v.split(',');
24090            if (xy.length !== 2) {
24091              break;
24092            }
24093            // We have to make sure both x and y parse, so use a temporary
24094            // settings object here.
24095            var anchor = new Settings();
24096            anchor.percent("x", xy[0]);
24097            anchor.percent("y", xy[1]);
24098            if (!anchor.has("x") || !anchor.has("y")) {
24099              break;
24100            }
24101            settings.set(k + "X", anchor.get("x"));
24102            settings.set(k + "Y", anchor.get("y"));
24103            break;
24104          case "scroll":
24105            settings.alt(k, v, ["up"]);
24106            break;
24107          }
24108        }, /=/, /\s/);
24109
24110        // Create the region, using default values for any values that were not
24111        // specified.
24112        if (settings.has("id")) {
24113          var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
24114          region.width = settings.get("width", 100);
24115          region.lines = settings.get("lines", 3);
24116          region.regionAnchorX = settings.get("regionanchorX", 0);
24117          region.regionAnchorY = settings.get("regionanchorY", 100);
24118          region.viewportAnchorX = settings.get("viewportanchorX", 0);
24119          region.viewportAnchorY = settings.get("viewportanchorY", 100);
24120          region.scroll = settings.get("scroll", "");
24121          // Register the region.
24122          self.onregion && self.onregion(region);
24123          // Remember the VTTRegion for later in case we parse any VTTCues that
24124          // reference it.
24125          self.regionList.push({
24126            id: settings.get("id"),
24127            region: region
24128          });
24129        }
24130      }
24131
24132      // 3.2 WebVTT metadata header syntax
24133      function parseHeader(input) {
24134        parseOptions(input, function (k, v) {
24135          switch (k) {
24136          case "Region":
24137            // 3.3 WebVTT region metadata header syntax
24138            parseRegion(v);
24139            break;
24140          }
24141        }, /:/);
24142      }
24143
24144      // 5.1 WebVTT file parsing.
24145      try {
24146        var line;
24147        if (self.state === "INITIAL") {
24148          // We can't start parsing until we have the first line.
24149          if (!/\r\n|\n/.test(self.buffer)) {
24150            return this;
24151          }
24152
24153          line = collectNextLine();
24154
24155          var m = line.match(/^WEBVTT([ \t].*)?$/);
24156          if (!m || !m[0]) {
24157            throw new ParsingError(ParsingError.Errors.BadSignature);
24158          }
24159
24160          self.state = "HEADER";
24161        }
24162
24163        var alreadyCollectedLine = false;
24164        while (self.buffer) {
24165          // We can't parse a line until we have the full line.
24166          if (!/\r\n|\n/.test(self.buffer)) {
24167            return this;
24168          }
24169
24170          if (!alreadyCollectedLine) {
24171            line = collectNextLine();
24172          } else {
24173            alreadyCollectedLine = false;
24174          }
24175
24176          switch (self.state) {
24177          case "HEADER":
24178            // 13-18 - Allow a header (metadata) under the WEBVTT line.
24179            if (/:/.test(line)) {
24180              parseHeader(line);
24181            } else if (!line) {
24182              // An empty line terminates the header and starts the body (cues).
24183              self.state = "ID";
24184            }
24185            continue;
24186          case "NOTE":
24187            // Ignore NOTE blocks.
24188            if (!line) {
24189              self.state = "ID";
24190            }
24191            continue;
24192          case "ID":
24193            // Check for the start of NOTE blocks.
24194            if (/^NOTE($|[ \t])/.test(line)) {
24195              self.state = "NOTE";
24196              break;
24197            }
24198            // 19-29 - Allow any number of line terminators, then initialize new cue values.
24199            if (!line) {
24200              continue;
24201            }
24202            self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
24203            self.state = "CUE";
24204            // 30-39 - Check if self line contains an optional identifier or timing data.
24205            if (line.indexOf("-->") === -1) {
24206              self.cue.id = line;
24207              continue;
24208            }
24209            // Process line as start of a cue.
24210            /*falls through*/
24211          case "CUE":
24212            // 40 - Collect cue timings and settings.
24213            try {
24214              parseCue(line, self.cue, self.regionList);
24215            } catch (e) {
24216              self.reportOrThrowError(e);
24217              // In case of an error ignore rest of the cue.
24218              self.cue = null;
24219              self.state = "BADCUE";
24220              continue;
24221            }
24222            self.state = "CUETEXT";
24223            continue;
24224          case "CUETEXT":
24225            var hasSubstring = line.indexOf("-->") !== -1;
24226            // 34 - If we have an empty line then report the cue.
24227            // 35 - If we have the special substring '-->' then report the cue,
24228            // but do not collect the line as we need to process the current
24229            // one as a new cue.
24230            if (!line || hasSubstring && (alreadyCollectedLine = true)) {
24231              // We are done parsing self cue.
24232              self.oncue && self.oncue(self.cue);
24233              self.cue = null;
24234              self.state = "ID";
24235              continue;
24236            }
24237            if (self.cue.text) {
24238              self.cue.text += "\n";
24239            }
24240            self.cue.text += line;
24241            continue;
24242          case "BADCUE": // BADCUE
24243            // 54-62 - Collect and discard the remaining cue.
24244            if (!line) {
24245              self.state = "ID";
24246            }
24247            continue;
24248          }
24249        }
24250      } catch (e) {
24251        self.reportOrThrowError(e);
24252
24253        // If we are currently parsing a cue, report what we have.
24254        if (self.state === "CUETEXT" && self.cue && self.oncue) {
24255          self.oncue(self.cue);
24256        }
24257        self.cue = null;
24258        // Enter BADWEBVTT state if header was not parsed correctly otherwise
24259        // another exception occurred so enter BADCUE state.
24260        self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
24261      }
24262      return this;
24263    },
24264    flush: function () {
24265      var self = this;
24266      try {
24267        // Finish decoding the stream.
24268        self.buffer += self.decoder.decode();
24269        // Synthesize the end of the current cue or region.
24270        if (self.cue || self.state === "HEADER") {
24271          self.buffer += "\n\n";
24272          self.parse();
24273        }
24274        // If we've flushed, parsed, and we're still on the INITIAL state then
24275        // that means we don't have enough of the stream to parse the first
24276        // line.
24277        if (self.state === "INITIAL") {
24278          throw new ParsingError(ParsingError.Errors.BadSignature);
24279        }
24280      } catch(e) {
24281        self.reportOrThrowError(e);
24282      }
24283      self.onflush && self.onflush();
24284      return this;
24285    }
24286  };
24287
24288  global.WebVTT = WebVTT;
24289
24290}(this, (this.vttjs || {})));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.