PageSourceSearch

https://tvidea.si/wp-content/plugins/cactus-video/js/video.js

js tvidea.si collected 2026-10-02 21:09:39 UTC 696,998 bytes, 22,220 lines download raw bytes

1/**
2 * @license
3 * Video.js 5.7.0 <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":49}],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":48,"object-keys":49}],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":51,"./shim":52,"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":49}],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 binder = function () {
1970        if (this instanceof bound) {
1971            var result = target.apply(
1972                this,
1973                args.concat(slice.call(arguments))
1974            );
1975            if (Object(result) === result) {
1976                return result;
1977            }
1978            return this;
1979        } else {
1980            return target.apply(
1981                that,
1982                args.concat(slice.call(arguments))
1983            );
1984        }
1985    };
1986
1987    var boundLength = Math.max(0, target.length - args.length);
1988    var boundArgs = [];
1989    for (var i = 0; i < boundLength; i++) {
1990        boundArgs.push('$' + i);
1991    }
1992
1993    var bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
1994
1995    if (target.prototype) {
1996        var Empty = function Empty() {};
1997        Empty.prototype = target.prototype;
1998        bound.prototype = new Empty();
1999        Empty.prototype = null;
2000    }
2001
2002    return bound;
2003};
2004
2005
2006},{}],49:[function(_dereq_,module,exports){
2007'use strict';
2008
2009// modified from https://github.com/es-shims/es5-shim
2010var has = Object.prototype.hasOwnProperty;
2011var toStr = Object.prototype.toString;
2012var slice = Array.prototype.slice;
2013var isArgs = _dereq_('./isArguments');
2014var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
2015var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
2016var dontEnums = [
2017	'toString',
2018	'toLocaleString',
2019	'valueOf',
2020	'hasOwnProperty',
2021	'isPrototypeOf',
2022	'propertyIsEnumerable',
2023	'constructor'
2024];
2025var equalsConstructorPrototype = function (o) {
2026	var ctor = o.constructor;
2027	return ctor && ctor.prototype === o;
2028};
2029var blacklistedKeys = {
2030	$console: true,
2031	$frame: true,
2032	$frameElement: true,
2033	$frames: true,
2034	$parent: true,
2035	$self: true,
2036	$webkitIndexedDB: true,
2037	$webkitStorageInfo: true,
2038	$window: true
2039};
2040var hasAutomationEqualityBug = (function () {
2041	/* global window */
2042	if (typeof window === 'undefined') { return false; }
2043	for (var k in window) {
2044		try {
2045			if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
2046				try {
2047					equalsConstructorPrototype(window[k]);
2048				} catch (e) {
2049					return true;
2050				}
2051			}
2052		} catch (e) {
2053			return true;
2054		}
2055	}
2056	return false;
2057}());
2058var equalsConstructorPrototypeIfNotBuggy = function (o) {
2059	/* global window */
2060	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
2061		return equalsConstructorPrototype(o);
2062	}
2063	try {
2064		return equalsConstructorPrototype(o);
2065	} catch (e) {
2066		return false;
2067	}
2068};
2069
2070var keysShim = function keys(object) {
2071	var isObject = object !== null && typeof object === 'object';
2072	var isFunction = toStr.call(object) === '[object Function]';
2073	var isArguments = isArgs(object);
2074	var isString = isObject && toStr.call(object) === '[object String]';
2075	var theKeys = [];
2076
2077	if (!isObject && !isFunction && !isArguments) {
2078		throw new TypeError('Object.keys called on a non-object');
2079	}
2080
2081	var skipProto = hasProtoEnumBug && isFunction;
2082	if (isString && object.length > 0 && !has.call(object, 0)) {
2083		for (var i = 0; i < object.length; ++i) {
2084			theKeys.push(String(i));
2085		}
2086	}
2087
2088	if (isArguments && object.length > 0) {
2089		for (var j = 0; j < object.length; ++j) {
2090			theKeys.push(String(j));
2091		}
2092	} else {
2093		for (var name in object) {
2094			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
2095				theKeys.push(String(name));
2096			}
2097		}
2098	}
2099
2100	if (hasDontEnumBug) {
2101		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
2102
2103		for (var k = 0; k < dontEnums.length; ++k) {
2104			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
2105				theKeys.push(dontEnums[k]);
2106			}
2107		}
2108	}
2109	return theKeys;
2110};
2111
2112keysShim.shim = function shimObjectKeys() {
2113	if (Object.keys) {
2114		var keysWorksWithArguments = (function () {
2115			// Safari 5.0 bug
2116			return (Object.keys(arguments) || '').length === 2;
2117		}(1, 2));
2118		if (!keysWorksWithArguments) {
2119			var originalKeys = Object.keys;
2120			Object.keys = function keys(object) {
2121				if (isArgs(object)) {
2122					return originalKeys(slice.call(object));
2123				} else {
2124					return originalKeys(object);
2125				}
2126			};
2127		}
2128	} else {
2129		Object.keys = keysShim;
2130	}
2131	return Object.keys || keysShim;
2132};
2133
2134module.exports = keysShim;
2135
2136},{"./isArguments":50}],50:[function(_dereq_,module,exports){
2137'use strict';
2138
2139var toStr = Object.prototype.toString;
2140
2141module.exports = function isArguments(value) {
2142	var str = toStr.call(value);
2143	var isArgs = str === '[object Arguments]';
2144	if (!isArgs) {
2145		isArgs = str !== '[object Array]' &&
2146			value !== null &&
2147			typeof value === 'object' &&
2148			typeof value.length === 'number' &&
2149			value.length >= 0 &&
2150			toStr.call(value.callee) === '[object Function]';
2151	}
2152	return isArgs;
2153};
2154
2155},{}],51:[function(_dereq_,module,exports){
2156'use strict';
2157
2158var implementation = _dereq_('./implementation');
2159
2160var lacksProperEnumerationOrder = function () {
2161	if (!Object.assign) {
2162		return false;
2163	}
2164	// v8, specifically in node 4.x, has a bug with incorrect property enumeration order
2165	// note: this does not detect the bug unless there's 20 characters
2166	var str = 'abcdefghijklmnopqrst';
2167	var letters = str.split('');
2168	var map = {};
2169	for (var i = 0; i < letters.length; ++i) {
2170		map[letters[i]] = letters[i];
2171	}
2172	var obj = Object.assign({}, map);
2173	var actual = '';
2174	for (var k in obj) {
2175		actual += k;
2176	}
2177	return str !== actual;
2178};
2179
2180var assignHasPendingExceptions = function () {
2181	if (!Object.assign || !Object.preventExtensions) {
2182		return false;
2183	}
2184	// Firefox 37 still has "pending exception" logic in its Object.assign implementation,
2185	// which is 72% slower than our shim, and Firefox 40's native implementation.
2186	var thrower = Object.preventExtensions({ 1: 2 });
2187	try {
2188		Object.assign(thrower, 'xy');
2189	} catch (e) {
2190		return thrower[1] === 'y';
2191	}
2192};
2193
2194module.exports = function getPolyfill() {
2195	if (!Object.assign) {
2196		return implementation;
2197	}
2198	if (lacksProperEnumerationOrder()) {
2199		return implementation;
2200	}
2201	if (assignHasPendingExceptions()) {
2202		return implementation;
2203	}
2204	return Object.assign;
2205};
2206
2207},{"./implementation":44}],52:[function(_dereq_,module,exports){
2208'use strict';
2209
2210var define = _dereq_('define-properties');
2211var getPolyfill = _dereq_('./polyfill');
2212
2213module.exports = function shimAssign() {
2214	var polyfill = getPolyfill();
2215	define(
2216		Object,
2217		{ assign: polyfill },
2218		{ assign: function () { return Object.assign !== polyfill; } }
2219	);
2220	return polyfill;
2221};
2222
2223},{"./polyfill":51,"define-properties":46}],53:[function(_dereq_,module,exports){
2224module.exports = SafeParseTuple
2225
2226function SafeParseTuple(obj, reviver) {
2227    var json
2228    var error = null
2229
2230    try {
2231        json = JSON.parse(obj, reviver)
2232    } catch (err) {
2233        error = err
2234    }
2235
2236    return [error, json]
2237}
2238
2239},{}],54:[function(_dereq_,module,exports){
2240function clean (s) {
2241  return s.replace(/\n\r?\s*/g, '')
2242}
2243
2244
2245module.exports = function tsml (sa) {
2246  var s = ''
2247    , i = 0
2248
2249  for (; i < arguments.length; i++)
2250    s += clean(sa[i]) + (arguments[i + 1] || '')
2251
2252  return s
2253}
2254},{}],55:[function(_dereq_,module,exports){
2255"use strict";
2256var window = _dereq_("global/window")
2257var once = _dereq_("once")
2258var isFunction = _dereq_("is-function")
2259var parseHeaders = _dereq_("parse-headers")
2260var xtend = _dereq_("xtend")
2261
2262module.exports = createXHR
2263createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
2264createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
2265
2266forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
2267    createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
2268        options = initParams(uri, options, callback)
2269        options.method = method.toUpperCase()
2270        return _createXHR(options)
2271    }
2272})
2273
2274function forEachArray(array, iterator) {
2275    for (var i = 0; i < array.length; i++) {
2276        iterator(array[i])
2277    }
2278}
2279
2280function isEmpty(obj){
2281    for(var i in obj){
2282        if(obj.hasOwnProperty(i)) return false
2283    }
2284    return true
2285}
2286
2287function initParams(uri, options, callback) {
2288    var params = uri
2289
2290    if (isFunction(options)) {
2291        callback = options
2292        if (typeof uri === "string") {
2293            params = {uri:uri}
2294        }
2295    } else {
2296        params = xtend(options, {uri: uri})
2297    }
2298
2299    params.callback = callback
2300    return params
2301}
2302
2303function createXHR(uri, options, callback) {
2304    options = initParams(uri, options, callback)
2305    return _createXHR(options)
2306}
2307
2308function _createXHR(options) {
2309    var callback = options.callback
2310    if(typeof callback === "undefined"){
2311        throw new Error("callback argument missing")
2312    }
2313    callback = once(callback)
2314
2315    function readystatechange() {
2316        if (xhr.readyState === 4) {
2317            loadFunc()
2318        }
2319    }
2320
2321    function getBody() {
2322        // Chrome with requestType=blob throws errors arround when even testing access to responseText
2323        var body = undefined
2324
2325        if (xhr.response) {
2326            body = xhr.response
2327        } else if (xhr.responseType === "text" || !xhr.responseType) {
2328            body = xhr.responseText || xhr.responseXML
2329        }
2330
2331        if (isJson) {
2332            try {
2333                body = JSON.parse(body)
2334            } catch (e) {}
2335        }
2336
2337        return body
2338    }
2339
2340    var failureResponse = {
2341                body: undefined,
2342                headers: {},
2343                statusCode: 0,
2344                method: method,
2345                url: uri,
2346                rawRequest: xhr
2347            }
2348
2349    function errorFunc(evt) {
2350        clearTimeout(timeoutTimer)
2351        if(!(evt instanceof Error)){
2352            evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
2353        }
2354        evt.statusCode = 0
2355        callback(evt, failureResponse)
2356    }
2357
2358    // will load the data & process the response in a special response object
2359    function loadFunc() {
2360        if (aborted) return
2361        var status
2362        clearTimeout(timeoutTimer)
2363        if(options.useXDR && xhr.status===undefined) {
2364            //IE8 CORS GET successful response doesn't have a status field, but body is fine
2365            status = 200
2366        } else {
2367            status = (xhr.status === 1223 ? 204 : xhr.status)
2368        }
2369        var response = failureResponse
2370        var err = null
2371
2372        if (status !== 0){
2373            response = {
2374                body: getBody(),
2375                statusCode: status,
2376                method: method,
2377                headers: {},
2378                url: uri,
2379                rawRequest: xhr
2380            }
2381            if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
2382                response.headers = parseHeaders(xhr.getAllResponseHeaders())
2383            }
2384        } else {
2385            err = new Error("Internal XMLHttpRequest Error")
2386        }
2387        callback(err, response, response.body)
2388
2389    }
2390
2391    var xhr = options.xhr || null
2392
2393    if (!xhr) {
2394        if (options.cors || options.useXDR) {
2395            xhr = new createXHR.XDomainRequest()
2396        }else{
2397            xhr = new createXHR.XMLHttpRequest()
2398        }
2399    }
2400
2401    var key
2402    var aborted
2403    var uri = xhr.url = options.uri || options.url
2404    var method = xhr.method = options.method || "GET"
2405    var body = options.body || options.data || null
2406    var headers = xhr.headers = options.headers || {}
2407    var sync = !!options.sync
2408    var isJson = false
2409    var timeoutTimer
2410
2411    if ("json" in options) {
2412        isJson = true
2413        headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
2414        if (method !== "GET" && method !== "HEAD") {
2415            headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
2416            body = JSON.stringify(options.json)
2417        }
2418    }
2419
2420    xhr.onreadystatechange = readystatechange
2421    xhr.onload = loadFunc
2422    xhr.onerror = errorFunc
2423    // IE9 must have onprogress be set to a unique function.
2424    xhr.onprogress = function () {
2425        // IE must die
2426    }
2427    xhr.ontimeout = errorFunc
2428    xhr.open(method, uri, !sync, options.username, options.password)
2429    //has to be after open
2430    if(!sync) {
2431        xhr.withCredentials = !!options.withCredentials
2432    }
2433    // Cannot set timeout with sync request
2434    // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
2435    // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
2436    if (!sync && options.timeout > 0 ) {
2437        timeoutTimer = setTimeout(function(){
2438            aborted=true//IE9 may still call readystatechange
2439            xhr.abort("timeout")
2440            var e = new Error("XMLHttpRequest timeout")
2441            e.code = "ETIMEDOUT"
2442            errorFunc(e)
2443        }, options.timeout )
2444    }
2445
2446    if (xhr.setRequestHeader) {
2447        for(key in headers){
2448            if(headers.hasOwnProperty(key)){
2449                xhr.setRequestHeader(key, headers[key])
2450            }
2451        }
2452    } else if (options.headers && !isEmpty(options.headers)) {
2453        throw new Error("Headers cannot be set on an XDomainRequest object")
2454    }
2455
2456    if ("responseType" in options) {
2457        xhr.responseType = options.responseType
2458    }
2459
2460    if ("beforeSend" in options &&
2461        typeof options.beforeSend === "function"
2462    ) {
2463        options.beforeSend(xhr)
2464    }
2465
2466    xhr.send(body)
2467
2468    return xhr
2469
2470
2471}
2472
2473function noop() {}
2474
2475},{"global/window":2,"is-function":56,"once":57,"parse-headers":60,"xtend":61}],56:[function(_dereq_,module,exports){
2476module.exports = isFunction
2477
2478var toString = Object.prototype.toString
2479
2480function isFunction (fn) {
2481  var string = toString.call(fn)
2482  return string === '[object Function]' ||
2483    (typeof fn === 'function' && string !== '[object RegExp]') ||
2484    (typeof window !== 'undefined' &&
2485     // IE8 and below
2486     (fn === window.setTimeout ||
2487      fn === window.alert ||
2488      fn === window.confirm ||
2489      fn === window.prompt))
2490};
2491
2492},{}],57:[function(_dereq_,module,exports){
2493module.exports = once
2494
2495once.proto = once(function () {
2496  Object.defineProperty(Function.prototype, 'once', {
2497    value: function () {
2498      return once(this)
2499    },
2500    configurable: true
2501  })
2502})
2503
2504function once (fn) {
2505  var called = false
2506  return function () {
2507    if (called) return
2508    called = true
2509    return fn.apply(this, arguments)
2510  }
2511}
2512
2513},{}],58:[function(_dereq_,module,exports){
2514var isFunction = _dereq_('is-function')
2515
2516module.exports = forEach
2517
2518var toString = Object.prototype.toString
2519var hasOwnProperty = Object.prototype.hasOwnProperty
2520
2521function forEach(list, iterator, context) {
2522    if (!isFunction(iterator)) {
2523        throw new TypeError('iterator must be a function')
2524    }
2525
2526    if (arguments.length < 3) {
2527        context = this
2528    }
2529    
2530    if (toString.call(list) === '[object Array]')
2531        forEachArray(list, iterator, context)
2532    else if (typeof list === 'string')
2533        forEachString(list, iterator, context)
2534    else
2535        forEachObject(list, iterator, context)
2536}
2537
2538function forEachArray(array, iterator, context) {
2539    for (var i = 0, len = array.length; i < len; i++) {
2540        if (hasOwnProperty.call(array, i)) {
2541            iterator.call(context, array[i], i, array)
2542        }
2543    }
2544}
2545
2546function forEachString(string, iterator, context) {
2547    for (var i = 0, len = string.length; i < len; i++) {
2548        // no such thing as a sparse string.
2549        iterator.call(context, string.charAt(i), i, string)
2550    }
2551}
2552
2553function forEachObject(object, iterator, context) {
2554    for (var k in object) {
2555        if (hasOwnProperty.call(object, k)) {
2556            iterator.call(context, object[k], k, object)
2557        }
2558    }
2559}
2560
2561},{"is-function":56}],59:[function(_dereq_,module,exports){
2562
2563exports = module.exports = trim;
2564
2565function trim(str){
2566  return str.replace(/^\s*|\s*$/g, '');
2567}
2568
2569exports.left = function(str){
2570  return str.replace(/^\s*/, '');
2571};
2572
2573exports.right = function(str){
2574  return str.replace(/\s*$/, '');
2575};
2576
2577},{}],60:[function(_dereq_,module,exports){
2578var trim = _dereq_('trim')
2579  , forEach = _dereq_('for-each')
2580  , isArray = function(arg) {
2581      return Object.prototype.toString.call(arg) === '[object Array]';
2582    }
2583
2584module.exports = function (headers) {
2585  if (!headers)
2586    return {}
2587
2588  var result = {}
2589
2590  forEach(
2591      trim(headers).split('\n')
2592    , function (row) {
2593        var index = row.indexOf(':')
2594          , key = trim(row.slice(0, index)).toLowerCase()
2595          , value = trim(row.slice(index + 1))
2596
2597        if (typeof(result[key]) === 'undefined') {
2598          result[key] = value
2599        } else if (isArray(result[key])) {
2600          result[key].push(value)
2601        } else {
2602          result[key] = [ result[key], value ]
2603        }
2604      }
2605  )
2606
2607  return result
2608}
2609},{"for-each":58,"trim":59}],61:[function(_dereq_,module,exports){
2610module.exports = extend
2611
2612var hasOwnProperty = Object.prototype.hasOwnProperty;
2613
2614function extend() {
2615    var target = {}
2616
2617    for (var i = 0; i < arguments.length; i++) {
2618        var source = arguments[i]
2619
2620        for (var key in source) {
2621            if (hasOwnProperty.call(source, key)) {
2622                target[key] = source[key]
2623            }
2624        }
2625    }
2626
2627    return target
2628}
2629
2630},{}],62:[function(_dereq_,module,exports){
2631/**
2632 * @file big-play-button.js
2633 */
2634'use strict';
2635
2636exports.__esModule = true;
2637
2638function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2639
2640function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2641
2642function _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; }
2643
2644var _buttonJs = _dereq_('./button.js');
2645
2646var _buttonJs2 = _interopRequireDefault(_buttonJs);
2647
2648var _componentJs = _dereq_('./component.js');
2649
2650var _componentJs2 = _interopRequireDefault(_componentJs);
2651
2652/**
2653 * Initial play button. Shows before the video has played. The hiding of the
2654 * big play button is done via CSS and player states.
2655 *
2656 * @param {Object} player  Main Player
2657 * @param {Object=} options Object of option names and values
2658 * @extends Button
2659 * @class BigPlayButton
2660 */
2661
2662var BigPlayButton = (function (_Button) {
2663  _inherits(BigPlayButton, _Button);
2664
2665  function BigPlayButton(player, options) {
2666    _classCallCheck(this, BigPlayButton);
2667
2668    _Button.call(this, player, options);
2669  }
2670
2671  /**
2672   * Allow sub components to stack CSS class names
2673   *
2674   * @return {String} The constructed class name
2675   * @method buildCSSClass
2676   */
2677
2678  BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
2679    return 'vjs-big-play-button';
2680  };
2681
2682  /**
2683   * Handles click for play
2684   *
2685   * @method handleClick
2686   */
2687
2688  BigPlayButton.prototype.handleClick = function handleClick() {
2689    this.player_.play();
2690  };
2691
2692  return BigPlayButton;
2693})(_buttonJs2['default']);
2694
2695BigPlayButton.prototype.controlText_ = 'Play Video';
2696
2697_componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton);
2698exports['default'] = BigPlayButton;
2699module.exports = exports['default'];
2700
2701},{"./button.js":63,"./component.js":66}],63:[function(_dereq_,module,exports){
2702/**
2703 * @file button.js
2704 */
2705'use strict';
2706
2707exports.__esModule = true;
2708
2709function _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; } }
2710
2711function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2712
2713function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2714
2715function _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
2715onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
2716
2717var _clickableComponentJs = _dereq_('./clickable-component.js');
2718
2719var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
2720
2721var _component = _dereq_('./component');
2722
2723var _component2 = _interopRequireDefault(_component);
2724
2725var _utilsEventsJs = _dereq_('./utils/events.js');
2726
2727var Events = _interopRequireWildcard(_utilsEventsJs);
2728
2729var _utilsFnJs = _dereq_('./utils/fn.js');
2730
2731var Fn = _interopRequireWildcard(_utilsFnJs);
2732
2733var _utilsLogJs = _dereq_('./utils/log.js');
2734
2735var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
2736
2737var _globalDocument = _dereq_('global/document');
2738
2739var _globalDocument2 = _interopRequireDefault(_globalDocument);
2740
2741var _objectAssign = _dereq_('object.assign');
2742
2743var _objectAssign2 = _interopRequireDefault(_objectAssign);
2744
2745/**
2746 * Base class for all buttons
2747 *
2748 * @param {Object} player  Main Player
2749 * @param {Object=} options Object of option names and values
2750 * @extends ClickableComponent
2751 * @class Button
2752 */
2753
2754var Button = (function (_ClickableComponent) {
2755  _inherits(Button, _ClickableComponent);
2756
2757  function Button(player, options) {
2758    _classCallCheck(this, Button);
2759
2760    _ClickableComponent.call(this, player, options);
2761  }
2762
2763  /**
2764   * Create the component's DOM element
2765   *
2766   * @param {String=} type Element's node type. e.g. 'div'
2767   * @param {Object=} props An object of properties that should be set on the element
2768   * @param {Object=} attributes An object of attributes that should be set on the element
2769   * @return {Element}
2770   * @method createEl
2771   */
2772
2773  Button.prototype.createEl = function createEl() {
2774    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0];
2775    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2776    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
2777
2778    props = _objectAssign2['default']({
2779      className: this.buildCSSClass()
2780    }, props);
2781
2782    if (tag !== 'button') {
2783      _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
2784    }
2785
2786    // Add attributes for button element
2787    attributes = _objectAssign2['default']({
2788      type: 'button', // Necessary since the default button type is "submit"
2789      'aria-live': 'polite' // let the screen reader user know that the text of the button may change
2790    }, attributes);
2791
2792    var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
2793
2794    this.createControlTextEl(el);
2795
2796    return el;
2797  };
2798
2799  /**
2800   * Adds a child component inside this button
2801   *
2802   * @param {String|Component} child The class name or instance of a child to add
2803   * @param {Object=} options Options, including options to be passed to children of the child.
2804   * @return {Component} The child component (created by this process if a string was used)
2805   * @deprecated
2806   * @method addChild
2807   */
2808
2809  Button.prototype.addChild = function addChild(child) {
2810    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2811
2812    var className = this.constructor.name;
2813    _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
2814
2815    // Avoid the error message generated by ClickableComponent's addChild method
2816    return _component2['default'].prototype.addChild.call(this, child, options);
2817  };
2818
2819  /**
2820   * Handle KeyPress (document level) - Extend with specific functionality for button
2821   *
2822   * @method handleKeyPress
2823   */
2824
2825  Button.prototype.handleKeyPress = function handleKeyPress(event) {
2826    // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
2827    if (event.which === 32 || event.which === 13) {} else {
2828      _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
2829    }
2830  };
2831
2832  return Button;
2833})(_clickableComponentJs2['default']);
2834
2835_component2['default'].registerComponent('Button', Button);
2836exports['default'] = Button;
2837module.exports = exports['default'];
2838
2839},{"./clickable-component.js":64,"./component":66,"./utils/events.js":132,"./ut
2839ils/fn.js":133,"./utils/log.js":136,"global/document":1,"object.assign":45}],64:[function(_dereq_,module,exports){
2840/**
2841 * @file button.js
2842 */
2843'use strict';
2844
2845exports.__esModule = true;
2846
2847function _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; } }
2848
2849function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2850
2851function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2852
2853function _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; }
2854
2855var _component = _dereq_('./component');
2856
2857var _component2 = _interopRequireDefault(_component);
2858
2859var _utilsDomJs = _dereq_('./utils/dom.js');
2860
2861var Dom = _interopRequireWildcard(_utilsDomJs);
2862
2863var _utilsEventsJs = _dereq_('./utils/events.js');
2864
2865var Events = _interopRequireWildcard(_utilsEventsJs);
2866
2867var _utilsFnJs = _dereq_('./utils/fn.js');
2868
2869var Fn = _interopRequireWildcard(_utilsFnJs);
2870
2871var _utilsLogJs = _dereq_('./utils/log.js');
2872
2873var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
2874
2875var _globalDocument = _dereq_('global/document');
2876
2877var _globalDocument2 = _interopRequireDefault(_globalDocument);
2878
2879var _objectAssign = _dereq_('object.assign');
2880
2881var _objectAssign2 = _interopRequireDefault(_objectAssign);
2882
2883/**
2884 * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button
2885 *
2886 * @param {Object} player  Main Player
2887 * @param {Object=} options Object of option names and values
2888 * @extends Component
2889 * @class ClickableComponent
2890 */
2891
2892var ClickableComponent = (function (_Component) {
2893  _inherits(ClickableComponent, _Component);
2894
2895  function ClickableComponent(player, options) {
2896    _classCallCheck(this, ClickableComponent);
2897
2898    _Component.call(this, player, options);
2899
2900    this.emitTapEvents();
2901
2902    this.on('tap', this.handleClick);
2903    this.on('click', this.handleClick);
2904    this.on('focus', this.handleFocus);
2905    this.on('blur', this.handleBlur);
2906  }
2907
2908  /**
2909   * Create the component's DOM element
2910   *
2911   * @param {String=} type Element's node type. e.g. 'div'
2912   * @param {Object=} props An object of properties that should be set on the element
2913   * @param {Object=} attributes An object of attributes that should be set on the element
2914   * @return {Element}
2915   * @method createEl
2916   */
2917
2918  ClickableComponent.prototype.createEl = function createEl() {
2919    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
2920    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2921    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
2922
2923    props = _objectAssign2['default']({
2924      className: this.buildCSSClass(),
2925      tabIndex: 0
2926    }, props);
2927
2928    if (tag === 'button') {
2929      _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
2930    }
2931
2932    // Add ARIA attributes for clickable element which is not a native HTML button
2933    attributes = _objectAssign2['default']({
2934      role: 'button',
2935      'aria-live': 'polite' // let the screen reader user know that the text of the element may change
2936    }, attributes);
2937
2938    var el = _Component.prototype.createEl.call(this, tag, props, attributes);
2939
2940    this.createControlTextEl(el);
2941
2942    return el;
2943  };
2944
2945  /**
2946   * create control text
2947   *
2948   * @param {Element} el Parent element for the control text
2949   * @return {Element}
2950   * @method controlText
2951   */
2952
2953  ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
2954    this.controlTextEl_ = Dom.createEl('span', {
2955      className: 'vjs-control-text'
2956    });
2957
2958    if (el) {
2959      el.appendChild(this.controlTextEl_);
2960    }
2961
2962    this.controlText(this.controlText_);
2963
2964    return this.controlTextEl_;
2965  };
2966
2967  /**
2968   * Controls text - both request and localize
2969   *
2970   * @param {String} text Text for element
2971   * @return {String}
2972   * @method controlText
2973   */
2974
2975  ClickableComponent.prototype.controlText = function controlText(text) {
2976    if (!text) return this.controlText_ || 'Need Text';
2977
2978    this.controlText_ = text;
2979    this.controlTextEl_.innerHTML = this.localize(this.controlText_);
2980
2981    return this;
2982  };
2983
2984  /**
2985   * Allows sub components to stack CSS class names
2986   *
2987   * @return {String}
2988   * @method buildCSSClass
2989   */
2990
2991  ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
2992    return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
2993  };
2994
2995  /**
2996   * Adds a child component inside this clickable-component
2997   *
2998   * @param {String|Component} child The class name or instance of a child to add
2999   * @param {Object=} options Options, including options to be passed to children of the child.
3000   * @return {Component} The child component (created by this process if a string was used)
3001   * @method addChild
3002   */
3003
3004  ClickableComponent.prototype.addChild = function addChild(child) {
3005    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
3006
3007    // TODO: Fix adding an actionable child to a ClickableComponent; currently
3008    // it will cause issues with assistive technology (e.g. screen readers)
3009    // which support ARIA, since an element with role="button" cannot have
3010    // actionable child elements.
3011
3012    //let className = this.constructor.name;
3013    //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.`);
3014
3015    return _Component.prototype.addChild.call(this, child, options);
3016  };
3017
3018  /**
3019   * Handle Click - Override with specific functionality for component
3020   *
3021   * @method handleClick
3022   */
3023
3024  ClickableComponent.prototype.handleClick = function handleClick() {};
3025
3026  /**
3027   * Handle Focus - Add keyboard functionality to element
3028   *
3029   * @method handleFocus
3030   */
3031
3032  ClickableComponent.prototype.handleFocus = function handleFocus() {
3033    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
3034  };
3035
3036  /**
3037   * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed
3038   *
3039   * @method handleKeyPress
3040   */
3041
3042  ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
3043    // Support Space (32) or Enter (13) key operation to fire a click event
3044    if (event.which === 32 || event.which === 13) {
3045      event.preventDefault();
3046      this.handleClick(event);
3047    } else if (_Component.prototype.handleKeyPress) {
3048      _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
3049    }
3050  };
3051
3052  /**
3053   * Handle Blur - Remove keyboard triggers
3054   *
3055   * @method handleBlur
3056   */
3057
3058  ClickableComponent.prototype.handleBlur = function handleBlur() {
3059    Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
3060  };
3061
3062  return ClickableComponent;
3063})(_component2['default']);
3064
3065_component2['default'].registerComponent('ClickableComponent', ClickableComponent);
3066exports['default'] = ClickableComponent;
3067module.exports = exports['default'];
3068
3069},{"./component":66,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/log.js":136,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){
3070'use strict';
3071
3072exports.__esModule = true;
3073
3074function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3075
3076function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
3077
3078function _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; }
3079
3080var _button = _dereq_('./button');
3081
3082var _button2 = _interopRequireDefault(_button);
3083
3084var _component = _dereq_('./component');
3085
3086var _component2 = _interopRequireDefault(_component);
3087
3088/**
3089 * The `CloseButton` component is a button which fires a "close" event
3090 * when it is activated.
3091 *
3092 * @extends Button
3093 * @class CloseButton
3094 */
3095
3096var CloseButton = (function (_Button) {
3097  _inherits(CloseButton, _Button);
3098
3099  function CloseButton(player, options) {
3100    _classCallCheck(this, CloseButton);
3101
3102    _Button.call(this, player, options);
3103    this.controlText(options && options.controlText || this.localize('Close'));
3104  }
3105
3106  CloseButton.prototype.buildCSSClass = function buildCSSClass() {
3107    return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
3108  };
3109
3110  CloseButton.prototype.handleClick = function handleClick() {
3111    this.trigger({ type: 'close', bubbles: false });
3112  };
3113
3114  return CloseButton;
3115})(_button2['default']);
3116
3117_component2['default'].registerComponent('CloseButton', CloseButton);
3118exports['default'] = CloseButton;
3119module.exports = exports['default'];
3120
3121},{"./button":63,"./component":66}],66:[function(_dereq_,module,exports){
3122/**
3123 * @file component.js
3124 *
3125 * Player Component - Base class for all UI objects
3126 */
3127
3128'use strict';
3129
3130exports.__esModule = true;
3131
3132function _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; } }
3133
3134function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3135
3136function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
3137
3138var _globalWindow = _dereq_('global/window');
3139
3140var _globalWindow2 = _interopRequireDefault(_globalWindow);
3141
3142var _utilsDomJs = _dereq_('./utils/dom.js');
3143
3144var Dom = _interopRequireWildcard(_utilsDomJs);
3145
3146var _utilsFnJs = _dereq_('./utils/fn.js');
3147
3148var Fn = _interopRequireWildcard(_utilsFnJs);
3149
3150var _utilsGuidJs = _dereq_('./utils/guid.js');
3151
3152var Guid = _interopRequireWildcard(_utilsGuidJs);
3153
3154var _utilsEventsJs = _dereq_('./utils/events.js');
3155
3156var Events = _interopRequireWildcard(_utilsEventsJs);
3157
3158var _utilsLogJs = _dereq_('./utils/log.js');
3159
3160var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
3161
3162var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
3163
3164var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
3165
3166var _objectAssign = _dereq_('object.assign');
3167
3168var _objectAssign2 = _interopRequireDefault(_objectAssign);
3169
3170var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
3171
3172var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
3173
3174/**
3175 * Base UI Component class
3176 * Components are embeddable UI objects that are represented by both a
3177 * javascript object and an element in the DOM. They can be children of other
3178 * components, and can have many children themselves.
3179 * ```js
3180 *     // adding a button to the player
3181 *     var button = player.addChild('button');
3182 *     button.el(); // -> button element
3183 * ```
3184 * ```html
3185 *     <div class="video-js">
3186 *       <div class="vjs-button">Button</div>
3187 *     </div>
3188 * ```
3189 * Components are also event targets.
3190 * ```js
3191 *     button.on('click', function(){
3192 *       console.log('Button Clicked!');
3193 *     });
3194 *     button.trigger('customevent');
3195 * ```
3196 *
3197 * @param {Object} player  Main Player
3198 * @param {Object=} options Object of option names and values
3199 * @param {Function=} ready    Ready callback function
3200 * @class Component
3201 */
3202
3203var Component = (function () {
3204  function Component(player, options, ready) {
3205    _classCallCheck(this, Component);
3206
3207    // The component might be the player itself and we can't pass `this` to super
3208    if (!player && this.play) {
3209      this.player_ = player = this; // eslint-disable-line
3210    } else {
3211        this.player_ = player;
3212      }
3213
3214    // Make a copy of prototype.options_ to protect against overriding defaults
3215    this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_);
3216
3217    // Updated options with supplied options
3218    options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options);
3219
3220    // Get ID from options or options element if one is supplied
3221    this.id_ = options.id || options.el && options.el.id;
3222
3223    // If there was no ID from the options, generate one
3224    if (!this.id_) {
3225      // Don't require the player ID function in the case of mock players
3226      var id = player && player.id && player.id() || 'no_player';
3227
3228      this.id_ = id + '_component_' + Guid.newGUID();
3229    }
3230
3231    this.name_ = options.name || null;
3232
3233    // Create element if one wasn't provided in options
3234    if (options.el) {
3235      this.el_ = options.el;
3236    } else if (options.createEl !== false) {
3237      this.el_ = this.createEl();
3238    }
3239
3240    this.children_ = [];
3241    this.childIndex_ = {};
3242    this.childNameIndex_ = {};
3243
3244    // Add any child components in options
3245    if (options.initChildren !== false) {
3246      this.initChildren();
3247    }
3248
3249    this.ready(ready);
3250    // Don't want to trigger ready here or it will before init is actually
3251    // finished for all children that run this constructor
3252
3253    if (options.reportTouchActivity !== false) {
3254      this.enableTouchActivity();
3255    }
3256  }
3257
3258  /**
3259   * Dispose of the component and all child components
3260   *
3261   * @method dispose
3262   */
3263
3264  Component.prototype.dispose = function dispose() {
3265    this.trigger({ type: 'dispose', bubbles: false });
3266
3267    // Dispose all children.
3268    if (this.children_) {
3269      for (var i = this.children_.length - 1; i >= 0; i--) {
3270        if (this.children_[i].dispose) {
3271          this.children_[i].dispose();
3272        }
3273      }
3274    }
3275
3276    // Delete child references
3277    this.children_ = null;
3278    this.childIndex_ = null;
3279    this.childNameIndex_ = null;
3280
3281    // Remove all event listeners.
3282    this.off();
3283
3284    // Remove element from DOM
3285    if (this.el_.parentNode) {
3286      this.el_.parentNode.removeChild(this.el_);
3287    }
3288
3289    Dom.removeElData(this.el_);
3290    this.el_ = null;
3291  };
3292
3293  /**
3294   * Return the component's player
3295   *
3296   * @return {Player}
3297   * @method player
3298   */
3299
3300  Component.prototype.player = function player() {
3301    return this.player_;
3302  };
3303
3304  /**
3305   * Deep merge of options objects
3306   * Whenever a property is an object on both options objects
3307   * the two properties will be merged using mergeOptions.
3308   *
3309   * ```js
3310   *     Parent.prototype.options_ = {
3311   *       optionSet: {
3312   *         'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },
3313   *         'childTwo': {},
3314   *         'childThree': {}
3315   *       }
3316   *     }
3317   *     newOptions = {
3318   *       optionSet: {
3319   *         'childOne': { 'foo': 'baz', 'abc': '123' }
3320   *         'childTwo': null,
3321   *         'childFour': {}
3322   *       }
3323   *     }
3324   *
3325   *     this.options(newOptions);
3326   * ```
3327   * RESULT
3328   * ```js
3329   *     {
3330   *       optionSet: {
3331   *         'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' },
3332   *         'childTwo': null, // Disabled. Won't be initialized.
3333   *         'childThree': {},
3334   *         'childFour': {}
3335   *       }
3336   *     }
3337   * ```
3338   *
3339   * @param  {Object} obj Object of new option values
3340   * @return {Object}     A NEW object of this.options_ and obj merged
3341   * @method options
3342   */
3343
3344  Component.prototype.options = function options(obj) {
3345    _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
3346
3347    if (!obj) {
3348      return this.options_;
3349    }
3350
3351    this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj);
3352    return this.options_;
3353  };
3354
3355  /**
3356   * Get the component's DOM element
3357   * ```js
3358   *     var domEl = myComponent.el();
3359   * ```
3360   *
3361   * @return {Element}
3362   * @method el
3363   */
3364
3365  Component.prototype.el = function el() {
3366    return this.el_;
3367  };
3368
3369  /**
3370   * Create the component's DOM element
3371   *
3372   * @param  {String=} tagName  Element's node type. e.g. 'div'
3373   * @param  {Object=} properties An object of properties that should be set
3374   * @param  {Object=} attributes An object of attributes that should be set
3375   * @return {Element}
3376   * @method createEl
3377   */
3378
3379  Component.prototype.createEl = function createEl(tagName, properties, attributes) {
3380    return Dom.createEl(tagName, properties, attributes);
3381  };
3382
3383  Component.prototype.localize = function localize(string) {
3384    var code = this.player_.language && this.player_.language();
3385    var languages = this.player_.languages && this.player_.languages();
3386
3387    if (!code || !languages) {
3388      return string;
3389    }
3390
3391    var language = languages[code];
3392
3393    if (language && language[string]) {
3394      return language[string];
3395    }
3396
3397    var primaryCode = code.split('-')[0];
3398    var primaryLang = languages[primaryCode];
3399
3400    if (primaryLang && primaryLang[string]) {
3401      return primaryLang[string];
3402    }
3403
3404    return string;
3405  };
3406
3407  /**
3408   * Return the component's DOM element where children are inserted.
3409   * Will either be the same as el() or a new element defined in createEl().
3410   *
3411   * @return {Element}
3412   * @method contentEl
3413   */
3414
3415  Component.prototype.contentEl = function contentEl() {
3416    return this.contentEl_ || this.el_;
3417  };
3418
3419  /**
3420   * Get the component's ID
3421   * ```js
3422   *     var id = myComponent.id();
3423   * ```
3424   *
3425   * @return {String}
3426   * @method id
3427   */
3428
3429  Component.prototype.id = function id() {
3430    return this.id_;
3431  };
3432
3433  /**
3434   * Get the component's name. The name is often used to reference the component.
3435   * ```js
3436   *     var name = myComponent.name();
3437   * ```
3438   *
3439   * @return {String}
3440   * @method name
3441   */
3442
3443  Component.prototype.name = function name() {
3444    return this.name_;
3445  };
3446
3447  /**
3448   * Get an array of all child components
3449   * ```js
3450   *     var kids = myComponent.children();
3451   * ```
3452   *
3453   * @return {Array} The children
3454   * @method children
3455   */
3456
3457  Component.prototype.children = function children() {
3458    return this.children_;
3459  };
3460
3461  /**
3462   * Returns a child component with the provided ID
3463   *
3464   * @return {Component}
3465   * @method getChildById
3466   */
3467
3468  Component.prototype.getChildById = function getChildById(id) {
3469    return this.childIndex_[id];
3470  };
3471
3472  /**
3473   * Returns a child component with the provided name
3474   *
3475   * @return {Component}
3476   * @method getChild
3477   */
3478
3479  Component.prototype.getChild = function getChild(name) {
3480    return this.childNameIndex_[name];
3481  };
3482
3483  /**
3484   * Adds a child component inside this component
3485   * ```js
3486   *     myComponent.el();
3487   *     // -> <div class='my-component'></div>
3488   *     myComponent.children();
3489   *     // [empty array]
3490   *
3491   *     var myButton = myComponent.addChild('MyButton');
3492   *     // -> <div class='my-component'><div class="my-button">myButton<div></div>
3493   *     // -> myButton === myComponent.children()[0];
3494   * ```
3495   * Pass in options for child constructors and options for children of the child
3496   * ```js
3497   *     var myButton = myComponent.addChild('MyButton', {
3498   *       text: 'Press Me',
3499   *       buttonChildExample: {
3500   *         buttonChildOption: true
3501   *       }
3502   *     });
3503   * ```
3504   *
3505   * @param {String|Component} child The class name or instance of a child to add
3506   * @param {Object=} options Options, including options to be passed to children of the child.
3507   * @param {Number} index into our children array to attempt to add the child
3508   * @return {Component} The child component (created by this process if a string was used)
3509   * @method addChild
3510   */
3511
3512  Component.prototype.addChild = function addChild(child) {
3513    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
3514    var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2];
3515
3516    var component = undefined;
3517    var componentName = undefined;
3518
3519    // If child is a string, create nt with options
3520    if (typeof child === 'string') {
3521      componentName = child;
3522
3523      // Options can also be specified as a boolean, so convert to an empty object if false.
3524      if (!options) {
3525        options = {};
3526      }
3527
3528      // Same as above, but true is deprecated so show a warning.
3529      if (options === true) {
3530        _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`.');
3531        options = {};
3532      }
3533
3534      // If no componentClass in options, assume componentClass is the name lowercased
3535      // (e.g. playButton)
3536      var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName);
3537
3538      // Set name through options
3539      options.name = componentName;
3540
3541      // Create a new object & element for this controls set
3542      // If there's no .player_, this is a player
3543      var ComponentClass = Component.getComponent(componentClassName);
3544
3545      if (!ComponentClass) {
3546        throw new Error('Component ' + componentClassName + ' does not exist');
3547      }
3548
3549      // data stored directly on the videojs object may be
3550      // misidentified as a component to retain
3551      // backwards-compatibility with 4.x. check to make sure the
3552      // component class can be instantiated.
3553      if (typeof ComponentClass !== 'function') {
3554        return null;
3555      }
3556
3557      component = new ComponentClass(this.player_ || this, options);
3558
3559      // child is a component instance
3560    } else {
3561        component = child;
3562      }
3563
3564    this.children_.splice(index, 0, component);
3565
3566    if (typeof component.id === 'function') {
3567      this.childIndex_[component.id()] = component;
3568    }
3569
3570    // If a name wasn't used to create the component, check if we can use the
3571    // name function of the component
3572    componentName = componentName || component.name && component.name();
3573
3574    if (componentName) {
3575      this.childNameIndex_[componentName] = component;
3576    }
3577
3578    // Add the UI object's element to the container div (box)
3579    // Having an element is not required
3580    if (typeof component.el === 'function' && component.el()) {
3581      var childNodes = this.contentEl().children;
vendor: 5,718 bytes, lines 3582-3765
3582      var refNode = childNodes[index] || null;
3583      this.contentEl().insertBefore(component.el(), refNode);
3584    }
3585
3586    // Return so it can stored on parent object if desired.
3587    return component;
3588  };
3589
3590  /**
3591   * Remove a child component from this component's list of children, and the
3592   * child component's element from this component's element
3593   *
3594   * @param  {Component} component Component to remove
3595   * @method removeChild
3596   */
3597
3598  Component.prototype.removeChild = function removeChild(component) {
3599    if (typeof component === 'string') {
3600      component = this.getChild(component);
3601    }
3602
3603    if (!component || !this.children_) {
3604      return;
3605    }
3606
3607    var childFound = false;
3608
3609    for (var i = this.children_.length - 1; i >= 0; i--) {
3610      if (this.children_[i] === component) {
3611        childFound = true;
3612        this.children_.splice(i, 1);
3613        break;
3614      }
3615    }
3616
3617    if (!childFound) {
3618      return;
3619    }
3620
3621    this.childIndex_[component.id()] = null;
3622    this.childNameIndex_[component.name()] = null;
3623
3624    var compEl = component.el();
3625
3626    if (compEl && compEl.parentNode === this.contentEl()) {
3627      this.contentEl().removeChild(component.el());
3628    }
3629  };
3630
3631  /**
3632   * Add and initialize default child components from options
3633   * ```js
3634   *     // when an instance of MyComponent is created, all children in options
3635   *     // will be added to the instance by their name strings and options
3636   *     MyComponent.prototype.options_ = {
3637   *       children: [
3638   *         'myChildComponent'
3639   *       ],
3640   *       myChildComponent: {
3641   *         myChildOption: true
3642   *       }
3643   *     };
3644   *
3645   *     // Or when creating the component
3646   *     var myComp = new MyComponent(player, {
3647   *       children: [
3648   *         'myChildComponent'
3649   *       ],
3650   *       myChildComponent: {
3651   *         myChildOption: true
3652   *       }
3653   *     });
3654   * ```
3655   * The children option can also be an array of
3656   * child options objects (that also include a 'name' key).
3657   * This can be used if you have two child components of the
3658   * same type that need different options.
3659   * ```js
3660   *     var myComp = new MyComponent(player, {
3661   *       children: [
3662   *         'button',
3663   *         {
3664   *           name: 'button',
3665   *           someOtherOption: true
3666   *         },
3667   *         {
3668   *           name: 'button',
3669   *           someOtherOption: false
3670   *         }
3671   *       ]
3672   *     });
3673   * ```
3674   *
3675   * @method initChildren
3676   */
3677
3678  Component.prototype.initChildren = function initChildren() {
3679    var _this = this;
3680
3681    var children = this.options_.children;
3682
3683    if (children) {
3684      (function () {
3685        // `this` is `parent`
3686        var parentOptions = _this.options_;
3687
3688        var handleAdd = function handleAdd(child) {
3689          var name = child.name;
3690          var opts = child.opts;
3691
3692          // Allow options for children to be set at the parent options
3693          // e.g. videojs(id, { controlBar: false });
3694          // instead of videojs(id, { children: { controlBar: false });
3695          if (parentOptions[name] !== undefined) {
3696            opts = parentOptions[name];
3697          }
3698
3699          // Allow for disabling default components
3700          // e.g. options['children']['posterImage'] = false
3701          if (opts === false) {
3702            return;
3703          }
3704
3705          // Allow options to be passed as a simple boolean if no configuration
3706          // is necessary.
3707          if (opts === true) {
3708            opts = {};
3709          }
3710
3711          // We also want to pass the original player options to each component as well so they don't need to
3712          // reach back into the player for options later.
3713          opts.playerOptions = _this.options_.playerOptions;
3714
3715          // Create and add the child component.
3716          // Add a direct reference to the child by name on the parent instance.
3717          // If two of the same component are used, different names should be supplied
3718          // for each
3719          var newChild = _this.addChild(name, opts);
3720          if (newChild) {
3721            _this[name] = newChild;
3722          }
3723        };
3724
3725        // Allow for an array of children details to passed in the options
3726        var workingChildren = undefined;
3727        var Tech = Component.getComponent('Tech');
3728
3729        if (Array.isArray(children)) {
3730          workingChildren = children;
3731        } else {
3732          workingChildren = Object.keys(children);
3733        }
3734
3735        workingChildren
3736        // children that are in this.options_ but also in workingChildren  would
3737        // give us extra children we do not want. So, we want to filter them out.
3738        .concat(Object.keys(_this.options_).filter(function (child) {
3739          return !workingChildren.some(function (wchild) {
3740            if (typeof wchild === 'string') {
3741              return child === wchild;
3742            } else {
3743              return child === wchild.name;
3744            }
3745          });
3746        })).map(function (child) {
3747          var name = undefined,
3748              opts = undefined;
3749
3750          if (typeof child === 'string') {
3751            name = child;
3752            opts = children[name] || _this.options_[name] || {};
3753          } else {
3754            name = child.name;
3755            opts = child;
3756          }
3757
3758          return { name: name, opts: opts };
3759        }).filter(function (child) {
3760          // we have to make sure that child.name isn't in the techOrder since
3761          // techs are registerd as Components but can't aren't compatible
3762          // See https://github.com/videojs/video.js/issues/2772
3763          var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name));
3764          return c && !Tech.isTech(c);
3765        }
3765).forEach(handleAdd);
3766      })();
3767    }
3768  };
3769
3770  /**
3771   * Allows sub components to stack CSS class names
3772   *
3773   * @return {String} The constructed class name
3774   * @method buildCSSClass
3775   */
3776
3777  Component.prototype.buildCSSClass = function buildCSSClass() {
3778    // Child classes can include a function that does:
3779    // return 'CLASS NAME' + this._super();
3780    return '';
3781  };
3782
3783  /**
3784   * Add an event listener to this component's element
3785   * ```js
3786   *     var myFunc = function(){
3787   *       var myComponent = this;
3788   *       // Do something when the event is fired
3789   *     };
3790   *
3791   *     myComponent.on('eventType', myFunc);
3792   * ```
3793   * The context of myFunc will be myComponent unless previously bound.
3794   * Alternatively, you can add a listener to another element or component.
3795   * ```js
3796   *     myComponent.on(otherElement, 'eventName', myFunc);
3797   *     myComponent.on(otherComponent, 'eventName', myFunc);
3798   * ```
3799   * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)`
3800   * and `otherComponent.on('eventName', myFunc)` is that this way the listeners
3801   * will be automatically cleaned up when either component is disposed.
3802   * It will also bind myComponent as the context of myFunc.
3803   * **NOTE**: When using this on elements in the page other than window
3804   * and document (both permanent), if you remove the element from the DOM
3805   * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up
3806   * references to it and allow the browser to garbage collect it.
3807   *
3808   * @param  {String|Component} first   The event type or other component
3809   * @param  {Function|String}      second  The event handler or event type
3810   * @param  {Function}             third   The event handler
3811   * @return {Component}
3812   * @method on
3813   */
3814
3815  Component.prototype.on = function on(first, second, third) {
3816    var _this2 = this;
3817
3818    if (typeof first === 'string' || Array.isArray(first)) {
3819      Events.on(this.el_, first, Fn.bind(this, second));
3820
3821      // Targeting another component or element
3822    } else {
3823        (function () {
3824          var target = first;
3825          var type = second;
3826          var fn = Fn.bind(_this2, third);
3827
3828          // When this component is disposed, remove the listener from the other component
3829          var removeOnDispose = function removeOnDispose() {
3830            return _this2.off(target, type, fn);
3831          };
3832
3833          // Use the same function ID so we can remove it later it using the ID
3834          // of the original listener
3835          removeOnDispose.guid = fn.guid;
3836          _this2.on('dispose', removeOnDispose);
3837
3838          // If the other component is disposed first we need to clean the reference
3839          // to the other component in this component's removeOnDispose listener
3840          // Otherwise we create a memory leak.
3841          var cleanRemover = function cleanRemover() {
3842            return _this2.off('dispose', removeOnDispose);
3843          };
3844
3845          // Add the same function ID so we can easily remove it later
3846          cleanRemover.guid = fn.guid;
3847
3848          // Check if this is a DOM node
3849          if (first.nodeName) {
3850            // Add the listener to the other element
3851            Events.on(target, type, fn);
3852            Events.on(target, 'dispose', cleanRemover);
3853
3854            // Should be a component
3855            // Not using `instanceof Component` because it makes mock players difficult
3856          } else if (typeof first.on === 'function') {
3857              // Add the listener to the other component
3858              target.on(type, fn);
3859              target.on('dispose', cleanRemover);
3860            }
3861        })();
3862      }
3863
3864    return this;
3865  };
3866
3867  /**
3868   * Remove an event listener from this component's element
3869   * ```js
3870   *     myComponent.off('eventType', myFunc);
3871   * ```
3872   * If myFunc is excluded, ALL listeners for the event type will be removed.
3873   * If eventType is excluded, ALL listeners will be removed from the component.
3874   * Alternatively you can use `off` to remove listeners that were added to other
3875   * elements or components using `myComponent.on(otherComponent...`.
3876   * In this case both the event type and listener function are REQUIRED.
3877   * ```js
3878   *     myComponent.off(otherElement, 'eventType', myFunc);
3879   *     myComponent.off(otherComponent, 'eventType', myFunc);
3880   * ```
3881   *
3882   * @param  {String=|Component}  first  The event type or other component
3883   * @param  {Function=|String}       second The listener function or event type
3884   * @param  {Function=}              third  The listener for other component
3885   * @return {Component}
3886   * @method off
3887   */
3888
3889  Component.prototype.off = function off(first, second, third) {
3890    if (!first || typeof first === 'string' || Array.isArray(first)) {
3891      Events.off(this.el_, first, second);
3892    } else {
3893      var target = first;
3894      var type = second;
3895      // Ensure there's at least a guid, even if the function hasn't been used
3896      var fn = Fn.bind(this, third);
3897
3898      // Remove the dispose listener on this component,
3899      // which was given the same guid as the event listener
3900      this.off('dispose', fn);
3901
3902      if (first.nodeName) {
3903        // Remove the listener
3904        Events.off(target, type, fn);
3905        // Remove the listener for cleaning the dispose listener
3906        Events.off(target, 'dispose', fn);
3907      } else {
3908        target.off(type, fn);
3909        target.off('dispose', fn);
3910      }
3911    }
3912
3913    return this;
3914  };
3915
3916  /**
3917   * Add an event listener to be triggered only once and then removed
3918   * ```js
3919   *     myComponent.one('eventName', myFunc);
3920   * ```
3921   * Alternatively you can add a listener to another element or component
3922   * that will be triggered only once.
3923   * ```js
3924   *     myComponent.one(otherElement, 'eventName', myFunc);
3925   *     myComponent.one(otherComponent, 'eventName', myFunc);
3926   * ```
3927   *
3928   * @param  {String|Component}  first   The event type or other component
3929   * @param  {Function|String}       second  The listener function or event type
3930   * @param  {Function=}             third   The listener function for other component
3931   * @return {Component}
3932   * @method one
3933   */
3934
3935  Component.prototype.one = function one(first, second, third) {
3936    var _this3 = this,
3937        _arguments = arguments;
3938
3939    if (typeof first === 'string' || Array.isArray(first)) {
3940      Events.one(this.el_, first, Fn.bind(this, second));
3941    } else {
3942      (function () {
3943        var target = first;
3944        var type = second;
3945        var fn = Fn.bind(_this3, third);
3946
3947        var newFunc = function newFunc() {
3948          _this3.off(target, type, newFunc);
3949          fn.apply(null, _arguments);
3950        };
3951
3952        // Keep the same function ID so we can remove it later
3953        newFunc.guid = fn.guid;
3954
3955        _this3.on(target, type, newFunc);
3956      })();
3957    }
3958
3959    return this;
3960  };
3961
3962  /**
3963   * Trigger an event on an element
3964   * ```js
3965   *     myComponent.trigger('eventName');
3966   *     myComponent.trigger({'type':'eventName'});
3967   *     myComponent.trigger('eventName', {data: 'some data'});
3968   *     myComponent.trigger({'type':'eventName'}, {data: 'some data'});
3969   * ```
3970   *
3971   * @param  {Event|Object|String} event  A string (the type) or an event object with a type attribute
3972   * @param  {Object} [hash] data hash to pass along with the event
3973   * @return {Component}       self
3974   * @method trigger
3975   */
3976
3977  Component.prototype.trigger = function trigger(event, hash) {
3978    Events.trigger(this.el_, event, hash);
3979    return this;
3980  };
3981
3982  /**
3983   * Bind a listener to the component's ready state.
3984   * Different from event listeners in that if the ready event has already happened
3985   * it will trigger the function immediately.
3986   *
3987   * @param  {Function} fn Ready listener
3988   * @param  {Boolean} sync Exec the listener synchronously if component is ready
3989   * @return {Component}
3990   * @method ready
3991   */
3992
3993  Component.prototype.ready = function ready(fn) {
3994    var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
3995
3996    if (fn) {
3997      if (this.isReady_) {
3998        if (sync) {
3999          fn.call(this);
4000        } else {
4001          // Call the function asynchronously by default for consistency
4002          this.setTimeout(fn, 1);
4003        }
4004      } else {
4005        this.readyQueue_ = this.readyQueue_ || [];
4006        this.readyQueue_.push(fn);
4007      }
4008    }
4009    return this;
4010  };
4011
4012  /**
4013   * Trigger the ready listeners
4014   *
4015   * @return {Component}
4016   * @method triggerReady
4017   */
4018
4019  Component.prototype.triggerReady = function triggerReady() {
4020    this.isReady_ = true;
4021
4022    // Ensure ready is triggerd asynchronously
4023    this.setTimeout(function () {
4024      var readyQueue = this.readyQueue_;
4025
4026      // Reset Ready Queue
4027      this.readyQueue_ = [];
4028
4029      if (readyQueue && readyQueue.length > 0) {
4030        readyQueue.forEach(function (fn) {
4031          fn.call(this);
4032        }, this);
4033      }
4034
4035      // Allow for using event listeners also
4036      this.trigger('ready');
4037    }, 1);
4038  };
4039
4040  /**
4041   * Finds a single DOM element matching `selector` within the component's
4042   * `contentEl` or another custom context.
4043   *
4044   * @method $
4045   * @param  {String} selector
4046   *         A valid CSS selector, which will be passed to `querySelector`.
4047   *
4048   * @param  {Element|String} [context=document]
4049   *         A DOM element within which to query. Can also be a selector
4050   *         string in which case the first matching element will be used
4051   *         as context. If missing (or no element matches selector), falls
4052   *         back to `document`.
4053   *
4054   * @return {Element|null}
4055   */
4056
4057  Component.prototype.$ = function $(selector, context) {
4058    return Dom.$(selector, context || this.contentEl());
4059  };
4060
4061  /**
4062   * Finds a all DOM elements matching `selector` within the component's
4063   * `contentEl` or another custom context.
4064   *
4065   * @method $$
4066   * @param  {String} selector
4067   *         A valid CSS selector, which will be passed to `querySelectorAll`.
4068   *
4069   * @param  {Element|String} [context=document]
4070   *         A DOM element within which to query. Can also be a selector
4071   *         string in which case the first matching element will be used
4072   *         as context. If missing (or no element matches selector), falls
4073   *         back to `document`.
4074   *
4075   * @return {NodeList}
4076   */
4077
4078  Component.prototype.$$ = function $$(selector, context) {
4079    return Dom.$$(selector, context || this.contentEl());
4080  };
4081
4082  /**
4083   * Check if a component's element has a CSS class name
4084   *
4085   * @param {String} classToCheck Classname to check
4086   * @return {Component}
4087   * @method hasClass
4088   */
4089
4090  Component.prototype.hasClass = function hasClass(classToCheck) {
4091    return Dom.hasElClass(this.el_, classToCheck);
4092  };
4093
4094  /**
4095   * Add a CSS class name to the component's element
4096   *
4097   * @param {String} classToAdd Classname to add
4098   * @return {Component}
4099   * @method addClass
4100   */
4101
4102  Component.prototype.addClass = function addClass(classToAdd) {
4103    Dom.addElClass(this.el_, classToAdd);
4104    return this;
4105  };
4106
4107  /**
4108   * Remove a CSS class name from the component's element
4109   *
4110   * @param {String} classToRemove Classname to remove
4111   * @return {Component}
4112   * @method removeClass
4113   */
4114
4115  Component.prototype.removeClass = function removeClass(classToRemove) {
4116    Dom.removeElClass(this.el_, classToRemove);
4117    return this;
4118  };
4119
4120  /**
4121   * Add or remove a CSS class name from the component's element
4122   *
4123   * @param  {String} classToToggle
4124   * @param  {Boolean|Function} [predicate]
4125   *         Can be a function that returns a Boolean. If `true`, the class
4126   *         will be added; if `false`, the class will be removed. If not
4127   *         given, the class will be added if not present and vice versa.
4128   *
4129   * @return {Component}
4130   * @method toggleClass
4131   */
4132
4133  Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
4134    Dom.toggleElClass(this.el_, classToToggle, predicate);
4135    return this;
4136  };
4137
4138  /**
4139   * Show the component element if hidden
4140   *
4141   * @return {Component}
4142   * @method show
4143   */
4144
4145  Component.prototype.show = function show() {
4146    this.removeClass('vjs-hidden');
4147    return this;
4148  };
4149
4150  /**
4151   * Hide the component element if currently showing
4152   *
4153   * @return {Component}
4154   * @method hide
4155   */
4156
4157  Component.prototype.hide = function hide() {
4158    this.addClass('vjs-hidden');
4159    return this;
4160  };
4161
4162  /**
4163   * Lock an item in its visible state
4164   * To be used with fadeIn/fadeOut.
4165   *
4166   * @return {Component}
4167   * @private
4168   * @method lockShowing
4169   */
4170
4171  Component.prototype.lockShowing = function lockShowing() {
4172    this.addClass('vjs-lock-showing');
4173    return this;
4174  };
4175
4176  /**
4177   * Unlock an item to be hidden
4178   * To be used with fadeIn/fadeOut.
4179   *
4180   * @return {Component}
4181   * @private
4182   * @method unlockShowing
4183   */
4184
4185  Component.prototype.unlockShowing = function unlockShowing() {
4186    this.removeClass('vjs-lock-showing');
4187    return this;
4188  };
4189
4190  /**
4191   * Set or get the width of the component (CSS values)
4192   * Setting the video tag dimension values only works with values in pixels.
4193   * Percent values will not work.
4194   * Some percents can be used, but width()/height() will return the number + %,
4195   * not the actual computed width/height.
4196   *
4197   * @param  {Number|String=} num   Optional width number
4198   * @param  {Boolean} skipListeners Skip the 'resize' event trigger
4199   * @return {Component} This component, when setting the width
4200   * @return {Number|String} The width, when getting
4201   * @method width
4202   */
4203
4204  Component.prototype.width = function width(num, skipListeners) {
4205    return this.dimension('width', num, skipListeners);
4206  };
4207
4208  /**
4209   * Get or set the height of the component (CSS values)
4210   * Setting the video tag dimension values only works with values in pixels.
4211   * Percent values will not work.
4212   * Some percents can be used, but width()/height() will return the number + %,
4213   * not the actual computed width/height.
4214   *
4215   * @param  {Number|String=} num     New component height
4216   * @param  {Boolean=} skipListeners Skip the resize event trigger
4217   * @return {Component} This component, when setting the height
4218   * @return {Number|String} The height, when getting
4219   * @method height
4220   */
4221
4222  Component.prototype.height = function height(num, skipListeners) {
4223    return this.dimension('height', num, skipListeners);
4224  };
4225
4226  /**
4227   * Set both width and height at the same time
4228   *
4229   * @param  {Number|String} width Width of player
4230   * @param  {Number|String} height Height of player
4231   * @return {Component} The component
4232   * @method dimensions
4233   */
4234
4235  Component.prototype.dimensions = function dimensions(width, height) {
4236    // Skip resize listeners on width for optimization
4237    return this.width(width, true).height(height);
4238  };
4239
4240  /**
4241   * Get or set width or height
4242   * This is the shared code for the width() and height() methods.
4243   * All for an integer, integer + 'px' or integer + '%';
4244   * Known issue: Hidden elements officially have a width of 0. We're defaulting
4245   * to the style.width value and falling back to computedStyle which has the
4246   * hidden element issue. Info, but probably not an efficient fix:
4247   * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/
4248   *
4249   * @param  {String} widthOrHeight  'width' or 'height'
4250   * @param  {Number|String=} num     New dimension
4251   * @param  {Boolean=} skipListeners Skip resize event trigger
4252   * @return {Component} The component if a dimension was set
4253   * @return {Number|String} The dimension if nothing was set
4254   * @private
4255   * @method dimension
4256   */
4257
4258  Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
4259    if (num !== undefined) {
4260      // Set to zero if null or literally NaN (NaN !== NaN)
4261      if (num === null || num !== num) {
4262        num = 0;
4263      }
4264
4265      // Check if using css width/height (% or px) and adjust
4266      if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
4267        this.el_.style[widthOrHeight] = num;
4268      } else if (num === 'auto') {
4269        this.el_.style[widthOrHeight] = '';
4270      } else {
4271        this.el_.style[widthOrHeight] = num + 'px';
4272      }
4273
4274      // skipListeners allows us to avoid triggering the resize event when setting both width and height
4275      if (!skipListeners) {
4276        this.trigger('resize');
4277      }
4278
4279      // Return component
4280      return this;
4281    }
4282
4283    // Not setting a value, so getting it
4284    // Make sure element exists
4285    if (!this.el_) {
4286      return 0;
4287    }
4288
4289    // Get dimension value from style
4290    var val = this.el_.style[widthOrHeight];
4291    var pxIndex = val.indexOf('px');
4292
4293    if (pxIndex !== -1) {
4294      // Return the pixel value with no 'px'
4295      return parseInt(val.slice(0, pxIndex), 10);
4296    }
4297
4298    // No px so using % or no style was set, so falling back to offsetWidth/height
4299    // If component has display:none, offset will return 0
4300    // TODO: handle display:none and no dimension style using px
4301    return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10);
4302  };
4303
4304  /**
4305   * Emit 'tap' events when touch events are supported
4306   * This is used to support toggling the controls through a tap on the video.
4307   * We're requiring them to be enabled because otherwise every component would
4308   * have this extra overhead unnecessarily, on mobile devices where extra
4309   * overhead is especially bad.
4310   *
4311   * @private
4312   * @method emitTapEvents
4313   */
4314
4315  Component.prototype.emitTapEvents = function emitTapEvents() {
4316    // Track the start time so we can determine how long the touch lasted
4317    var touchStart = 0;
4318    var firstTouch = null;
4319
4320    // Maximum movement allowed during a touch event to still be considered a tap
4321    // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
4322    var tapMovementThreshold = 10;
4323
4324    // The maximum length a touch can be while still being considered a tap
4325    var touchTimeThreshold = 200;
4326
4327    var couldBeTap = undefined;
4328
4329    this.on('touchstart', function (event) {
4330      // If more than one finger, don't consider treating this as a click
4331      if (event.touches.length === 1) {
4332        // Copy the touches object to prevent modifying the original
4333        firstTouch = _objectAssign2['default']({}, event.touches[0]);
4334        // Record start time so we can detect a tap vs. "touch and hold"
4335        touchStart = new Date().getTime();
4336        // Reset couldBeTap tracking
4337        couldBeTap = true;
4338      }
4339    });
4340
4341    this.on('touchmove', function (event) {
4342      // If more than one finger, don't consider treating this as a click
4343      if (event.touches.length > 1) {
4344        couldBeTap = false;
vendor: 4,486 bytes, lines 4345-4454
4345      } else if (firstTouch) {
4346        // Some devices will throw touchmoves for all but the slightest of taps.
4347        // So, if we moved only a small distance, this could still be a tap
4348        var xdiff = event.touches[0].pageX - firstTouch.pageX;
4349        var ydiff = event.touches[0].pageY - firstTouch.pageY;
4350        var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
4351
4352        if (touchDistance > tapMovementThreshold) {
4353          couldBeTap = false;
4354        }
4355      }
4356    });
4357
4358    var noTap = function noTap() {
4359      couldBeTap = false;
4360    };
4361
4362    // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
4363    this.on('touchleave', noTap);
4364    this.on('touchcancel', noTap);
4365
4366    // When the touch ends, measure how long it took and trigger the appropriate
4367    // event
4368    this.on('touchend', function (event) {
4369      firstTouch = null;
4370      // Proceed only if the touchmove/leave/cancel event didn't happen
4371      if (couldBeTap === true) {
4372        // Measure how long the touch lasted
4373        var touchTime = new Date().getTime() - touchStart;
4374
4375        // Make sure the touch was less than the threshold to be considered a tap
4376        if (touchTime < touchTimeThreshold) {
4377          // Don't let browser turn this into a click
4378          event.preventDefault();
4379          this.trigger('tap');
4380          // It may be good to copy the touchend event object and change the
4381          // type to tap, if the other event properties aren't exact after
4382          // Events.fixEvent runs (e.g. event.target)
4383        }
4384      }
4385    });
4386  };
4387
4388  /**
4389   * Report user touch activity when touch events occur
4390   * User activity is used to determine when controls should show/hide. It's
4391   * relatively simple when it comes to mouse events, because any mouse event
4392   * should show the controls. So we capture mouse events that bubble up to the
4393   * player and report activity when that happens.
4394   * With touch events it isn't as easy. We can't rely on touch events at the
4395   * player level, because a tap (touchstart + touchend) on the video itself on
4396   * mobile devices is meant to turn controls off (and on). User activity is
4397   * checked asynchronously, so what could happen is a tap event on the video
4398   * turns the controls off, then the touchend event bubbles up to the player,
4399   * which if it reported user activity, would turn the controls right back on.
4400   * (We also don't want to completely block touch events from bubbling up)
4401   * Also a touchmove, touch+hold, and anything other than a tap is not supposed
4402   * to turn the controls back on on a mobile device.
4403   * Here we're setting the default component behavior to report user activity
4404   * whenever touch events happen, and this can be turned off by components that
4405   * want touch events to act differently.
4406   *
4407   * @method enableTouchActivity
4408   */
4409
4410  Component.prototype.enableTouchActivity = function enableTouchActivity() {
4411    // Don't continue if the root player doesn't support reporting user activity
4412    if (!this.player() || !this.player().reportUserActivity) {
4413      return;
4414    }
4415
4416    // listener for reporting that the user is active
4417    var report = Fn.bind(this.player(), this.player().reportUserActivity);
4418
4419    var touchHolding = undefined;
4420
4421    this.on('touchstart', function () {
4422      report();
4423      // For as long as the they are touching the device or have their mouse down,
4424      // we consider them active even if they're not moving their finger or mouse.
4425      // So we want to continue to update that they are active
4426      this.clearInterval(touchHolding);
4427      // report at the same interval as activityCheck
4428      touchHolding = this.setInterval(report, 250);
4429    });
4430
4431    var touchEnd = function touchEnd(event) {
4432      report();
4433      // stop the interval that maintains activity if the touch is holding
4434      this.clearInterval(touchHolding);
4435    };
4436
4437    this.on('touchmove', report);
4438    this.on('touchend', touchEnd);
4439    this.on('touchcancel', touchEnd);
4440  };
4441
4442  /**
4443   * Creates timeout and sets up disposal automatically.
4444   *
4445   * @param {Function} fn The function to run after the timeout.
4446   * @param {Number} timeout Number of ms to delay before executing specified function.
4447   * @return {Number} Returns the timeout ID
4448   * @method setTimeout
4449   */
4450
4451  Component.prototype.setTimeout = function setTimeout(fn, timeout) {
4452    fn = Fn.bind(this, fn);
4453
4454    // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/
4454or Phantomjs, we can't.
4455    var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout);
4456
4457    var disposeFn = function disposeFn() {
4458      this.clearTimeout(timeoutId);
4459    };
4460
4461    disposeFn.guid = 'vjs-timeout-' + timeoutId;
4462
4463    this.on('dispose', disposeFn);
4464
4465    return timeoutId;
4466  };
4467
4468  /**
4469   * Clears a timeout and removes the associated dispose listener
4470   *
4471   * @param {Number} timeoutId The id of the timeout to clear
4472   * @return {Number} Returns the timeout ID
4473   * @method clearTimeout
4474   */
4475
4476  Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
4477    _globalWindow2['default'].clearTimeout(timeoutId);
4478
4479    var disposeFn = function disposeFn() {};
4480
4481    disposeFn.guid = 'vjs-timeout-' + timeoutId;
4482
4483    this.off('dispose', disposeFn);
4484
4485    return timeoutId;
4486  };
4487
4488  /**
4489   * Creates an interval and sets up disposal automatically.
4490   *
4491   * @param {Function} fn The function to run every N seconds.
4492   * @param {Number} interval Number of ms to delay before executing specified function.
4493   * @return {Number} Returns the interval ID
4494   * @method setInterval
4495   */
4496
4497  Component.prototype.setInterval = function setInterval(fn, interval) {
4498    fn = Fn.bind(this, fn);
4499
4500    var intervalId = _globalWindow2['default'].setInterval(fn, interval);
4501
4502    var disposeFn = function disposeFn() {
4503      this.clearInterval(intervalId);
4504    };
4505
4506    disposeFn.guid = 'vjs-interval-' + intervalId;
4507
4508    this.on('dispose', disposeFn);
4509
4510    return intervalId;
4511  };
4512
4513  /**
4514   * Clears an interval and removes the associated dispose listener
4515   *
4516   * @param {Number} intervalId The id of the interval to clear
4517   * @return {Number} Returns the interval ID
4518   * @method clearInterval
4519   */
4520
4521  Component.prototype.clearInterval = function clearInterval(intervalId) {
4522    _globalWindow2['default'].clearInterval(intervalId);
4523
4524    var disposeFn = function disposeFn() {};
4525
4526    disposeFn.guid = 'vjs-interval-' + intervalId;
4527
4528    this.off('dispose', disposeFn);
4529
4530    return intervalId;
4531  };
4532
4533  /**
4534   * Registers a component
4535   *
4536   * @param {String} name Name of the component to register
4537   * @param {Object} comp The component to register
4538   * @static
4539   * @method registerComponent
4540   */
4541
4542  Component.registerComponent = function registerComponent(name, comp) {
4543    if (!Component.components_) {
4544      Component.components_ = {};
4545    }
4546
4547    Component.components_[name] = comp;
4548    return comp;
4549  };
4550
4551  /**
4552   * Gets a component by name
4553   *
4554   * @param {String} name Name of the component to get
4555   * @return {Component}
4556   * @static
4557   * @method getComponent
4558   */
4559
4560  Component.getComponent = function getComponent(name) {
4561    if (Component.components_ && Component.components_[name]) {
4562      return Component.components_[name];
4563    }
4564
4565    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
4566      _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
4567      return _globalWindow2['default'].videojs[name];
4568    }
4569  };
4570
4571  /**
4572   * Sets up the constructor using the supplied init method
4573   * or uses the init of the parent object
4574   *
4575   * @param {Object} props An object of properties
4576   * @static
4577   * @deprecated
4578   * @method extend
4579   */
4580
4581  Component.extend = function extend(props) {
4582    props = props || {};
4583
4584    _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead');
4585
4586    // Set up the constructor using the supplied init method
4587    // or using the init of the parent object
4588    // Make sure to check the unobfuscated version for external libs
4589    var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
4590    // In Resig's simple class inheritance (previously used) the constructor
4591    //  is a function that calls `this.init.apply(arguments)`
4592    // However that would prevent us from using `ParentObject.call(this);`
4593    //  in a Child constructor because the `this` in `this.init`
4594    //  would still refer to the Child and cause an infinite loop.
4595    // We would instead have to do
4596    //    `ParentObject.prototype.init.apply(this, arguments);`
4597    //  Bleh. We're not creating a _super() function, so it's good to keep
4598    //  the parent constructor reference simple.
4599    var subObj = function subObj() {
4600      init.apply(this, arguments);
4601    };
4602
4603    // Inherit from this object's prototype
4604    subObj.prototype = Object.create(this.prototype);
4605    // Reset the constructor property for subObj otherwise
4606    // instances of subObj would have the constructor of the parent Object
4607    subObj.prototype.constructor = subObj;
4608
4609    // Make the class extendable
4610    subObj.extend = Component.extend;
4611
4612    // Extend subObj's prototype with functions and other properties from props
4613    for (var _name in props) {
4614      if (props.hasOwnProperty(_name)) {
4615        subObj.prototype[_name] = props[_name];
4616      }
4617    }
4618
4619    return subObj;
4620  };
4621
4622  return Component;
4623})();
4624
4625Component.registerComponent('Component', Component);
4626exports['default'] = Component;
4627module.exports = exports['default'];
4628
4629},{"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/guid.js":135,"./utils/log.js":136,"./utils/merge-options.js":137,"./utils/to-title-case.js":140,"global/window":2,"object.assign":45}],67:[function(_dereq_,module,exports){
4630/**
4631 * @file control-bar.js
4632 */
4633'use strict';
4634
4635exports.__esModule = true;
4636
4637function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4638
4639function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4640
4641function _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; }
4642
4643var _componentJs = _dereq_('../component.js');
4644
4645var _componentJs2 = _interopRequireDefault(_componentJs);
4646
4647// Required children
4648
4649var _playToggleJs = _dereq_('./play-toggle.js');
4650
4651var _playToggleJs2 = _interopRequireDefault(_playToggleJs);
4652
4653var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js');
4654
4655var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs);
4656
4657var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js');
4658
4659var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs);
4660
4661var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js');
4662
4663var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs);
4664
4665var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-controls/remaining-time-display.js');
4666
4667var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs);
4668
4669var _liveDisplayJs = _dereq_('./live-display.js');
4670
4671var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs);
4672
4673var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js');
4674
4675var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs);
4676
4677var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js');
4678
4679var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs);
4680
4681var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js');
4682
4683var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs);
4684
4685var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js');
4686
4687var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs);
4688
4689var _muteToggleJs = _dereq_('./mute-toggle.js');
4690
4691var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
4692
4693var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js');
4694
4695var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChapter
4695sButtonJs);
4696
4697var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js');
4698
4699var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs);
4700
4701var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js');
4702
4703var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs);
4704
4705var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js');
4706
4707var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs);
4708
4709var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js');
4710
4711var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs);
4712
4713/**
4714 * Container of main controls
4715 *
4716 * @extends Component
4717 * @class ControlBar
4718 */
4719
4720var ControlBar = (function (_Component) {
4721  _inherits(ControlBar, _Component);
4722
4723  function ControlBar() {
4724    _classCallCheck(this, ControlBar);
4725
4726    _Component.apply(this, arguments);
4727  }
4728
4729  /**
4730   * Create the component's DOM element
4731   *
4732   * @return {Element}
4733   * @method createEl
4734   */
4735
4736  ControlBar.prototype.createEl = function createEl() {
4737    return _Component.prototype.createEl.call(this, 'div', {
4738      className: 'vjs-control-bar'
4739    }, {
4740      'role': 'group' // The control bar is a group, so it can contain menuitems
4741    });
4742  };
4743
4744  return ControlBar;
4745})(_componentJs2['default']);
4746
4747ControlBar.prototype.options_ = {
4748  loadEvent: 'play',
4749  children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'subtitlesButton', 'captionsButton', 'fullscreenToggle']
4750};
4751
4752_componentJs2['default'].registerComponent('ControlBar', ControlBar);
4753exports['default'] = ControlBar;
4754module.exports = exports['default'];
4755
4756},{"../component.js":66,"./fullscreen-toggle.js":68,"./live-display.js":69,"./mute-toggle.js":70,"./play-toggle.js":71,"./playback-rate-menu/playback-rate-menu-button.js":72,"./progress-control/progress-control.js":77,"./spacer-controls/custom-control-spacer.js":79,"./text-track-controls/captions-button.js":82,"./text-track-controls/chapters-button.js":83,"./text-track-controls/subtitles-button.js":86,"./time-controls/current-time-display.js":89,"./time-controls/duration-display.js":90,"./time-controls/remaining-time-display.js":91,"./time-controls/time-divider.js":92,"./volume-control/volume-control.js":94,"./volume-menu-button.js":96}],68:[function(_dereq_,module,exports){
4757/**
4758 * @file fullscreen-toggle.js
4759 */
4760'use strict';
4761
4762exports.__esModule = true;
4763
4764function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4765
4766function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4767
4768function _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; }
4769
4770var _buttonJs = _dereq_('../button.js');
4771
4772var _buttonJs2 = _interopRequireDefault(_buttonJs);
4773
4774var _componentJs = _dereq_('../component.js');
4775
4776var _componentJs2 = _interopRequireDefault(_componentJs);
4777
4778/**
4779 * Toggle fullscreen video
4780 *
4781 * @extends Button
4782 * @class FullscreenToggle
4783 */
4784
4785var FullscreenToggle = (function (_Button) {
4786  _inherits(FullscreenToggle, _Button);
4787
4788  function FullscreenToggle() {
4789    _classCallCheck(this, FullscreenToggle);
4790
4791    _Button.apply(this, arguments);
4792  }
4793
4794  /**
4795   * Allow sub components to stack CSS class names
4796   *
4797   * @return {String} The constructed class name
4798   * @method buildCSSClass
4799   */
4800
4801  FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
4802    return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
4803  };
4804
4805  /**
4806   * Handles click for full screen
4807   *
4808   * @method handleClick
4809   */
4810
4811  FullscreenToggle.prototype.handleClick = function handleClick() {
4812    if (!this.player_.isFullscreen()) {
4813      this.player_.requestFullscreen();
4814      this.controlText('Non-Fullscreen');
4815    } else {
4816      this.player_.exitFullscreen();
4817      this.controlText('Fullscreen');
4818    }
4819  };
4820
4821  return FullscreenToggle;
4822})(_buttonJs2['default']);
4823
4824FullscreenToggle.prototype.controlText_ = 'Fullscreen';
4825
4826_componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
4827exports['default'] = FullscreenToggle;
4828module.exports = exports['default'];
4829
4830},{"../button.js":63,"../component.js":66}],69:[function(_dereq_,module,exports){
4831/**
4832 * @file live-display.js
4833 */
4834'use strict';
4835
4836exports.__esModule = true;
4837
4838function _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; } }
4839
4840function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4841
4842function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4843
4844function _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
4844onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
4845
4846var _component = _dereq_('../component');
4847
4848var _component2 = _interopRequireDefault(_component);
4849
4850var _utilsDomJs = _dereq_('../utils/dom.js');
4851
4852var Dom = _interopRequireWildcard(_utilsDomJs);
4853
4854/**
4855 * Displays the live indicator
4856 * TODO - Future make it click to snap to live
4857 *
4858 * @extends Component
4859 * @class LiveDisplay
4860 */
4861
4862var LiveDisplay = (function (_Component) {
4863  _inherits(LiveDisplay, _Component);
4864
4865  function LiveDisplay(player, options) {
4866    _classCallCheck(this, LiveDisplay);
4867
4868    _Component.call(this, player, options);
4869
4870    this.updateShowing();
4871    this.on(this.player(), 'durationchange', this.updateShowing);
4872  }
4873
4874  /**
4875   * Create the component's DOM element
4876   *
4877   * @return {Element}
4878   * @method createEl
4879   */
4880
4881  LiveDisplay.prototype.createEl = function createEl() {
4882    var el = _Component.prototype.createEl.call(this, 'div', {
4883      className: 'vjs-live-control vjs-control'
4884    });
4885
4886    this.contentEl_ = Dom.createEl('div', {
4887      className: 'vjs-live-display',
4888      innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
4889    }, {
4890      'aria-live': 'off'
4891    });
4892
4893    el.appendChild(this.contentEl_);
4894    return el;
4895  };
4896
4897  LiveDisplay.prototype.updateShowing = function updateShowing() {
4898    if (this.player().duration() === Infinity) {
4899      this.show();
4900    } else {
4901      this.hide();
4902    }
4903  };
4904
4905  return LiveDisplay;
4906})(_component2['default']);
4907
4908_component2['default'].registerComponent('LiveDisplay', LiveDisplay);
4909exports['default'] = LiveDisplay;
4910module.exports = exports['default'];
4911
4912},{"../component":66,"../utils/dom.js":131}],70:[function(_dereq_,module,exports){
4913/**
4914 * @file mute-toggle.js
4915 */
4916'use strict';
4917
4918exports.__esModule = true;
4919
4920function _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; } }
4921
4922function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4923
4924function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
4925
4926function _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; }
4927
4928var _button = _dereq_('../button');
4929
4930var _button2 = _interopRequireDefault(_button);
4931
4932var _component = _dereq_('../component');
4933
4934var _component2 = _interopRequireDefault(_component);
4935
4936var _utilsDomJs = _dereq_('../utils/dom.js');
4937
4938var Dom = _interopRequireWildcard(_utilsDomJs);
4939
4940/**
4941 * A button component for muting the audio
4942 *
4943 * @param {Player|Object} player
4944 * @param {Object=} options
4945 * @extends Button
4946 * @class MuteToggle
4947 */
4948
4949var MuteToggle = (function (_Button) {
4950  _inherits(MuteToggle, _Button);
4951
4952  function MuteToggle(player, options) {
4953    _classCallCheck(this, MuteToggle);
4954
4955    _Button.call(this, player, options);
4956
4957    this.on(player, 'volumechange', this.update);
4958
4959    // hide mute toggle if the current tech doesn't support volume control
4960    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
4961      this.addClass('vjs-hidden');
4962    }
4963
4964    this.on(player, 'loadstart', function () {
4965      this.update(); // We need to update the button to account for a default muted state.
4966
4967      if (player.tech_['featuresVolumeControl'] === false) {
4968        this.addClass('vjs-hidden');
4969      } else {
4970        this.removeClass('vjs-hidden');
4971      }
4972    });
4973  }
4974
4975  /**
4976   * Allow sub components to stack CSS class names
4977   *
4978   * @return {String} The constructed class name
4979   * @method buildCSSClass
4980   */
4981
4982  MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
4983    return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
4984  };
4985
4986  /**
4987   * Handle click on mute
4988   *
4989   * @method handleClick
4990   */
4991
4992  MuteToggle.prototype.handleClick = function handleClick() {
4993    this.player_.muted(this.player_.muted() ? false : true);
4994  };
4995
4996  /**
4997   * Update volume
4998   *
4999   * @method update
5000   */
5001
5002  MuteToggle.prototype.update = function update() {
5003    var vol = this.player_.volume(),
5004        level = 3;
5005
5006    if (vol === 0 || this.player_.muted()) {
5007      level = 0;
5008    } else if (vol < 0.33) {
5009      level = 1;
5010    } else if (vol < 0.67) {
5011      level = 2;
5012    }
5013
5014    // Don't rewrite the button text if the actual text doesn't change.
5015    // This causes unnecessary and confusing information for screen reader users.
5016    // This check is needed because this function gets called every time the volume level is changed.
5017    var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
5018    if (this.controlText() !== toMute) {
5019      this.controlText(toMute);
5020    }
5021
5022    /* TODO improve muted icon classes */
5023    for (var i = 0; i < 4; i++) {
5024      Dom.removeElClass(this.el_, 'vjs-vol-' + i);
5025    }
5026    Dom.addElClass(this.el_, 'vjs-vol-' + level);
5027  };
5028
5029  return MuteToggle;
5030})(_button2['default']);
5031
5032MuteToggle.prototype.controlText_ = 'Mute';
5033
5034_component2['default'].registerComponent('MuteToggle', MuteToggle);
5035exports['default'] = MuteToggle;
5036module.exports = exports['default'];
5037
5038},{"../button":63,"../component":66,"../utils/dom.js":131}],71:[function(_dereq_,module,exports){
5039/**
5040 * @file play-toggle.js
5041 */
5042'use strict';
5043
5044exports.__esModule = true;
5045
5046function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5047
5048function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5049
5050function _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; }
5051
5052var _buttonJs = _dereq_('../button.js');
5053
5054var _buttonJs2 = _interopRequireDefault(_buttonJs);
5055
5056var _componentJs = _dereq_('../component.js');
5057
5058var _componentJs2 = _interopRequireDefault(_componentJs);
5059
5060/**
5061 * Button to toggle between play and pause
5062 *
5063 * @param {Player|Object} player
5064 * @param {Object=} options
5065 * @extends Button
5066 * @class PlayToggle
5067 */
5068
5069var PlayToggle = (function (_Button) {
5070  _inherits(PlayToggle, _Button);
5071
5072  function PlayToggle(player, options) {
5073    _classCallCheck(this, PlayToggle);
5074
5075    _Button.call(this, player, options);
5076
5077    this.on(player, 'play', this.handlePlay);
5078    this.on(player, 'pause', this.handlePause);
5079  }
5080
5081  /**
5082   * Allow sub components to stack CSS class names
5083   *
5084   * @return {String} The constructed class name
5085   * @method buildCSSClass
5086   */
5087
5088  PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
5089    return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
5090  };
5091
5092  /**
5093   * Handle click to toggle between play and pause
5094   *
5095   * @method handleClick
5096   */
5097
5098  PlayToggle.prototype.handleClick = function handleClick() {
5099    if (this.player_.paused()) {
5100      this.player_.play();
5101    } else {
5102      this.player_.pause();
5103    }
5104  };
5105
5106  /**
5107   * Add the vjs-playing class to the element so it can change appearance
5108   *
5109   * @method handlePlay
5110   */
5111
5112  PlayToggle.prototype.handlePlay = function handlePlay() {
5113    this.removeClass('vjs-paused');
5114    this.addClass('vjs-playing');
5115    this.controlText('Pause'); // change the button text to "Pause"
5116  };
5117
5118  /**
5119   * Add the vjs-paused class to the element so it can change appearance
5120   *
5121   * @method handlePause
5122   */
5123
5124  PlayToggle.prototype.handlePause = function handlePause() {
5125    this.removeClass('vjs-playing');
5126    this.addClass('vjs-paused');
5127    this.controlText('Play'); // change the button text to "Play"
5128  };
5129
5130  return PlayToggle;
5131})(_buttonJs2['default']);
5132
5133PlayToggle.prototype.controlText_ = 'Play';
5134
5135_componentJs2['default'].registerComponent('PlayToggle', PlayToggle);
5136exports['default'] = PlayToggle;
5137module.exports = exports['default'];
5138
5139},{"../button.js":63,"../component.js":66}],72:[function(_dereq_,module,exports){
5140/**
5141 * @file playback-rate-menu-button.js
5142 */
5143'use strict';
5144
5145exports.__esModule = true;
5146
5147function _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; } }
5148
5149function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5150
5151function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5152
5153function _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
5153onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
5154
5155var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');
5156
5157var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
5158
5159var _menuMenuJs = _dereq_('../../menu/menu.js');
5160
5161var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
5162
5163var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js');
5164
5165var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs);
5166
5167var _componentJs = _dereq_('../../component.js');
5168
5169var _componentJs2 = _interopRequireDefault(_componentJs);
5170
5171var _utilsDomJs = _dereq_('../../utils/dom.js');
5172
5173var Dom = _interopRequireWildcard(_utilsDomJs);
5174
5175/**
5176 * The component for controlling the playback rate
5177 *
5178 * @param {Player|Object} player
5179 * @param {Object=} options
5180 * @extends MenuButton
5181 * @class PlaybackRateMenuButton
5182 */
5183
5184var PlaybackRateMenuButton = (function (_MenuButton) {
5185  _inherits(PlaybackRateMenuButton, _MenuButton);
5186
5187  function PlaybackRateMenuButton(player, options) {
5188    _classCallCheck(this, PlaybackRateMenuButton);
5189
5190    _MenuButton.call(this, player, options);
5191
5192    this.updateVisibility();
5193    this.updateLabel();
5194
5195    this.on(player, 'loadstart', this.updateVisibility);
5196    this.on(player, 'ratechange', this.updateLabel);
5197  }
5198
5199  /**
5200   * Create the component's DOM element
5201   *
5202   * @return {Element}
5203   * @method createEl
5204   */
5205
5206  PlaybackRateMenuButton.prototype.createEl = function createEl() {
5207    var el = _MenuButton.prototype.createEl.call(this);
5208
5209    this.labelEl_ = Dom.createEl('div', {
5210      className: 'vjs-playback-rate-value',
5211      innerHTML: 1.0
5212    });
5213
5214    el.appendChild(this.labelEl_);
5215
5216    return el;
5217  };
5218
5219  /**
5220   * Allow sub components to stack CSS class names
5221   *
5222   * @return {String} The constructed class name
5223   * @method buildCSSClass
5224   */
5225
5226  PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
5227    return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
5228  };
5229
5230  /**
5231   * Create the playback rate menu
5232   *
5233   * @return {Menu} Menu object populated with items
5234   * @method createMenu
5235   */
5236
5237  PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
5238    var menu = new _menuMenuJs2['default'](this.player());
5239    var rates = this.playbackRates();
5240
5241    if (rates) {
5242      for (var i = rates.length - 1; i >= 0; i--) {
5243        menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' }));
5244      }
5245    }
5246
5247    return menu;
5248  };
5249
5250  /**
5251   * Updates ARIA accessibility attributes
5252   *
5253   * @method updateARIAAttributes
5254   */
5255
5256  PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
5257    // Current playback rate
5258    this.el().setAttribute('aria-valuenow', this.player().playbackRate());
5259  };
5260
5261  /**
5262   * Handle menu item click
5263   *
5264   * @method handleClick
5265   */
5266
5267  PlaybackRateMenuButton.prototype.handleClick = function handleClick() {
5268    // select next rate option
5269    var currentRate = this.player().playbackRate();
5270    var rates = this.playbackRates();
5271
5272    // this will select first one if the last one currently selected
5273    var newRate = rates[0];
5274    for (var i = 0; i < rates.length; i++) {
5275      if (rates[i] > currentRate) {
5276        newRate = rates[i];
5277        break;
5278      }
5279    }
5280    this.player().playbackRate(newRate);
5281  };
5282
5283  /**
5284   * Get possible playback rates
5285   *
5286   * @return {Array} Possible playback rates
5287   * @method playbackRates
5288   */
5289
5290  PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
5291    return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates'];
5292  };
5293
5294  /**
5295   * Get supported playback rates
5296   *
5297   * @return {Array} Supported playback rates
5298   * @method playbackRateSupported
5299   */
5300
5301  PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
5302    return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0;
5303  };
5304
5305  /**
5306   * Hide playback rate controls when they're no playback rate options to select
5307   *
5308   * @method updateVisibility
5309   */
5310
5311  PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() {
5312    if (this.playbackRateSupported()) {
5313      this.removeClass('vjs-hidden');
5314    } else {
5315      this.addClass('vjs-hidden');
5316    }
5317  };
5318
5319  /**
5320   * Update button label when rate changed
5321   *
5322   * @method updateLabel
5323   */
5324
5325  PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() {
5326    if (this.playbackRateSupported()) {
5327      this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
5328    }
5329  };
5330
5331  return PlaybackRateMenuButton;
5332}
5332)(_menuMenuButtonJs2['default']);
5333
5334PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
5335
5336_componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
5337exports['default'] = PlaybackRateMenuButton;
5338module.exports = exports['default'];
5339
5340},{"../../component.js":66,"../../menu/menu-button.js":103,"../../menu/menu.js":105,"../../utils/dom.js":131,"./playback-rate-menu-item.js":73}],73:[function(_dereq_,module,exports){
5341/**
5342 * @file playback-rate-menu-item.js
5343 */
5344'use strict';
5345
5346exports.__esModule = true;
5347
5348function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5349
5350function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5351
5352function _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; }
5353
5354var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
5355
5356var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
5357
5358var _componentJs = _dereq_('../../component.js');
5359
5360var _componentJs2 = _interopRequireDefault(_componentJs);
5361
5362/**
5363 * The specific menu item type for selecting a playback rate
5364 *
5365 * @param {Player|Object} player
5366 * @param {Object=} options
5367 * @extends MenuItem
5368 * @class PlaybackRateMenuItem
5369 */
5370
5371var PlaybackRateMenuItem = (function (_MenuItem) {
5372  _inherits(PlaybackRateMenuItem, _MenuItem);
5373
5374  function PlaybackRateMenuItem(player, options) {
5375    _classCallCheck(this, PlaybackRateMenuItem);
5376
5377    var label = options['rate'];
5378    var rate = parseFloat(label, 10);
5379
5380    // Modify options for parent MenuItem class's init.
5381    options['label'] = label;
5382    options['selected'] = rate === 1;
5383    _MenuItem.call(this, player, options);
5384
5385    this.label = label;
5386    this.rate = rate;
5387
5388    this.on(player, 'ratechange', this.update);
5389  }
5390
5391  /**
5392   * Handle click on menu item
5393   *
5394   * @method handleClick
5395   */
5396
5397  PlaybackRateMenuItem.prototype.handleClick = function handleClick() {
5398    _MenuItem.prototype.handleClick.call(this);
5399    this.player().playbackRate(this.rate);
5400  };
5401
5402  /**
5403   * Update playback rate with selected rate
5404   *
5405   * @method update
5406   */
5407
5408  PlaybackRateMenuItem.prototype.update = function update() {
5409    this.selected(this.player().playbackRate() === this.rate);
5410  };
5411
5412  return PlaybackRateMenuItem;
5413})(_menuMenuItemJs2['default']);
5414
5415PlaybackRateMenuItem.prototype.contentElType = 'button';
5416
5417_componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
5418exports['default'] = PlaybackRateMenuItem;
5419module.exports = exports['default'];
5420
5421},{"../../component.js":66,"../../menu/menu-item.js":104}],74:[function(_dereq_,module,exports){
5422/**
5423 * @file load-progress-bar.js
5424 */
5425'use strict';
5426
5427exports.__esModule = true;
5428
5429function _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; } }
5430
5431function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5432
5433function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5434
5435function _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; }
5436
5437var _componentJs = _dereq_('../../component.js');
5438
5439var _componentJs2 = _interopRequireDefault(_componentJs);
5440
5441var _utilsDomJs = _dereq_('../../utils/dom.js');
5442
5443var Dom = _interopRequireWildcard(_utilsDomJs);
5444
5445/**
5446 * Shows load progress
5447 *
5448 * @param {Player|Object} player
5449 * @param {Object=} options
5450 * @extends Component
5451 * @class LoadProgressBar
5452 */
5453
5454var LoadProgressBar = (function (_Component) {
5455  _inherits(LoadProgressBar, _Component);
5456
5457  function LoadProgressBar(player, options) {
5458    _classCallCheck(this, LoadProgressBar);
5459
5460    _Component.call(this, player, options);
5461    this.on(player, 'progress', this.update);
5462  }
5463
5464  /**
5465   * Create the component's DOM element
5466   *
5467   * @return {Element}
5468   * @method createEl
5469   */
5470
5471  LoadProgressBar.prototype.createEl = function createEl() {
5472    return _Component.prototype.createEl.call(this, 'div', {
5473      className: 'vjs-load-progress',
5474      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
5475    });
5476  };
5477
5478  /**
5479   * Update progress bar
5480   *
5481   * @method update
5482   */
5483
5484  LoadProgressBar.prototype.update = function update() {
5485    var buffered = this.player_.buffered();
5486    var duration = this.player_.duration();
5487    var bufferedEnd = this.player_.bufferedEnd();
5488    var children = this.el_.children;
5489
5490    // get the percent width of a time compared to the total end
5491    var percentify = function percentify(time, end) {
5492      var percent = time / end || 0; // no NaN
5493      return (percent >= 1 ? 1 : percent) * 100 + '%';
5494    };
5495
5496    // update the width of the progress bar
5497    this.el_.style.width = percentify(bufferedEnd, duration);
5498
5499    // add child elements to represent the individual buffered time ranges
5500    for (var i = 0; i < buffered.length; i++) {
5501      var start = buffered.start(i);
5502      var end = buffered.end(i);
5503      var part = children[i];
5504
5505      if (!part) {
5506        part = this.el_.appendChild(Dom.createEl());
5507      }
5508
5509      // set the percent based on the width of the progress bar (bufferedEnd)
5510      part.style.left = percentify(start, bufferedEnd);
5511      part.style.width = percentify(end - start, bufferedEnd);
5512    }
5513
5514    // remove unused buffered range elements
5515    for (var i = children.length; i > buffered.length; i--) {
5516      this.el_.removeChild(children[i - 1]);
5517    }
5518  };
5519
5520  return LoadProgressBar;
5521})(_componentJs2['default']);
5522
5523_componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
5524exports['default'] = LoadProgressBar;
5525module.exports = exports['default'];
5526
5527},{"../../component.js":66,"../../utils/dom.js":131}],75:[function(_dereq_,module,exports){
5528/**
5529 * @file mouse-time-display.js
5530 */
5531'use strict';
5532
5533exports.__esModule = true;
5534
5535function _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; } }
5536
5537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5538
5539function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5540
5541function _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; }
5542
5543var _componentJs = _dereq_('../../component.js');
5544
5545var _componentJs2 = _interopRequireDefault(_componentJs);
5546
5547var _utilsDomJs = _dereq_('../../utils/dom.js');
5548
5549var Dom = _interopRequireWildcard(_utilsDomJs);
5550
5551var _utilsFnJs = _dereq_('../../utils/fn.js');
5552
5553var Fn = _interopRequireWildcard(_utilsFnJs);
5554
5555var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
5556
5557var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
5558
5559var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle');
5560
5561var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle);
5562
5563/**
5564 * The Mouse Time Display component shows the time you will seek to
5565 * when hovering over the progress bar
5566 *
5567 * @param {Player|Object} player
5568 * @param {Object=} options
5569 * @extends Component
5570 * @class MouseTimeDisplay
5571 */
5572
5573var MouseTimeDisplay = (function (_Component) {
5574  _inherits(MouseTimeDisplay, _Component);
5575
5576  function MouseTimeDisplay(player, options) {
5577    var _this = this;
5578
5579    _classCallCheck(this, MouseTimeDisplay);
5580
5581    _Component.call(this, player, options);
5582
5583    this.update(0, 0);
5584
5585    player.on('ready', function () {
5586      _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25));
5587    });
5588  }
5589
5590  /**
5591   * Create the component's DOM element
5592   *
5593   * @return {Element}
5594   * @method createEl
5595   */
5596
5597  MouseTimeDisplay.prototype.createEl = function createEl() {
5598    return _Component.prototype.createEl.call(this, 'div', {
5599      className: 'vjs-mouse-display'
5600    });
5601  };
5602
5603  MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
5604    var duration = this.player_.duration();
5605    var newTime = this.calculateDistance(event) * duration;
5606    var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
5607
5608    this.update(newTime, position);
5609  };
5610
5611  MouseTimeDisplay.prototype.update = function update(newTime, position) {
5612    var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration());
5613
5614    this.el().style.left = position + 'px';
5615    this.el().setAttribute('data-current-time', time);
5616  };
5617
5618  MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
5619    return Dom.getPointerPosition(this.el().parentNode, event).x;
5620  };
5621
5622  return MouseTimeDisplay;
5623})(_componentJs2['default']);
5624
5625_componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
5626exports['default'] = MouseTimeDisplay;
5627module.exports = exports['default'];
5628
5629},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/fn.js":133,"../../utils/format-time.js":134,"lodash-compat/function/throttle":7}],76:[function(_dereq_,module,exports){
5630/**
5631 * @file play-progress-bar.js
5632 */
5633'use strict';
5634
5635exports.__esModule = true;
5636
5637function _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; } }
5638
5639function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5640
5641function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5642
5643function _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
5643onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
5644
5645var _componentJs = _dereq_('../../component.js');
5646
5647var _componentJs2 = _interopRequireDefault(_componentJs);
5648
5649var _utilsFnJs = _dereq_('../../utils/fn.js');
5650
5651var Fn = _interopRequireWildcard(_utilsFnJs);
5652
5653var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
5654
5655var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
5656
5657/**
5658 * Shows play progress
5659 *
5660 * @param {Player|Object} player
5661 * @param {Object=} options
5662 * @extends Component
5663 * @class PlayProgressBar
5664 */
5665
5666var PlayProgressBar = (function (_Component) {
5667  _inherits(PlayProgressBar, _Component);
5668
5669  function PlayProgressBar(player, options) {
5670    _classCallCheck(this, PlayProgressBar);
5671
5672    _Component.call(this, player, options);
5673    this.updateDataAttr();
5674    this.on(player, 'timeupdate', this.updateDataAttr);
5675    player.ready(Fn.bind(this, this.updateDataAttr));
5676  }
5677
5678  /**
5679   * Create the component's DOM element
5680   *
5681   * @return {Element}
5682   * @method createEl
5683   */
5684
5685  PlayProgressBar.prototype.createEl = function createEl() {
5686    return _Component.prototype.createEl.call(this, 'div', {
5687      className: 'vjs-play-progress vjs-slider-bar',
5688      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
5689    });
5690  };
5691
5692  PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() {
5693    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5694    this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration()));
5695  };
5696
5697  return PlayProgressBar;
5698})(_componentJs2['default']);
5699
5700_componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
5701exports['default'] = PlayProgressBar;
5702module.exports = exports['default'];
5703
5704},{"../../component.js":66,"../../utils/fn.js":133,"../../utils/format-time.js":134}],77:[function(_dereq_,module,exports){
5705/**
5706 * @file progress-control.js
5707 */
5708'use strict';
5709
5710exports.__esModule = true;
5711
5712function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5713
5714function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5715
5716function _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; }
5717
5718var _componentJs = _dereq_('../../component.js');
5719
5720var _componentJs2 = _interopRequireDefault(_componentJs);
5721
5722var _seekBarJs = _dereq_('./seek-bar.js');
5723
5724var _seekBarJs2 = _interopRequireDefault(_seekBarJs);
5725
5726var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js');
5727
5728var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs);
5729
5730/**
5731 * The Progress Control component contains the seek bar, load progress,
5732 * and play progress
5733 *
5734 * @param {Player|Object} player
5735 * @param {Object=} options
5736 * @extends Component
5737 * @class ProgressControl
5738 */
5739
5740var ProgressControl = (function (_Component) {
5741  _inherits(ProgressControl, _Component);
5742
5743  function ProgressControl() {
5744    _classCallCheck(this, ProgressControl);
5745
5746    _Component.apply(this, arguments);
5747  }
5748
5749  /**
5750   * Create the component's DOM element
5751   *
5752   * @return {Element}
5753   * @method createEl
5754   */
5755
5756  ProgressControl.prototype.createEl = function createEl() {
5757    return _Component.prototype.createEl.call(this, 'div', {
5758      className: 'vjs-progress-control vjs-control'
5759    });
5760  };
5761
5762  return ProgressControl;
5763})(_componentJs2['default']);
5764
5765ProgressControl.prototype.options_ = {
5766  children: ['seekBar']
5767};
5768
5769_componentJs2['default'].registerComponent('ProgressControl', ProgressControl);
5770exports['default'] = ProgressControl;
5771module.exports = exports['default'];
5772
5773},{"../../component.js":66,"./mouse-time-display.js":75,"./seek-bar.js":78}],78:[function(_dereq_,module,exports){
5774/**
5775 * @file seek-bar.js
5776 */
5777'use strict';
5778
5779exports.__esModule = true;
5780
5781function _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; } }
5782
5783function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5784
5785function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5786
5787function _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
5787onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
5788
5789var _sliderSliderJs = _dereq_('../../slider/slider.js');
5790
5791var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
5792
5793var _componentJs = _dereq_('../../component.js');
5794
5795var _componentJs2 = _interopRequireDefault(_componentJs);
5796
5797var _loadProgressBarJs = _dereq_('./load-progress-bar.js');
5798
5799var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs);
5800
5801var _playProgressBarJs = _dereq_('./play-progress-bar.js');
5802
5803var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs);
5804
5805var _utilsFnJs = _dereq_('../../utils/fn.js');
5806
5807var Fn = _interopRequireWildcard(_utilsFnJs);
5808
5809var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
5810
5811var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
5812
5813var _objectAssign = _dereq_('object.assign');
5814
5815var _objectAssign2 = _interopRequireDefault(_objectAssign);
5816
5817/**
5818 * Seek Bar and holder for the progress bars
5819 *
5820 * @param {Player|Object} player
5821 * @param {Object=} options
5822 * @extends Slider
5823 * @class SeekBar
5824 */
5825
5826var SeekBar = (function (_Slider) {
5827  _inherits(SeekBar, _Slider);
5828
5829  function SeekBar(player, options) {
5830    _classCallCheck(this, SeekBar);
5831
5832    _Slider.call(this, player, options);
5833    this.on(player, 'timeupdate', this.updateARIAAttributes);
5834    player.ready(Fn.bind(this, this.updateARIAAttributes));
5835  }
5836
5837  /**
5838   * Create the component's DOM element
5839   *
5840   * @return {Element}
5841   * @method createEl
5842   */
5843
5844  SeekBar.prototype.createEl = function createEl() {
5845    return _Slider.prototype.createEl.call(this, 'div', {
5846      className: 'vjs-progress-holder'
5847    }, {
5848      'aria-label': 'video progress bar'
5849    });
5850  };
5851
5852  /**
5853   * Update ARIA accessibility attributes
5854   *
5855   * @method updateARIAAttributes
5856   */
5857
5858  SeekBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
5859    // Allows for smooth scrubbing, when player can't keep up.
5860    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5861    this.el_.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete)
5862    this.el_.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete)
5863  };
5864
5865  /**
5866   * Get percentage of video played
5867   *
5868   * @return {Number} Percentage played
5869   * @method getPercent
5870   */
5871
5872  SeekBar.prototype.getPercent = function getPercent() {
5873    var percent = this.player_.currentTime() / this.player_.duration();
5874    return percent >= 1 ? 1 : percent;
5875  };
5876
5877  /**
5878   * Handle mouse down on seek bar
5879   *
5880   * @method handleMouseDown
5881   */
5882
5883  SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
5884    _Slider.prototype.handleMouseDown.call(this, event);
5885
5886    this.player_.scrubbing(true);
5887
5888    this.videoWasPlaying = !this.player_.paused();
5889    this.player_.pause();
5890  };
5891
5892  /**
5893   * Handle mouse move on seek bar
5894   *
5895   * @method handleMouseMove
5896   */
5897
5898  SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
5899    var newTime = this.calculateDistance(event) * this.player_.duration();
5900
5901    // Don't let video end while scrubbing.
5902    if (newTime === this.player_.duration()) {
5903      newTime = newTime - 0.1;
5904    }
5905
5906    // Set new time (tell player to seek to new time)
5907    this.player_.currentTime(newTime);
5908  };
5909
5910  /**
5911   * Handle mouse up on seek bar
5912   *
5913   * @method handleMouseUp
5914   */
5915
5916  SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
5917    _Slider.prototype.handleMouseUp.call(this, event);
5918
5919    this.player_.scrubbing(false);
5920    if (this.videoWasPlaying) {
5921      this.player_.play();
5922    }
5923  };
5924
5925  /**
5926   * Move more quickly fast forward for keyboard-only users
5927   *
5928   * @method stepForward
5929   */
5930
5931  SeekBar.prototype.stepForward = function stepForward() {
5932    this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
5933  };
5934
5935  /**
5936   * Move more quickly rewind for keyboard-only users
5937   *
5938   * @method stepBack
5939   */
5940
5941  SeekBar.prototype.stepBack = function stepBack() {
5942    this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
5943  };
5944
5945  return SeekBar;
5946})(_sliderSliderJs2['default']);
5947
5948SeekBar.prototype.options_ = {
5949  children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
5950  'barName': 'playProgressBar'
5951};
5952
5953SeekBar.prototype.playerEvent = 'timeupdate';
5954
5955_componentJs2['default'].registerComponent('SeekBar', SeekBar);
5956exports['default'] = SeekBar;
5957module.exports = exports['default'];
5958
5959},{"../../component.js":66,"../../slider/slider.js":113,"../../utils/fn.js":133,"../../utils/format-time.js":134,"./load-progress-bar.js":74,"./play-progress-bar.js":76,"object.assign":45}],79:[function(_dereq_,module,exports){
5960/**
5961 * @file custom-control-spacer.js
5962 */
5963'use strict';
5964
5965exports.__esModule = true;
5966
5967function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5968
5969function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
5970
5971function _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
5971onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
5972
5973var _spacerJs = _dereq_('./spacer.js');
5974
5975var _spacerJs2 = _interopRequireDefault(_spacerJs);
5976
5977var _componentJs = _dereq_('../../component.js');
5978
5979var _componentJs2 = _interopRequireDefault(_componentJs);
5980
5981/**
5982 * Spacer specifically meant to be used as an insertion point for new plugins, etc.
5983 *
5984 * @extends Spacer
5985 * @class CustomControlSpacer
5986 */
5987
5988var CustomControlSpacer = (function (_Spacer) {
5989  _inherits(CustomControlSpacer, _Spacer);
5990
5991  function CustomControlSpacer() {
5992    _classCallCheck(this, CustomControlSpacer);
5993
5994    _Spacer.apply(this, arguments);
5995  }
5996
5997  /**
5998   * Allow sub components to stack CSS class names
5999   *
6000   * @return {String} The constructed class name
6001   * @method buildCSSClass
6002   */
6003
6004  CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
6005    return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
6006  };
6007
6008  /**
6009   * Create the component's DOM element
6010   *
6011   * @return {Element}
6012   * @method createEl
6013   */
6014
6015  CustomControlSpacer.prototype.createEl = function createEl() {
6016    var el = _Spacer.prototype.createEl.call(this, {
6017      className: this.buildCSSClass()
6018    });
6019
6020    // No-flex/table-cell mode requires there be some content
6021    // in the cell to fill the remaining space of the table.
6022    el.innerHTML = '&nbsp;';
6023    return el;
6024  };
6025
6026  return CustomControlSpacer;
6027})(_spacerJs2['default']);
6028
6029_componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
6030exports['default'] = CustomControlSpacer;
6031module.exports = exports['default'];
6032
6033},{"../../component.js":66,"./spacer.js":80}],80:[function(_dereq_,module,exports){
6034/**
6035 * @file spacer.js
6036 */
6037'use strict';
6038
6039exports.__esModule = true;
6040
6041function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6042
6043function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6044
6045function _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; }
6046
6047var _componentJs = _dereq_('../../component.js');
6048
6049var _componentJs2 = _interopRequireDefault(_componentJs);
6050
6051/**
6052 * Just an empty spacer element that can be used as an append point for plugins, etc.
6053 * Also can be used to create space between elements when necessary.
6054 *
6055 * @extends Component
6056 * @class Spacer
6057 */
6058
6059var Spacer = (function (_Component) {
6060  _inherits(Spacer, _Component);
6061
6062  function Spacer() {
6063    _classCallCheck(this, Spacer);
6064
6065    _Component.apply(this, arguments);
6066  }
6067
6068  /**
6069   * Allow sub components to stack CSS class names
6070   *
6071   * @return {String} The constructed class name
6072   * @method buildCSSClass
6073   */
6074
6075  Spacer.prototype.buildCSSClass = function buildCSSClass() {
6076    return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
6077  };
6078
6079  /**
6080   * Create the component's DOM element
6081   *
6082   * @return {Element}
6083   * @method createEl
6084   */
6085
6086  Spacer.prototype.createEl = function createEl() {
6087    return _Component.prototype.createEl.call(this, 'div', {
6088      className: this.buildCSSClass()
6089    });
6090  };
6091
6092  return Spacer;
6093})(_componentJs2['default']);
6094
6095_componentJs2['default'].registerComponent('Spacer', Spacer);
6096
6097exports['default'] = Spacer;
6098module.exports = exports['default'];
6099
6100},{"../../component.js":66}],81:[function(_dereq_,module,exports){
6101/**
6102 * @file caption-settings-menu-item.js
6103 */
6104'use strict';
6105
6106exports.__esModule = true;
6107
6108function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6109
6110function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6111
6112function _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
6112onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
6113
6114var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6115
6116var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6117
6118var _componentJs = _dereq_('../../component.js');
6119
6120var _componentJs2 = _interopRequireDefault(_componentJs);
6121
6122/**
6123 * The menu item for caption track settings menu
6124 *
6125 * @param {Player|Object} player
6126 * @param {Object=} options
6127 * @extends TextTrackMenuItem
6128 * @class CaptionSettingsMenuItem
6129 */
6130
6131var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) {
6132  _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
6133
6134  function CaptionSettingsMenuItem(player, options) {
6135    _classCallCheck(this, CaptionSettingsMenuItem);
6136
6137    options['track'] = {
6138      'kind': options['kind'],
6139      'player': player,
6140      'label': options['kind'] + ' settings',
6141      'selectable': false,
6142      'default': false,
6143      mode: 'disabled'
6144    };
6145
6146    // CaptionSettingsMenuItem has no concept of 'selected'
6147    options['selectable'] = false;
6148
6149    _TextTrackMenuItem.call(this, player, options);
6150    this.addClass('vjs-texttrack-settings');
6151    this.controlText(', opens ' + options['kind'] + ' settings dialog');
6152  }
6153
6154  /**
6155   * Handle click on menu item
6156   *
6157   * @method handleClick
6158   */
6159
6160  CaptionSettingsMenuItem.prototype.handleClick = function handleClick() {
6161    this.player().getChild('textTrackSettings').show();
6162    this.player().getChild('textTrackSettings').el_.focus();
6163  };
6164
6165  return CaptionSettingsMenuItem;
6166})(_textTrackMenuItemJs2['default']);
6167
6168_componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
6169exports['default'] = CaptionSettingsMenuItem;
6170module.exports = exports['default'];
6171
6172},{"../../component.js":66,"./text-track-menu-item.js":88}],82:[function(_dereq_,module,exports){
6173/**
6174 * @file captions-button.js
6175 */
6176'use strict';
6177
6178exports.__esModule = true;
6179
6180function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6181
6182function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6183
6184function _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; }
6185
6186var _textTrackButtonJs = _dereq_('./text-track-button.js');
6187
6188var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
6189
6190var _componentJs = _dereq_('../../component.js');
6191
6192var _componentJs2 = _interopRequireDefault(_componentJs);
6193
6194var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js');
6195
6196var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs);
6197
6198/**
6199 * The button component for toggling and selecting captions
6200 *
6201 * @param {Object} player  Player object
6202 * @param {Object=} options Object of option names and values
6203 * @param {Function=} ready    Ready callback function
6204 * @extends TextTrackButton
6205 * @class CaptionsButton
6206 */
6207
6208var CaptionsButton = (function (_TextTrackButton) {
6209  _inherits(CaptionsButton, _TextTrackButton);
6210
6211  function CaptionsButton(player, options, ready) {
6212    _classCallCheck(this, CaptionsButton);
6213
6214    _TextTrackButton.call(this, player, options, ready);
6215    this.el_.setAttribute('aria-label', 'Captions Menu');
6216  }
6217
6218  /**
6219   * Allow sub components to stack CSS class names
6220   *
6221   * @return {String} The constructed class name
6222   * @method buildCSSClass
6223   */
6224
6225  CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
6226    return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
6227  };
6228
6229  /**
6230   * Update caption menu items
6231   *
6232   * @method update
6233   */
6234
6235  CaptionsButton.prototype.update = function update() {
6236    var threshold = 2;
6237    _TextTrackButton.prototype.update.call(this);
6238
6239    // if native, then threshold is 1 because no settings button
6240    if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) {
6241      threshold = 1;
6242    }
6243
6244    if (this.items && this.items.length > threshold) {
6245      this.show();
6246    } else {
6247      this.hide();
6248    }
6249  };
6250
6251  /**
6252   * Create caption menu items
6253   *
6254   * @return {Array} Array of menu items
6255   * @method createItems
6256   */
6257
6258  CaptionsButton.prototype.createItems = function createItems() {
6259    var items = [];
6260
6261    if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) {
6262      items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
6263    }
6264
6265    return _TextTrackButton.prototype.createItems.call(this, items);
6266  };
6267
6268  return CaptionsButton;
6269})(_textTrackButtonJs2['default']);
6270
6271CaptionsButton.prototype.kind_ = 'captions';
6272CaptionsButton.prototype.controlText_ = 'Captions';
6273
6274_componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton);
6275exports['default'] = CaptionsButton;
6276module.exports = exports['default'];
6277
6278},{"../../component.js":66,"./caption-settings-menu-item.js":81,"./text-track-button.js":87}],83:[function(_dereq_,module,exports){
6279/**
6280 * @file chapters-button.js
6281 */
6282'use strict';
6283
6284exports.__esModule = true;
6285
6286function _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; } }
6287
6288function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6289
6290function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6291
6292function _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; }
6293
6294var _textTrackButtonJs = _dereq_('./text-track-button.js');
6295
6296var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
6297
6298var _componentJs = _dereq_('../../component.js');
6299
6300var _componentJs2 = _interopRequireDefault(_componentJs);
6301
6302var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6303
6304var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6305
6306var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js');
6307
6308var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs);
6309
6310var _menuMenuJs = _dereq_('../../menu/menu.js');
6311
6312var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
6313
6314var _utilsDomJs = _dereq_('../../utils/dom.js');
6315
6316var Dom = _interopRequireWildcard(_utilsDomJs);
6317
6318var _utilsFnJs = _dereq_('../../utils/fn.js');
6319
6320var Fn = _interopRequireWildcard(_utilsFnJs);
6321
6322var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js');
6323
6324var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
6325
6326var _globalWindow = _dereq_('global/window');
6327
6328var _globalWindow2 = _interopRequireDefault(_globalWindow);
6329
6330/**
6331 * The button component for toggling and selecting chapters
6332 * Chapters act much differently than other text tracks
6333 * Cues are navigation vs. other tracks of alternative languages
6334 *
6335 * @param {Object} player  Player object
6336 * @param {Object=} options Object of option names and values
6337 * @param {Function=} ready    Ready callback function
6338 * @extends TextTrackButton
6339 * @class ChaptersButton
6340 */
6341
6342var ChaptersButton = (function (_TextTrackButton) {
6343  _inherits(ChaptersButton, _TextTrackButton);
6344
6345  function ChaptersButton(player, options, ready) {
6346    _classCallCheck(this, ChaptersButton);
6347
6348    _TextTrackButton.call(this, player, options, ready);
6349    this.el_.setAttribute('aria-label', 'Chapters Menu');
6350  }
6351
6352  /**
6353   * Allow sub components to stack CSS class names
6354   *
6355   * @return {String} The constructed class name
6356   * @method buildCSSClass
6357   */
6358
6359  ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
6360    return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
6361  };
6362
6363  /**
6364   * Create a menu item for each text track
6365   *
6366   * @return {Array} Array of menu items
6367   * @method createItems
6368   */
6369
6370  ChaptersButton.prototype.createItems = function createItems() {
6371    var items = [];
6372
6373    var tracks = this.player_.textTracks();
6374
6375    if (!tracks) {
6376      return items;
6377    }
6378
6379    for (var i = 0; i < tracks.length; i++) {
6380      var track = tracks[i];
6381      if (track['kind'] === this.kind_) {
6382        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
6383          'track': track
6384        }));
6385      }
6386    }
6387
6388    return items;
6389  };
6390
6391  /**
6392   * Create menu from chapter buttons
6393   *
6394   * @return {Menu} Menu of chapter buttons
6395   * @method createMenu
6396   */
6397
6398  ChaptersButton.prototype.createMenu = function createMenu() {
6399    var _this = this;
6400
6401    var tracks = this.player_.textTracks() || [];
6402    var chaptersTrack = undefined;
6403    var items = this.items = [];
6404
6405    for (var i = 0, _length = tracks.length; i < _length; i++) {
6406      var track = tracks[i];
6407
6408      if (track['kind'] === this.kind_) {
6409        chaptersTrack = track;
6410
6411        break;
6412      }
6413    }
6414
6415    var menu = this.menu;
6416    if (menu === undefined) {
6417      menu = new _menuMenuJs2['default'](this.player_);
6418      menu.contentEl().appendChild(Dom.createEl('li', {
6419        className: 'vjs-menu-title',
6420        innerHTML: _utilsToTitleCaseJs2['default'](this.kind_),
6421        tabIndex: -1
6422      }));
6423    }
6424
6425    if (chaptersTrack && chaptersTrack.cues == null) {
6426      chaptersTrack['mode'] = 'hidden';
6427
6428      var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
6429
6430      if (remoteTextTrackEl) {
6431        remoteTextTrackEl.addEventListener('load', function (event) {
6432          return _this.update();
6433        });
6434      }
6435    }
6436
6437    if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
6438      var cues = chaptersTrack['cues'],
6439          cue = undefined;
6440
6441      for (var i = 0, l = cues.length; i < l; i++) {
6442        cue = cues[i];
6443
6444        var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, {
6445          'track': chaptersTrack,
6446          'cue': cue
6447        });
6448
6449        items.push(mi);
6450
6451        menu.addChild(mi);
6452      }
6453
6454      this.addChild(menu);
6455    }
6456
6457    if (this.items.length > 0) {
6458      this.show();
6459    }
6460
6461    return menu;
6462  };
6463
6464  return ChaptersButton;
6465})(_textTrackButtonJs2['default']);
6466
6467ChaptersButton.prototype.kind_ = 'chapters';
6468ChaptersButton.prototype.controlText_ = 'Chapters';
6469
6470_componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton);
6471exports['default'] = ChaptersButton;
6472module.exports = exports['default'];
6473
6474},{"../../component.js":66,"../../menu/menu.js":105,"../../utils/dom.js":131,"../../utils/fn.js":133,"../../utils/to-title-case.js":140,"./chapters-track-menu-item.js":84,"./text-track-button.js":87,"./text-track-menu-item.js":88,"global/window":2}],84:[function(_dereq_,module,exports){
6475/**
6476 * @file chapters-track-menu-item.js
6477 */
6478'use strict';
6479
6480exports.__esModule = true;
6481
6482function _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; } }
6483
6484function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6485
6486function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6487
6488function _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; }
6489
6490var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
6491
6492var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
6493
6494var _componentJs = _dereq_('../../component.js');
6495
6496var _componentJs2 = _interopRequireDefault(_componentJs);
6497
6498var _utilsFnJs = _dereq_('../../utils/fn.js');
6499
6500var Fn = _interopRequireWildcard(_utilsFnJs);
6501
6502/**
6503 * The chapter track menu item
6504 *
6505 * @param {Player|Object} player
6506 * @param {Object=} options
6507 * @extends MenuItem
6508 * @class ChaptersTrackMenuItem
6509 */
6510
6511var ChaptersTrackMenuItem = (function (_MenuItem) {
6512  _inherits(ChaptersTrackMenuItem, _MenuItem);
6513
6514  function ChaptersTrackMenuItem(player, options) {
6515    _classCallCheck(this, ChaptersTrackMenuItem);
6516
6517    var track = options['track'];
6518    var cue = options['cue'];
6519    var currentTime = player.currentTime();
6520
6521    // Modify options for parent MenuItem class's init.
6522    options['label'] = cue.text;
6523    options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime'];
6524    _MenuItem.call(this, player, options);
6525
6526    this.track = track;
6527    this.cue = cue;
6528    track.addEventListener('cuechange', Fn.bind(this, this.update));
6529  }
6530
6531  /**
6532   * Handle click on menu item
6533   *
6534   * @method handleClick
6535   */
6536
6537  ChaptersTrackMenuItem.prototype.handleClick = function handleClick() {
6538    _MenuItem.prototype.handleClick.call(this);
6539    this.player_.currentTime(this.cue.startTime);
6540    this.update(this.cue.startTime);
6541  };
6542
6543  /**
6544   * Update chapter menu item
6545   *
6546   * @method update
6547   */
6548
6549  ChaptersTrackMenuItem.prototype.update = function update() {
6550    var cue = this.cue;
6551    var currentTime = this.player_.currentTime();
6552
6553    // vjs.log(currentTime, cue.startTime);
6554    this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']);
6555  };
6556
6557  return ChaptersTrackMenuItem;
6558})(_menuMenuItemJs2['default']);
6559
6560_componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
6561exports['default'] = ChaptersTrackMenuItem;
6562module.exports = exports['default'];
6563
6564},{"../../component.js":66,"../../menu/menu-item.js":104,"../../utils/fn.js":133}],85:[function(_dereq_,module,exports){
6565/**
6566 * @file off-text-track-menu-item.js
6567 */
6568'use strict';
6569
6570exports.__esModule = true;
6571
6572function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6573
6574function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6575
6576function _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; }
6577
6578var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6579
6580var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6581
6582var _componentJs = _dereq_('../../component.js');
6583
6584var _componentJs2 = _interopRequireDefault(_componentJs);
6585
6586/**
6587 * A special menu item for turning of a specific type of text track
6588 *
6589 * @param {Player|Object} player
6590 * @param {Object=} options
6591 * @extends TextTrackMenuItem
6592 * @class OffTextTrackMenuItem
6593 */
6594
6595var OffTextTrackMenuItem = (function (_TextTrackMenuItem) {
6596  _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
6597
6598  function OffTextTrackMenuItem(player, options) {
6599    _classCallCheck(this, OffTextTrackMenuItem);
6600
6601    // Create pseudo track info
6602    // Requires options['kind']
6603    options['track'] = {
6604      'kind': options['kind'],
6605      'player': player,
6606      'label': options['kind'] + ' off',
6607      'default': false,
6608      'mode': 'disabled'
6609    };
6610
6611    // MenuItem is selectable
6612    options['selectable'] = true;
6613
6614    _TextTrackMenuItem.call(this, player, options);
6615    this.selected(true);
6616  }
6617
6618  /**
6619   * Handle text track change
6620   *
6621   * @param {Object} event Event object
6622   * @method handleTracksChange
6623   */
6624
6625  OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
6626    var tracks = this.player().textTracks();
6627    var selected = true;
6628
6629    for (var i = 0, l = tracks.length; i < l; i++) {
6630      var track = tracks[i];
6631      if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') {
6632        selected = false;
6633        break;
6634      }
6635    }
6636
6637    this.selected(selected);
6638  };
6639
6640  return OffTextTrackMenuItem;
6641})(_textTrackMenuItemJs2['default']);
6642
6643_componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
6644exports['default'] = OffTextTrackMenuItem;
6645module.exports = exports['default'];
6646
6647},{"../../component.js":66,"./text-track-menu-item.js":88}],86:[function(_dereq_,module,exports){
6648/**
6649 * @file subtitles-button.js
6650 */
6651'use strict';
6652
6653exports.__esModule = true;
6654
6655function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6656
6657function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6658
6659function _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; }
6660
6661var _textTrackButtonJs = _dereq_('./text-track-button.js');
6662
6663var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
6664
6665var _componentJs = _dereq_('../../component.js');
6666
6667var _componentJs2 = _interopRequireDefault(_componentJs);
6668
6669/**
6670 * The button component for toggling and selecting subtitles
6671 *
6672 * @param {Object} player  Player object
6673 * @param {Object=} options Object of option names and values
6674 * @param {Function=} ready    Ready callback function
6675 * @extends TextTrackButton
6676 * @class SubtitlesButton
6677 */
6678
6679var SubtitlesButton = (function (_TextTrackButton) {
6680  _inherits(SubtitlesButton, _TextTrackButton);
6681
6682  function SubtitlesButton(player, options, ready) {
6683    _classCallCheck(this, SubtitlesButton);
6684
6685    _TextTrackButton.call(this, player, options, ready);
6686    this.el_.setAttribute('aria-label', 'Subtitles Menu');
6687  }
6688
6689  /**
6690   * Allow sub components to stack CSS class names
6691   *
6692   * @return {String} The constructed class name
6693   * @method buildCSSClass
6694   */
6695
6696  SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
6697    return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
6698  };
6699
6700  return SubtitlesButton;
6701})(_textTrackButtonJs2['default']);
6702
6703SubtitlesButton.prototype.kind_ = 'subtitles';
6704SubtitlesButton.prototype.controlText_ = 'Subtitles';
6705
6706_componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
6707exports['default'] = SubtitlesButton;
6708module.exports = exports['default'];
6709
6710},{"../../component.js":66,"./text-track-button.js":87}],87:[function(_dereq_,module,exports){
6711/**
6712 * @file text-track-button.js
6713 */
6714'use strict';
6715
6716exports.__esModule = true;
6717
6718function _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; } }
6719
6720function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6721
6722function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6723
6724function _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; }
6725
6726var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');
6727
6728var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
6729
6730var _componentJs = _dereq_('../../component.js');
6731
6732var _componentJs2 = _interopRequireDefault(_componentJs);
6733
6734var _utilsFnJs = _dereq_('../../utils/fn.js');
6735
6736var Fn = _interopRequireWildcard(_utilsFnJs);
6737
6738var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
6739
6740var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
6741
6742var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js');
6743
6744var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs);
6745
6746/**
6747 * The base class for buttons that toggle specific text track types (e.g. subtitles)
6748 *
6749 * @param {Player|Object} player
6750 * @param {Object=} options
6751 * @extends MenuButton
6752 * @class TextTrackButton
6753 */
6754
6755var TextTrackButton = (function (_MenuButton) {
6756  _inherits(TextTrackButton, _MenuButton);
6757
6758  function TextTrackButton(player, options) {
6759    _classCallCheck(this, TextTrackButton);
6760
6761    _MenuButton.call(this, player, options);
6762
6763    var tracks = this.player_.textTracks();
6764
6765    if (this.items.length <= 1) {
6766      this.hide();
6767    }
6768
6769    if (!tracks) {
6770      return;
6771    }
6772
6773    var updateHandler = Fn.bind(this, this.update);
6774    tracks.addEventListener('removetrack', updateHandler);
6775    tracks.addEventListener('addtrack', updateHandler);
6776
6777    this.player_.on('dispose', function () {
6778      tracks.removeEventListener('removetrack', updateHandler);
6779      tracks.removeEventListener('addtrack', updateHandler);
6780    });
6781  }
6782
6783  // Create a menu item for each text track
6784
6785  TextTrackButton.prototype.createItems = function createItems() {
6786    var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
6787
6788    // Add an OFF menu item to turn all tracks off
6789    items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
6790
6791    var tracks = this.player_.textTracks();
6792
6793    if (!tracks) {
6794      return items;
6795    }
6796
6797    for (var i = 0; i < tracks.length; i++) {
6798      var track = tracks[i];
6799
6800      // only add tracks that are of the appropriate kind and have a label
6801      if (track['kind'] === this.kind_) {
6802        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
6803          // MenuItem is selectable
6804          'selectable': true,
6805          'track': track
6806        }));
6807      }
6808    }
6809
6810    return items;
6811  };
6812
6813  return TextTrackButton;
6814}
6814)(_menuMenuButtonJs2['default']);
6815
6816_componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton);
6817exports['default'] = TextTrackButton;
6818module.exports = exports['default'];
6819
6820},{"../../component.js":66,"../../menu/menu-button.js":103,"../../utils/fn.js":133,"./off-text-track-menu-item.js":85,"./text-track-menu-item.js":88}],88:[function(_dereq_,module,exports){
6821/**
6822 * @file text-track-menu-item.js
6823 */
6824'use strict';
6825
6826exports.__esModule = true;
6827
6828function _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; } }
6829
6830function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6831
6832function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6833
6834function _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; }
6835
6836var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
6837
6838var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
6839
6840var _componentJs = _dereq_('../../component.js');
6841
6842var _componentJs2 = _interopRequireDefault(_componentJs);
6843
6844var _utilsFnJs = _dereq_('../../utils/fn.js');
6845
6846var Fn = _interopRequireWildcard(_utilsFnJs);
6847
6848var _globalWindow = _dereq_('global/window');
6849
6850var _globalWindow2 = _interopRequireDefault(_globalWindow);
6851
6852var _globalDocument = _dereq_('global/document');
6853
6854var _globalDocument2 = _interopRequireDefault(_globalDocument);
6855
6856/**
6857 * The specific menu item type for selecting a language within a text track kind
6858 *
6859 * @param {Player|Object} player
6860 * @param {Object=} options
6861 * @extends MenuItem
6862 * @class TextTrackMenuItem
6863 */
6864
6865var TextTrackMenuItem = (function (_MenuItem) {
6866  _inherits(TextTrackMenuItem, _MenuItem);
6867
6868  function TextTrackMenuItem(player, options) {
6869    var _this = this;
6870
6871    _classCallCheck(this, TextTrackMenuItem);
6872
6873    var track = options['track'];
6874    var tracks = player.textTracks();
6875
6876    // Modify options for parent MenuItem class's init.
6877    options['label'] = track['label'] || track['language'] || 'Unknown';
6878    options['selected'] = track['default'] || track['mode'] === 'showing';
6879
6880    _MenuItem.call(this, player, options);
6881
6882    this.track = track;
6883
6884    if (tracks) {
6885      (function () {
6886        var changeHandler = Fn.bind(_this, _this.handleTracksChange);
6887
6888        tracks.addEventListener('change', changeHandler);
6889        _this.on('dispose', function () {
6890          tracks.removeEventListener('change', changeHandler);
6891        });
6892      })();
6893    }
6894
6895    // iOS7 doesn't dispatch change events to TextTrackLists when an
6896    // associated track's mode changes. Without something like
6897    // Object.observe() (also not present on iOS7), it's not
6898    // possible to detect changes to the mode attribute and polyfill
6899    // the change event. As a poor substitute, we manually dispatch
6900    // change events whenever the controls modify the mode.
6901    if (tracks && tracks.onchange === undefined) {
6902      (function () {
6903        var event = undefined;
6904
6905        _this.on(['tap', 'click'], function () {
6906          if (typeof _globalWindow2['default'].Event !== 'object') {
6907            // Android 2.3 throws an Illegal Constructor error for window.Event
6908            try {
6909              event = new _globalWindow2['default'].Event('change');
6910            } catch (err) {}
6911          }
6912
6913          if (!event) {
6914            event = _globalDocument2['default'].createEvent('Event');
6915            event.initEvent('change', true, true);
6916          }
6917
6918          tracks.dispatchEvent(event);
6919        });
6920      })();
6921    }
6922  }
6923
6924  /**
6925   * Handle click on text track
6926   *
6927   * @method handleClick
6928   */
6929
6930  TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
6931    var kind = this.track['kind'];
6932    var tracks = this.player_.textTracks();
6933
6934    _MenuItem.prototype.handleClick.call(this, event);
6935
6936    if (!tracks) return;
6937
6938    for (var i = 0; i < tracks.length; i++) {
6939      var track = tracks[i];
6940
6941      if (track['kind'] !== kind) {
6942        continue;
6943      }
6944
6945      if (track === this.track) {
6946        track['mode'] = 'showing';
6947      } else {
6948        track['mode'] = 'disabled';
6949      }
6950    }
6951  };
6952
6953  /**
6954   * Handle text track change
6955   *
6956   * @method handleTracksChange
6957   */
6958
6959  TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
6960    this.selected(this.track['mode'] === 'showing');
6961  };
6962
6963  return TextTrackMenuItem;
6964}
6964)(_menuMenuItemJs2['default']);
6965
6966_componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
6967exports['default'] = TextTrackMenuItem;
6968module.exports = exports['default'];
6969
6970},{"../../component.js":66,"../../menu/menu-item.js":104,"../../utils/fn.js":133,"global/document":1,"global/window":2}],89:[function(_dereq_,module,exports){
6971/**
6972 * @file current-time-display.js
6973 */
6974'use strict';
6975
6976exports.__esModule = true;
6977
6978function _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; } }
6979
6980function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6981
6982function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
6983
6984function _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; }
6985
6986var _componentJs = _dereq_('../../component.js');
6987
6988var _componentJs2 = _interopRequireDefault(_componentJs);
6989
6990var _utilsDomJs = _dereq_('../../utils/dom.js');
6991
6992var Dom = _interopRequireWildcard(_utilsDomJs);
6993
6994var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
6995
6996var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
6997
6998/**
6999 * Displays the current time
7000 *
7001 * @param {Player|Object} player
7002 * @param {Object=} options
7003 * @extends Component
7004 * @class CurrentTimeDisplay
7005 */
7006
7007var CurrentTimeDisplay = (function (_Component) {
7008  _inherits(CurrentTimeDisplay, _Component);
7009
7010  function CurrentTimeDisplay(player, options) {
7011    _classCallCheck(this, CurrentTimeDisplay);
7012
7013    _Component.call(this, player, options);
7014
7015    this.on(player, 'timeupdate', this.updateContent);
7016  }
7017
7018  /**
7019   * Create the component's DOM element
7020   *
7021   * @return {Element}
7022   * @method createEl
7023   */
7024
7025  CurrentTimeDisplay.prototype.createEl = function createEl() {
7026    var el = _Component.prototype.createEl.call(this, 'div', {
7027      className: 'vjs-current-time vjs-time-control vjs-control'
7028    });
7029
7030    this.contentEl_ = Dom.createEl('div', {
7031      className: 'vjs-current-time-display',
7032      // label the current time for screen reader users
7033      innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
7034    }, {
7035      // tell screen readers not to automatically read the time as it changes
7036      'aria-live': 'off'
7037    });
7038
7039    el.appendChild(this.contentEl_);
7040    return el;
7041  };
7042
7043  /**
7044   * Update current time display
7045   *
7046   * @method updateContent
7047   */
7048
7049  CurrentTimeDisplay.prototype.updateContent = function updateContent() {
7050    // Allows for smooth scrubbing, when player can't keep up.
7051    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
7052    var localizedText = this.localize('Current Time');
7053    var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
7054    this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
7055  };
7056
7057  return CurrentTimeDisplay;
7058})(_componentJs2['default']);
7059
7060_componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
7061exports['default'] = CurrentTimeDisplay;
7062module.exports = exports['default'];
7063
7064},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],90:[function(_dereq_,module,exports){
7065/**
7066 * @file duration-display.js
7067 */
7068'use strict';
7069
7070exports.__esModule = true;
7071
7072function _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; } }
7073
7074function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7075
7076function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7077
7078function _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
7078onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7079
7080var _componentJs = _dereq_('../../component.js');
7081
7082var _componentJs2 = _interopRequireDefault(_componentJs);
7083
7084var _utilsDomJs = _dereq_('../../utils/dom.js');
7085
7086var Dom = _interopRequireWildcard(_utilsDomJs);
7087
7088var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
7089
7090var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
7091
7092/**
7093 * Displays the duration
7094 *
7095 * @param {Player|Object} player
7096 * @param {Object=} options
7097 * @extends Component
7098 * @class DurationDisplay
7099 */
7100
7101var DurationDisplay = (function (_Component) {
7102  _inherits(DurationDisplay, _Component);
7103
7104  function DurationDisplay(player, options) {
7105    _classCallCheck(this, DurationDisplay);
7106
7107    _Component.call(this, player, options);
7108
7109    // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually,
7110    // however the durationchange event fires before this.player_.duration() is set,
7111    // so the value cannot be written out using this method.
7112    // Once the order of durationchange and this.player_.duration() being set is figured out,
7113    // this can be updated.
7114    this.on(player, 'timeupdate', this.updateContent);
7115    this.on(player, 'loadedmetadata', this.updateContent);
7116  }
7117
7118  /**
7119   * Create the component's DOM element
7120   *
7121   * @return {Element}
7122   * @method createEl
7123   */
7124
7125  DurationDisplay.prototype.createEl = function createEl() {
7126    var el = _Component.prototype.createEl.call(this, 'div', {
7127      className: 'vjs-duration vjs-time-control vjs-control'
7128    });
7129
7130    this.contentEl_ = Dom.createEl('div', {
7131      className: 'vjs-duration-display',
7132      // label the duration time for screen reader users
7133      innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
7134    }, {
7135      // tell screen readers not to automatically read the time as it changes
7136      'aria-live': 'off'
7137    });
7138
7139    el.appendChild(this.contentEl_);
7140    return el;
7141  };
7142
7143  /**
7144   * Update duration time display
7145   *
7146   * @method updateContent
7147   */
7148
7149  DurationDisplay.prototype.updateContent = function updateContent() {
7150    var duration = this.player_.duration();
7151    if (duration) {
7152      var localizedText = this.localize('Duration Time');
7153      var formattedTime = _utilsFormatTimeJs2['default'](duration);
7154      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users
7155    }
7156  };
7157
7158  return DurationDisplay;
7159})(_componentJs2['default']);
7160
7161_componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay);
7162exports['default'] = DurationDisplay;
7163module.exports = exports['default'];
7164
7165},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],91:[function(_dereq_,module,exports){
7166/**
7167 * @file remaining-time-display.js
7168 */
7169'use strict';
7170
7171exports.__esModule = true;
7172
7173function _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; } }
7174
7175function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7176
7177function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7178
7179function _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; }
7180
7181var _componentJs = _dereq_('../../component.js');
7182
7183var _componentJs2 = _interopRequireDefault(_componentJs);
7184
7185var _utilsDomJs = _dereq_('../../utils/dom.js');
7186
7187var Dom = _interopRequireWildcard(_utilsDomJs);
7188
7189var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
7190
7191var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
7192
7193/**
7194 * Displays the time left in the video
7195 *
7196 * @param {Player|Object} player
7197 * @param {Object=} options
7198 * @extends Component
7199 * @class RemainingTimeDisplay
7200 */
7201
7202var RemainingTimeDisplay = (function (_Component) {
7203  _inherits(RemainingTimeDisplay, _Component);
7204
7205  function RemainingTimeDisplay(player, options) {
7206    _classCallCheck(this, RemainingTimeDisplay);
7207
7208    _Component.call(this, player, options);
7209
7210    this.on(player, 'timeupdate', this.updateContent);
7211  }
7212
7213  /**
7214   * Create the component's DOM element
7215   *
7216   * @return {Element}
7217   * @method createEl
7218   */
7219
7220  RemainingTimeDisplay.prototype.createEl = function createEl() {
7221    var el = _Component.prototype.createEl.call(this, 'div', {
7222      className: 'vjs-remaining-time vjs-time-control vjs-control'
7223    });
7224
7225    this.contentEl_ = Dom.createEl('div', {
7226      className: 'vjs-remaining-time-display',
7227      // label the remaining time for screen reader users
7228      innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
7229    }, {
7230      // tell screen readers not to automatically read the time as it changes
7231      'aria-live': 'off'
7232    });
7233
7234    el.appendChild(this.contentEl_);
7235    return el;
7236  };
7237
7238  /**
7239   * Update remaining time display
7240   *
7241   * @method updateContent
7242   */
7243
7244  RemainingTimeDisplay.prototype.updateContent = function updateContent() {
7245    if (this.player_.duration()) {
7246      var localizedText = this.localize('Remaining Time');
7247      var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime());
7248      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
7249    }
7250
7251    // Allows for smooth scrubbing, when player can't keep up.
7252    // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
7253    // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
7254  };
7255
7256  return RemainingTimeDisplay;
7257})(_componentJs2['default']);
7258
7259_componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
7260exports['default'] = RemainingTimeDisplay;
7261module.exports = exports['default'];
7262
7263},{"../../component.js":66,"../../utils/dom.js":131,"../../utils/format-time.js":134}],92:[function(_dereq_,module,exports){
7264/**
7265 * @file time-divider.js
7266 */
7267'use strict';
7268
7269exports.__esModule = true;
7270
7271function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7272
7273function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7274
7275function _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; }
7276
7277var _componentJs = _dereq_('../../component.js');
7278
7279var _componentJs2 = _interopRequireDefault(_componentJs);
7280
7281/**
7282 * The separator between the current time and duration.
7283 * Can be hidden if it's not needed in the design.
7284 *
7285 * @param {Player|Object} player
7286 * @param {Object=} options
7287 * @extends Component
7288 * @class TimeDivider
7289 */
7290
7291var TimeDivider = (function (_Component) {
7292  _inherits(TimeDivider, _Component);
7293
7294  function TimeDivider() {
7295    _classCallCheck(this, TimeDivider);
7296
7297    _Component.apply(this, arguments);
7298  }
7299
7300  /**
7301   * Create the component's DOM element
7302   *
7303   * @return {Element}
7304   * @method createEl
7305   */
7306
7307  TimeDivider.prototype.createEl = function createEl() {
7308    return _Component.prototype.createEl.call(this, 'div', {
7309      className: 'vjs-time-control vjs-time-divider',
7310      innerHTML: '<div><span>/</span></div>'
7311    });
7312  };
7313
7314  return TimeDivider;
7315})(_componentJs2['default']);
7316
7317_componentJs2['default'].registerComponent('TimeDivider', TimeDivider);
7318exports['default'] = TimeDivider;
7319module.exports = exports['default'];
7320
7321},{"../../component.js":66}],93:[function(_dereq_,module,exports){
7322/**
7323 * @file volume-bar.js
7324 */
7325'use strict';
7326
7327exports.__esModule = true;
7328
7329function _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; } }
7330
7331function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7332
7333function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7334
7335function _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; }
7336
7337var _sliderSliderJs = _dereq_('../../slider/slider.js');
7338
7339var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
7340
7341var _componentJs = _dereq_('../../component.js');
7342
7343var _componentJs2 = _interopRequireDefault(_componentJs);
7344
7345var _utilsFnJs = _dereq_('../../utils/fn.js');
7346
7347var Fn = _interopRequireWildcard(_utilsFnJs);
7348
7349// Required children
7350
7351var _volumeLevelJs = _dereq_('./volume-level.js');
7352
7353var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs);
7354
7355/**
7356 * The bar that contains the volume level and can be clicked on to adjust the level
7357 *
7358 * @param {Player|Object} player
7359 * @param {Object=} options
7360 * @extends Slider
7361 * @class VolumeBar
7362 */
7363
7364var VolumeBar = (function (_Slider) {
7365  _inherits(VolumeBar, _Slider);
7366
7367  function VolumeBar(player, options) {
7368    _classCallCheck(this, VolumeBar);
7369
7370    _Slider.call(this, player, options);
7371    this.on(player, 'volumechange', this.updateARIAAttributes);
7372    player.ready(Fn.bind(this, this.updateARIAAttributes));
7373  }
7374
7375  /**
7376   * Create the component's DOM element
7377   *
7378   * @return {Element}
7379   * @method createEl
7380   */
7381
7382  VolumeBar.prototype.createEl = function createEl() {
7383    return _Slider.prototype.createEl.call(this, 'div', {
7384      className: 'vjs-volume-bar vjs-slider-bar'
7385    }, {
7386      'aria-label': 'volume level'
7387    });
7388  };
7389
7390  /**
7391   * Handle mouse move on volume bar
7392   *
7393   * @method handleMouseMove
7394   */
7395
7396  VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
7397    this.checkMuted();
7398    this.player_.volume(this.calculateDistance(event));
7399  };
7400
7401  VolumeBar.prototype.checkMuted = function checkMuted() {
7402    if (this.player_.muted()) {
7403      this.player_.muted(false);
7404    }
7405  };
7406
7407  /**
7408   * Get percent of volume level
7409   *
7410   * @retun {Number} Volume level percent
7411   * @method getPercent
7412   */
7413
7414  VolumeBar.prototype.getPercent = function getPercent() {
7415    if (this.player_.muted()) {
7416      return 0;
7417    } else {
7418      return this.player_.volume();
7419    }
7420  };
7421
7422  /**
7423   * Increase volume level for keyboard users
7424   *
7425   * @method stepForward
7426   */
7427
7428  VolumeBar.prototype.stepForward = function stepForward() {
7429    this.checkMuted();
7430    this.player_.volume(this.player_.volume() + 0.1);
7431  };
7432
7433  /**
7434   * Decrease volume level for keyboard users
7435   *
7436   * @method stepBack
7437   */
7438
7439  VolumeBar.prototype.stepBack = function stepBack() {
7440    this.checkMuted();
7441    this.player_.volume(this.player_.volume() - 0.1);
7442  };
7443
7444  /**
7445   * Update ARIA accessibility attributes
7446   *
7447   * @method updateARIAAttributes
7448   */
7449
7450  VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
7451    // Current value of volume bar as a percentage
7452    var volume = (this.player_.volume() * 100).toFixed(2);
7453    this.el_.setAttribute('aria-valuenow', volume);
7454    this.el_.setAttribute('aria-valuetext', volume + '%');
7455  };
7456
7457  return VolumeBar;
7458})(_sliderSliderJs2['default']);
7459
7460VolumeBar.prototype.options_ = {
7461  children: ['volumeLevel'],
7462  'barName': 'volumeLevel'
7463};
7464
7465VolumeBar.prototype.playerEvent = 'volumechange';
7466
7467_componentJs2['default'].registerComponent('VolumeBar', VolumeBar);
7468exports['default'] = VolumeBar;
7469module.exports = exports['default'];
7470
7471},{"../../component.js":66,"../../slider/slider.js":113,"../../utils/fn.js":133,"./volume-level.js":95}],94:[function(_dereq_,module,exports){
7472/**
7473 * @file volume-control.js
7474 */
7475'use strict';
7476
7477exports.__esModule = true;
7478
7479function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7480
7481function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7482
7483function _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; }
7484
7485var _componentJs = _dereq_('../../component.js');
7486
7487var _componentJs2 = _interopRequireDefault(_componentJs);
7488
7489// Required children
7490
7491var _volumeBarJs = _dereq_('./volume-bar.js');
7492
7493var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs);
7494
7495/**
7496 * The component for controlling the volume level
7497 *
7498 * @param {Player|Object} player
7499 * @param {Object=} options
7500 * @extends Component
7501 * @class VolumeControl
7502 */
7503
7504var VolumeControl = (function (_Component) {
7505  _inherits(VolumeControl, _Component);
7506
7507  function VolumeControl(player, options) {
7508    _classCallCheck(this, VolumeControl);
7509
7510    _Component.call(this, player, options);
7511
7512    // hide volume controls when they're not supported by the current tech
7513    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
7514      this.addClass('vjs-hidden');
7515    }
7516    this.on(player, 'loadstart', function () {
7517      if (player.tech_['featuresVolumeControl'] === false) {
7518        this.addClass('vjs-hidden');
7519      } else {
7520        this.removeClass('vjs-hidden');
7521      }
7522    });
7523  }
7524
7525  /**
7526   * Create the component's DOM element
7527   *
7528   * @return {Element}
7529   * @method createEl
7530   */
7531
7532  VolumeControl.prototype.createEl = function createEl() {
7533    return _Component.prototype.createEl.call(this, 'div', {
7534      className: 'vjs-volume-control vjs-control'
7535    });
7536  };
7537
7538  return VolumeControl;
7539})(_componentJs2['default']);
7540
7541VolumeControl.prototype.options_ = {
7542  children: ['volumeBar']
7543};
7544
7545_componentJs2['default'].registerComponent('VolumeControl', VolumeControl);
7546exports['default'] = VolumeControl;
7547module.exports = exports['default'];
7548
7549},{"../../component.js":66,"./volume-bar.js":93}],95:[function(_dereq_,module,exports){
7550/**
7551 * @file volume-level.js
7552 */
7553'use strict';
7554
7555exports.__esModule = true;
7556
7557function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7558
7559function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7560
7561function _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
7561onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7562
7563var _componentJs = _dereq_('../../component.js');
7564
7565var _componentJs2 = _interopRequireDefault(_componentJs);
7566
7567/**
7568 * Shows volume level
7569 *
7570 * @param {Player|Object} player
7571 * @param {Object=} options
7572 * @extends Component
7573 * @class VolumeLevel
7574 */
7575
7576var VolumeLevel = (function (_Component) {
7577  _inherits(VolumeLevel, _Component);
7578
7579  function VolumeLevel() {
7580    _classCallCheck(this, VolumeLevel);
7581
7582    _Component.apply(this, arguments);
7583  }
7584
7585  /**
7586   * Create the component's DOM element
7587   *
7588   * @return {Element}
7589   * @method createEl
7590   */
7591
7592  VolumeLevel.prototype.createEl = function createEl() {
7593    return _Component.prototype.createEl.call(this, 'div', {
7594      className: 'vjs-volume-level',
7595      innerHTML: '<span class="vjs-control-text"></span>'
7596    });
7597  };
7598
7599  return VolumeLevel;
7600})(_componentJs2['default']);
7601
7602_componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel);
7603exports['default'] = VolumeLevel;
7604module.exports = exports['default'];
7605
7606},{"../../component.js":66}],96:[function(_dereq_,module,exports){
7607/**
7608 * @file volume-menu-button.js
7609 */
7610'use strict';
7611
7612exports.__esModule = true;
7613
7614function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7615
7616function _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; } }
7617
7618function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7619
7620function _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; }
7621
7622var _utilsFnJs = _dereq_('../utils/fn.js');
7623
7624var Fn = _interopRequireWildcard(_utilsFnJs);
7625
7626var _componentJs = _dereq_('../component.js');
7627
7628var _componentJs2 = _interopRequireDefault(_componentJs);
7629
7630var _popupPopupJs = _dereq_('../popup/popup.js');
7631
7632var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs);
7633
7634var _popupPopupButtonJs = _dereq_('../popup/popup-button.js');
7635
7636var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs);
7637
7638var _muteToggleJs = _dereq_('./mute-toggle.js');
7639
7640var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
7641
7642var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js');
7643
7644var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs);
7645
7646var _globalDocument = _dereq_('global/document');
7647
7648var _globalDocument2 = _interopRequireDefault(_globalDocument);
7649
7650/**
7651 * Button for volume popup
7652 *
7653 * @param {Player|Object} player
7654 * @param {Object=} options
7655 * @extends PopupButton
7656 * @class VolumeMenuButton
7657 */
7658
7659var VolumeMenuButton = (function (_PopupButton) {
7660  _inherits(VolumeMenuButton, _PopupButton);
7661
7662  function VolumeMenuButton(player) {
7663    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7664
7665    _classCallCheck(this, VolumeMenuButton);
7666
7667    // Default to inline
7668    if (options.inline === undefined) {
7669      options.inline = true;
7670    }
7671
7672    // If the vertical option isn't passed at all, default to true.
7673    if (options.vertical === undefined) {
7674      // If an inline volumeMenuButton is used, we should default to using
7675      // a horizontal slider for obvious reasons.
7676      if (options.inline) {
7677        options.vertical = false;
7678      } else {
7679        options.vertical = true;
7680      }
7681    }
7682
7683    // The vertical option needs to be set on the volumeBar as well,
7684    // since that will need to be passed along to the VolumeBar constructor
7685    options.volumeBar = options.volumeBar || {};
7686    options.volumeBar.vertical = !!options.vertical;
7687
7688    _PopupButton.call(this, player, options);
7689
7690    // Same listeners as MuteToggle
7691    this.on(player, 'volumechange', this.volumeUpdate);
7692    this.on(player, 'loadstart', this.volumeUpdate);
7693
7694    // hide mute toggle if the current tech doesn't support volume control
7695    function updateVisibility() {
7696      if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
7697        this.addClass('vjs-hidden');
7698      } else {
7699        this.removeClass('vjs-hidden');
7700      }
7701    }
7702
7703    updateVisibility.call(this);
7704    this.on(player, 'loadstart', updateVisibility);
7705
7706    this.on(this.volumeBar, ['slideractive', 'focus'], function () {
7707      this.addClass('vjs-slider-active');
7708    });
7709
7710    this.on(this.volumeBar, ['sliderinactive', 'blur'], function () {
7711      this.removeClass('vjs-slider-active');
7712    });
7713
7714    this.on(this.volumeBar, ['focus'], function () {
7715      this.addClass('vjs-lock-showing');
7716    });
7717
7718    this.on(this.volumeBar, ['blur'], function () {
7719      this.removeClass('vjs-lock-showing');
7720    });
7721  }
7722
7723  /**
7724   * Allow sub components to stack CSS class names
7725   *
7726   * @return {String} The constructed class name
7727   * @method buildCSSClass
7728   */
7729
7730  VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
7731    var orientationClass = '';
7732    if (!!this.options_.vertical) {
7733      orientationClass = 'vjs-volume-menu-button-vertical';
7734    } else {
7735      orientationClass = 'vjs-volume-menu-button-horizontal';
7736    }
7737
7738    return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
7739  };
7740
7741  /**
7742   * Allow sub components to stack CSS class names
7743   *
7744   * @return {Popup} The volume popup button
7745   * @method createPopup
7746   */
7747
7748  VolumeMenuButton.prototype.createPopup = function createPopup() {
7749    var popup = new _popupPopupJs2['default'](this.player_, {
7750      contentElType: 'div'
7751    });
7752
7753    var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar);
7754
7755    popup.addChild(vb);
7756
7757    this.volumeBar = vb;
7758
7759    this.attachVolumeBarEvents();
7760
7761    return popup;
7762  };
7763
7764  /**
7765   * Handle click on volume popup and calls super
7766   *
7767   * @method handleClick
7768   */
7769
7770  VolumeMenuButton.prototype.handleClick = function handleClick() {
7771    _muteToggleJs2['default'].prototype.handleClick.call(this);
7772    _PopupButton.prototype.handleClick.call(this);
7773  };
7774
7775  VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
7776    this.on(['mousedown', 'touchdown'], this.handleMouseDown);
7777  };
7778
7779  VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
7780    this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
7781    this.on(_globalDocument2['default'], ['mouseup', 'touchend'], this.handleMouseUp);
7782  };
7783
7784  VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
7785    this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
7786  };
7787
7788  return VolumeMenuButton;
7789})(_popupPopupButtonJs2['default']);
7790
7791VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update;
7792VolumeMenuButton.prototype.controlText_ = 'Mute';
7793
7794_componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
7795exports['default'] = VolumeMenuButton;
7796module.exports = exports['default'];
7797
7798},{"../component.js":66,"../popup/popup-button.js":109,"../popup/popup.js":110,"../utils/fn.js":133,"./mute-toggle.js":70,"./volume-control/volume-bar.js":93,"global/document":1}],97:[function(_dereq_,module,exports){
7799/**
7800 * @file error-display.js
7801 */
7802'use strict';
7803
7804exports.__esModule = true;
7805
7806function _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; } }
7807
7808function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7809
7810function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
7811
7812function _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
7812onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
7813
7814var _component = _dereq_('./component');
7815
7816var _component2 = _interopRequireDefault(_component);
7817
7818var _modalDialog = _dereq_('./modal-dialog');
7819
7820var _modalDialog2 = _interopRequireDefault(_modalDialog);
7821
7822var _utilsDom = _dereq_('./utils/dom');
7823
7824var Dom = _interopRequireWildcard(_utilsDom);
7825
7826var _utilsMergeOptions = _dereq_('./utils/merge-options');
7827
7828var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
7829
7830/**
7831 * Display that an error has occurred making the video unplayable.
7832 *
7833 * @extends ModalDialog
7834 * @class ErrorDisplay
7835 */
7836
7837var ErrorDisplay = (function (_ModalDialog) {
7838  _inherits(ErrorDisplay, _ModalDialog);
7839
7840  /**
7841   * Constructor for error display modal.
7842   *
7843   * @param  {Player} player
7844   * @param  {Object} [options]
7845   */
7846
7847  function ErrorDisplay(player, options) {
7848    _classCallCheck(this, ErrorDisplay);
7849
7850    _ModalDialog.call(this, player, options);
7851    this.on(player, 'error', this.open);
7852  }
7853
7854  /**
7855   * Include the old class for backward-compatibility.
7856   *
7857   * This can be removed in 6.0.
7858   *
7859   * @method buildCSSClass
7860   * @deprecated
7861   * @return {String}
7862   */
7863
7864  ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
7865    return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
7866  };
7867
7868  /**
7869   * Generates the modal content based on the player error.
7870   *
7871   * @return {String|Null}
7872   */
7873
7874  ErrorDisplay.prototype.content = function content() {
7875    var error = this.player().error();
7876    return error ? this.localize(error.message) : '';
7877  };
7878
7879  return ErrorDisplay;
7880})(_modalDialog2['default']);
7881
7882ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, {
7883  fillAlways: true,
7884  temporary: false,
7885  uncloseable: true
7886});
7887
7888_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
7889exports['default'] = ErrorDisplay;
7890module.exports = exports['default'];
7891
7892},{"./component":66,"./modal-dialog":106,"./utils/dom":131,"./utils/merge-options":137}],98:[function(_dereq_,module,exports){
7893/**
7894 * @file event-target.js
7895 */
7896'use strict';
7897
7898exports.__esModule = true;
7899
7900function _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; } }
7901
7902var _utilsEventsJs = _dereq_('./utils/events.js');
7903
7904var Events = _interopRequireWildcard(_utilsEventsJs);
7905
7906var EventTarget = function EventTarget() {};
7907
7908EventTarget.prototype.allowedEvents_ = {};
7909
7910EventTarget.prototype.on = function (type, fn) {
7911  // Remove the addEventListener alias before calling Events.on
7912  // so we don't get into an infinite type loop
7913  var ael = this.addEventListener;
7914  this.addEventListener = Function.prototype;
7915  Events.on(this, type, fn);
7916  this.addEventListener = ael;
7917};
7918EventTarget.prototype.addEventListener = EventTarget.prototype.on;
7919
7920EventTarget.prototype.off = function (type, fn) {
7921  Events.off(this, type, fn);
7922};
7923EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
7924
7925EventTarget.prototype.one = function (type, fn) {
7926  Events.one(this, type, fn);
7927};
7928
7929EventTarget.prototype.trigger = function (event) {
7930  var type = event.type || event;
7931
7932  if (typeof event === 'string') {
7933    event = {
7934      type: type
7935    };
7936  }
7937  event = Events.fixEvent(event);
7938
7939  if (this.allowedEvents_[type] && this['on' + type]) {
7940    this['on' + type](event);
7941  }
7942
7943  Events.trigger(this, event);
7944};
7945// The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
7946EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
7947
7948exports['default'] = EventTarget;
7949module.exports = exports['default'];
7950
7951},{"./utils/events.js":132}],99:[function(_dereq_,module,exports){
7952'use strict';
7953
7954exports.__esModule = true;
7955
7956function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7957
7958var _utilsLog = _dereq_('./utils/log');
7959
7960var _utilsLog2 = _interopRequireDefault(_utilsLog);
7961
7962/*
7963 * @file extend.js
7964 *
7965 * A combination of node inherits and babel's inherits (after transpile).
7966 * Both work the same but node adds `super_` to the subClass
7967 * and Bable adds the superClass as __proto__. Both seem useful.
7968 */
7969var _inherits = function _inherits(subClass, superClass) {
7970  if (typeof superClass !== 'function' && superClass !== null) {
7971    throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
7972  }
7973
7974  subClass.prototype = Object.create(superClass && superClass.prototype, {
7975    constructor: {
7976      value: subClass,
7977      enumerable: false,
7978      writable: true,
7979      configurable: true
7980    }
7981  });
7982
7983  if (superClass) {
7984    // node
7985    subClass.super_ = superClass;
7986  }
7987};
7988
7989/*
7990 * Function for subclassing using the same inheritance that
7991 * videojs uses internally
7992 * ```js
7993 * var Button = videojs.getComponent('Button');
7994 * ```
7995 * ```js
7996 * var MyButton = videojs.extend(Button, {
7997 *   constructor: function(player, options) {
7998 *     Button.call(this, player, options);
7999 *   },
8000 *   onClick: function() {
8001 *     // doSomething
8002 *   }
8003 * });
8004 * ```
8005 */
8006var extendFn = function extendFn(superClass) {
8007  var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8008
8009  var subClass = function subClass() {
8010    superClass.apply(this, arguments);
8011  };
8012  var methods = {};
8013
8014  if (typeof subClassMethods === 'object') {
8015    if (typeof subClassMethods.init === 'function') {
8016      _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
8017      subClassMethods.constructor = subClassMethods.init;
8018    }
8019    if (subClassMethods.constructor !== Object.prototype.constructor) {
8020      subClass = subClassMethods.constructor;
8021    }
8022    methods = subClassMethods;
8023  } else if (typeof subClassMethods === 'function') {
8024    subClass = subClassMethods;
8025  }
8026
8027  _inherits(subClass, superClass);
8028
8029  // Extend subObj's prototype with functions and other properties from props
8030  for (var name in methods) {
8031    if (methods.hasOwnProperty(name)) {
8032      subClass.prototype[name] = methods[name];
8033    }
8034  }
8035
8036  return subClass;
8037};
8038
8039exports['default'] = extendFn;
8040module.exports = exports['default'];
8041
8042},{"./utils/log":136}],100:[function(_dereq_,module,exports){
8043/**
8044 * @file fullscreen-api.js
8045 */
8046'use strict';
8047
8048exports.__esModule = true;
8049
8050function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8051
8052var _globalDocument = _dereq_('global/document');
8053
8054var _globalDocument2 = _interopRequireDefault(_globalDocument);
8055
8056/*
8057 * Store the browser-specific methods for the fullscreen API
8058 * @type {Object|undefined}
8059 * @private
8060 */
8061var FullscreenApi = {};
8062
8063// browser API methods
8064// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
8065var apiMap = [
8066// Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
8067['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
8068// WebKit
8069['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
8070// Old WebKit (Safari 5.1)
8071['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
8072// Mozilla
8073['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
8074// Microsoft
8075['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
8076
8077var specApi = apiMap[0];
8078var browserApi = undefined;
8079
8080// determine the supported set of functions
8081for (var i = 0; i < apiMap.length; i++) {
8082  // check for exitFullscreen function
8083  if (apiMap[i][1] in _globalDocument2['default']) {
8084    browserApi = apiMap[i];
8085    break;
8086  }
8087}
8088
8089// map the browser API names to the spec API names
8090if (browserApi) {
8091  for (var i = 0; i < browserApi.length; i++) {
8092    FullscreenApi[specApi[i]] = browserApi[i];
8093  }
8094}
8095
8096exports['default'] = FullscreenApi;
8097module.exports = exports['default'];
8098
8099},{"global/document":1}],101:[function(_dereq_,module,exports){
8100/**
8101 * @file loading-spinner.js
8102 */
8103'use strict';
8104
8105exports.__esModule = true;
8106
8107function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8108
8109function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8110
8111function _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
8111onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8112
8113var _component = _dereq_('./component');
8114
8115var _component2 = _interopRequireDefault(_component);
8116
8117/* Loading Spinner
8118================================================================================ */
8119/**
8120 * Loading spinner for waiting events
8121 *
8122 * @extends Component
8123 * @class LoadingSpinner
8124 */
8125
8126var LoadingSpinner = (function (_Component) {
8127  _inherits(LoadingSpinner, _Component);
8128
8129  function LoadingSpinner() {
8130    _classCallCheck(this, LoadingSpinner);
8131
8132    _Component.apply(this, arguments);
8133  }
8134
8135  /**
8136   * Create the component's DOM element
8137   *
8138   * @method createEl
8139   */
8140
8141  LoadingSpinner.prototype.createEl = function createEl() {
8142    return _Component.prototype.createEl.call(this, 'div', {
8143      className: 'vjs-loading-spinner'
8144    });
8145  };
8146
8147  return LoadingSpinner;
8148})(_component2['default']);
8149
8150_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
8151exports['default'] = LoadingSpinner;
8152module.exports = exports['default'];
8153
8154},{"./component":66}],102:[function(_dereq_,module,exports){
8155/**
8156 * @file media-error.js
8157 */
8158'use strict';
8159
8160exports.__esModule = true;
8161
8162function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8163
8164var _objectAssign = _dereq_('object.assign');
8165
8166var _objectAssign2 = _interopRequireDefault(_objectAssign);
8167
8168/*
8169 * Custom MediaError to mimic the HTML5 MediaError
8170 *
8171 * @param {Number} code The media error code
8172 */
8173var MediaError = function MediaError(code) {
8174  if (typeof code === 'number') {
8175    this.code = code;
8176  } else if (typeof code === 'string') {
8177    // default code is zero, so this is a custom error
8178    this.message = code;
8179  } else if (typeof code === 'object') {
8180    // object
8181    _objectAssign2['default'](this, code);
8182  }
8183
8184  if (!this.message) {
8185    this.message = MediaError.defaultMessages[this.code] || '';
8186  }
8187};
8188
8189/*
8190 * The error code that refers two one of the defined
8191 * MediaError types
8192 *
8193 * @type {Number}
8194 */
8195MediaError.prototype.code = 0;
8196
8197/*
8198 * An optional message to be shown with the error.
8199 * Message is not part of the HTML5 video spec
8200 * but allows for more informative custom errors.
8201 *
8202 * @type {String}
8203 */
8204MediaError.prototype.message = '';
8205
8206/*
8207 * An optional status code that can be set by plugins
8208 * to allow even more detail about the error.
8209 * For example the HLS plugin might provide the specific
8210 * HTTP status code that was returned when the error
8211 * occurred, then allowing a custom error overlay
8212 * to display more information.
8213 *
8214 * @type {Array}
8215 */
8216MediaError.prototype.status = null;
8217
8218MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0
8219'MEDIA_ERR_ABORTED', // = 1
8220'MEDIA_ERR_NETWORK', // = 2
8221'MEDIA_ERR_DECODE', // = 3
8222'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4
8223'MEDIA_ERR_ENCRYPTED' // = 5
8224];
8225
8226MediaError.defaultMessages = {
8227  1: 'You aborted the media playback',
8228  2: 'A network error caused the media download to fail part-way.',
8229  3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
8230  4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
8231  5: 'The media is encrypted and we do not have the keys to decrypt it.'
8232};
8233
8234// Add types as properties on MediaError
8235// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
8236for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
8237  MediaError[MediaError.errorTypes[errNum]] = errNum;
8238  // values should be accessible on both the class and instance
8239  MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
8240}
8241
8242exports['default'] = MediaError;
8243module.exports = exports['default'];
8244
8245},{"object.assign":45}],103:[function(_dereq_,module,exports){
8246/**
8247 * @file menu-button.js
8248 */
8249'use strict';
8250
8251exports.__esModule = true;
8252
8253function _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; } }
8254
8255function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8256
8257function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8258
8259function _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; }
8260
8261var _clickableComponentJs = _dereq_('../clickable-component.js');
8262
8263var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
8264
8265var _componentJs = _dereq_('../component.js');
8266
8267var _componentJs2 = _interopRequireDefault(_componentJs);
8268
8269var _menuJs = _dereq_('./menu.js');
8270
8271var _menuJs2 = _interopRequireDefault(_menuJs);
8272
8273var _utilsDomJs = _dereq_('../utils/dom.js');
8274
8275var Dom = _interopRequireWildcard(_utilsDomJs);
8276
8277var _utilsFnJs = _dereq_('../utils/fn.js');
8278
8279var Fn = _interopRequireWildcard(_utilsFnJs);
8280
8281var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
8282
8283var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
8284
8285/**
8286 * A button class with a popup menu
8287 *
8288 * @param {Player|Object} player
8289 * @param {Object=} options
8290 * @extends Button
8291 * @class MenuButton
8292 */
8293
8294var MenuButton = (function (_ClickableComponent) {
8295  _inherits(MenuButton, _ClickableComponent);
8296
8297  function MenuButton(player) {
8298    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8299
8300    _classCallCheck(this, MenuButton);
8301
8302    _ClickableComponent.call(this, player, options);
8303
8304    this.update();
8305
8306    this.el_.setAttribute('aria-haspopup', true);
8307    this.el_.setAttribute('role', 'menuitem');
8308    this.on('keydown', this.handleSubmenuKeyPress);
8309  }
8310
8311  /**
8312   * Update menu
8313   *
8314   * @method update
8315   */
8316
8317  MenuButton.prototype.update = function update() {
8318    var menu = this.createMenu();
8319
8320    if (this.menu) {
8321      this.removeChild(this.menu);
8322    }
8323
8324    this.menu = menu;
8325    this.addChild(menu);
8326
8327    /**
8328     * Track the state of the menu button
8329     *
8330     * @type {Boolean}
8331     * @private
8332     */
8333    this.buttonPressed_ = false;
8334    this.el_.setAttribute('aria-expanded', false);
8335
8336    if (this.items && this.items.length === 0) {
8337      this.hide();
8338    } else if (this.items && this.items.length > 1) {
8339      this.show();
8340    }
8341  };
8342
8343  /**
8344   * Create menu
8345   *
8346   * @return {Menu} The constructed menu
8347   * @method createMenu
8348   */
8349
8350  MenuButton.prototype.createMenu = function createMenu() {
8351    var menu = new _menuJs2['default'](this.player_);
8352
8353    // Add a title list item to the top
8354    if (this.options_.title) {
8355      menu.contentEl().appendChild(Dom.createEl('li', {
8356        className: 'vjs-menu-title',
8357        innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title),
8358        tabIndex: -1
8359      }));
8360    }
8361
8362    this.items = this['createItems']();
8363
8364    if (this.items) {
8365      // Add menu items to the menu
8366      for (var i = 0; i < this.items.length; i++) {
8367        menu.addItem(this.items[i]);
8368      }
8369    }
8370
8371    return menu;
8372  };
8373
8374  /**
8375   * Create the list of menu items. Specific to each subclass.
8376   *
8377   * @method createItems
8378   */
8379
8380  MenuButton.prototype.createItems = function createItems() {};
8381
8382  /**
8383   * Create the component's DOM element
8384   *
8385   * @return {Element}
8386   * @method createEl
8387   */
8388
8389  MenuButton.prototype.createEl = function createEl() {
8390    return _ClickableComponent.prototype.createEl.call(this, 'div', {
8391      className: this.buildCSSClass()
8392    });
8393  };
8394
8395  /**
8396   * Allow sub components to stack CSS class names
8397   *
8398   * @return {String} The constructed class name
8399   * @method buildCSSClass
8400   */
8401
8402  MenuButton.prototype.buildCSSClass = function buildCSSClass() {
8403    var menuButtonClass = 'vjs-menu-button';
8404
8405    // If the inline option is passed, we want to use different styles altogether.
8406    if (this.options_.inline === true) {
8407      menuButtonClass += '-inline';
8408    } else {
8409      menuButtonClass += '-popup';
8410    }
8411
8412    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
8413  };
8414
8415  /**
8416   * When you click the button it adds focus, which
8417   * will show the menu indefinitely.
8418   * So we'll remove focus when the mouse leaves the button.
8419   * Focus is needed for tab navigation.
8420   * Allow sub components to stack CSS class names
8421   *
8422   * @method handleClick
8423   */
8424
8425  MenuButton.prototype.handleClick = function handleClick() {
8426    this.one('mouseout', Fn.bind(this, function () {
8427      this.menu.unlockShowing();
8428      this.el_.blur();
8429    }));
8430    if (this.buttonPressed_) {
8431      this.unpressButton();
8432    } else {
8433      this.pressButton();
8434    }
8435  };
8436
8437  /**
8438   * Handle key press on menu
8439   *
8440   * @param {Object} event Key press event
8441   * @method handleKeyPress
8442   */
8443
8444  MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
8445
8446    // Escape (27) key or Tab (9) key unpress the 'button'
8447    if (event.which === 27 || event.which === 9) {
8448      if (this.buttonPressed_) {
8449        this.unpressButton();
8450      }
8451      // Don't preventDefault for Tab key - we still want to lose focus
8452      if (event.which !== 9) {
8453        event.preventDefault();
8454      }
8455      // Up (38) key or Down (40) key press the 'button'
8456    } else if (event.which === 38 || event.which === 40) {
8457        if (!this.buttonPressed_) {
8458          this.pressButton();
8459          event.preventDefault();
8460        }
8461      } else {
8462        _ClickableComponent.prototype.handleKeyPress.call(this, event);
8463      }
8464  };
8465
8466  /**
8467   * Handle key press on submenu
8468   *
8469   * @param {Object} event Key press event
8470   * @method handleSubmenuKeyPress
8471   */
8472
8473  MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
8474
8475    // Escape (27) key or Tab (9) key unpress the 'button'
8476    if (event.which === 27 || event.which === 9) {
8477      if (this.buttonPressed_) {
8478        this.unpressButton();
8479      }
8480      // Don't preventDefault for Tab key - we still want to lose focus
8481      if (event.which !== 9) {
8482        event.preventDefault();
8483      }
8484    }
8485  };
8486
8487  /**
8488   * Makes changes based on button pressed
8489   *
8490   * @method pressButton
8491   */
8492
8493  MenuButton.prototype.pressButton = function pressButton() {
8494    this.buttonPressed_ = true;
8495    this.menu.lockShowing();
8496    this.el_.setAttribute('aria-expanded', true);
8497    this.menu.focus(); // set the focus into the submenu
8498  };
8499
8500  /**
8501   * Makes changes based on button unpressed
8502   *
8503   * @method unpressButton
8504   */
8505
8506  MenuButton.prototype.unpressButton = function unpressButton() {
8507    this.buttonPressed_ = false;
8508    this.menu.unlockShowing();
8509    this.el_.setAttribute('aria-expanded', false);
8510    this.el_.focus(); // Set focus back to this menu button
8511  };
8512
8513  return MenuButton;
8514})(_clickableComponentJs2['default']);
8515
8516_componentJs2['default'].registerComponent('MenuButton', MenuButton);
8517exports['default'] = MenuButton;
8518module.exports = exports['default'];
8519
8520},{"../clickable-component.js":64,"../component.js":66,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/to-title-case.js":140,"./menu.js":105}],104:[function(_dereq_,module,exports){
8521/**
8522 * @file menu-item.js
8523 */
8524'use strict';
8525
8526exports.__esModule = true;
8527
8528function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8529
8530function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8531
8532function _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; }
8533
8534var _clickableComponentJs = _dereq_('../clickable-component.js');
8535
8536var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
8537
8538var _componentJs = _dereq_('../component.js');
8539
8540var _componentJs2 = _interopRequireDefault(_componentJs);
8541
8542var _objectAssign = _dereq_('object.assign');
8543
8544var _objectAssign2 = _interopRequireDefault(_objectAssign);
8545
8546/**
8547 * The component for a menu item. `<li>`
8548 *
8549 * @param {Player|Object} player
8550 * @param {Object=} options
8551 * @extends Button
8552 * @class MenuItem
8553 */
8554
8555var MenuItem = (function (_ClickableComponent) {
8556  _inherits(MenuItem, _ClickableComponent);
8557
8558  function MenuItem(player, options) {
8559    _classCallCheck(this, MenuItem);
8560
8561    _ClickableComponent.call(this, player, options);
8562
8563    this.selectable = options['selectable'];
8564
8565    this.selected(options['selected']);
8566
8567    if (this.selectable) {
8568      // TODO: May need to be either menuitemcheckbox or menuitemradio,
8569      //       and may need logical grouping of menu items.
8570      this.el_.setAttribute('role', 'menuitemcheckbox');
8571    } else {
8572      this.el_.setAttribute('role', 'menuitem');
8573    }
8574  }
8575
8576  /**
8577   * Create the component's DOM element
8578   *
8579   * @param {String=} type Desc
8580   * @param {Object=} props Desc
8581   * @return {Element}
8582   * @method createEl
8583   */
8584
8585  MenuItem.prototype.createEl = function createEl(type, props, attrs) {
8586    return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({
8587      className: 'vjs-menu-item',
8588      innerHTML: this.localize(this.options_['label']),
8589      tabIndex: -1
8590    }, props), attrs);
8591  };
8592
8593  /**
8594   * Handle a click on the menu item, and set it to selected
8595   *
8596   * @method handleClick
8597   */
8598
8599  MenuItem.prototype.handleClick = function handleClick() {
8600    this.selected(true);
8601  };
8602
8603  /**
8604   * Set this menu item as selected or not
8605   *
8606   * @param  {Boolean} selected
8607   * @method selected
8608   */
8609
8610  MenuItem.prototype.selected = function selected(_selected) {
8611    if (this.selectable) {
8612      if (_selected) {
8613        this.addClass('vjs-selected');
8614        this.el_.setAttribute('aria-checked', true);
8615        // aria-checked isn't fully supported by browsers/screen readers,
8616        // so indicate selected state to screen reader in the control text.
8617        this.controlText(', selected');
8618      } else {
8619        this.removeClass('vjs-selected');
8620        this.el_.setAttribute('aria-checked', false);
8621        // Indicate un-selected state to screen reader
8622        // Note that a space clears out the selected state text
8623        this.controlText(' ');
8624      }
8625    }
8626  };
8627
8628  return MenuItem;
8629})(_clickableComponentJs2['default']);
8630
8631_componentJs2['default'].registerComponent('MenuItem', MenuItem);
8632exports['default'] = MenuItem;
8633module.exports = exports['default'];
8634
8635},{"../clickable-component.js":64,"../component.js":66,"object.assign":45}],105:[function(_dereq_,module,exports){
8636/**
8637 * @file menu.js
8638 */
8639'use strict';
8640
8641exports.__esModule = true;
8642
8643function _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; } }
8644
8645function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8646
8647function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8648
8649function _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
8649onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8650
8651var _componentJs = _dereq_('../component.js');
8652
8653var _componentJs2 = _interopRequireDefault(_componentJs);
8654
8655var _utilsDomJs = _dereq_('../utils/dom.js');
8656
8657var Dom = _interopRequireWildcard(_utilsDomJs);
8658
8659var _utilsFnJs = _dereq_('../utils/fn.js');
8660
8661var Fn = _interopRequireWildcard(_utilsFnJs);
8662
8663var _utilsEventsJs = _dereq_('../utils/events.js');
8664
8665var Events = _interopRequireWildcard(_utilsEventsJs);
8666
8667/**
8668 * The Menu component is used to build pop up menus, including subtitle and
8669 * captions selection menus.
8670 *
8671 * @extends Component
8672 * @class Menu
8673 */
8674
8675var Menu = (function (_Component) {
8676  _inherits(Menu, _Component);
8677
8678  function Menu(player, options) {
8679    _classCallCheck(this, Menu);
8680
8681    _Component.call(this, player, options);
8682
8683    this.focusedChild_ = -1;
8684
8685    this.on('keydown', this.handleKeyPress);
8686  }
8687
8688  /**
8689   * Add a menu item to the menu
8690   *
8691   * @param {Object|String} component Component or component type to add
8692   * @method addItem
8693   */
8694
8695  Menu.prototype.addItem = function addItem(component) {
8696    this.addChild(component);
8697    component.on('click', Fn.bind(this, function () {
8698      this.unlockShowing();
8699      //TODO: Need to set keyboard focus back to the menuButton
8700    }));
8701  };
8702
8703  /**
8704   * Create the component's DOM element
8705   *
8706   * @return {Element}
8707   * @method createEl
8708   */
8709
8710  Menu.prototype.createEl = function createEl() {
8711    var contentElType = this.options_.contentElType || 'ul';
8712    this.contentEl_ = Dom.createEl(contentElType, {
8713      className: 'vjs-menu-content'
8714    });
8715    this.contentEl_.setAttribute('role', 'menu');
8716    var el = _Component.prototype.createEl.call(this, 'div', {
8717      append: this.contentEl_,
8718      className: 'vjs-menu'
8719    });
8720    el.setAttribute('role', 'presentation');
8721    el.appendChild(this.contentEl_);
8722
8723    // Prevent clicks from bubbling up. Needed for Menu Buttons,
8724    // where a click on the parent is significant
8725    Events.on(el, 'click', function (event) {
8726      event.preventDefault();
8727      event.stopImmediatePropagation();
8728    });
8729
8730    return el;
8731  };
8732
8733  /**
8734   * Handle key press for menu
8735   *
8736   * @param {Object} event Event object
8737   * @method handleKeyPress
8738   */
8739
8740  Menu.prototype.handleKeyPress = function handleKeyPress(event) {
8741    if (event.which === 37 || event.which === 40) {
8742      // Left and Down Arrows
8743      event.preventDefault();
8744      this.stepForward();
8745    } else if (event.which === 38 || event.which === 39) {
8746      // Up and Right Arrows
8747      event.preventDefault();
8748      this.stepBack();
8749    }
8750  };
8751
8752  /**
8753   * Move to next (lower) menu item for keyboard users
8754   *
8755   * @method stepForward
8756   */
8757
8758  Menu.prototype.stepForward = function stepForward() {
8759    var stepChild = 0;
8760
8761    if (this.focusedChild_ !== undefined) {
8762      stepChild = this.focusedChild_ + 1;
8763    }
8764    this.focus(stepChild);
8765  };
8766
8767  /**
8768   * Move to previous (higher) menu item for keyboard users
8769   *
8770   * @method stepBack
8771   */
8772
8773  Menu.prototype.stepBack = function stepBack() {
8774    var stepChild = 0;
8775
8776    if (this.focusedChild_ !== undefined) {
8777      stepChild = this.focusedChild_ - 1;
8778    }
8779    this.focus(stepChild);
8780  };
8781
8782  /**
8783   * Set focus on a menu item in the menu
8784   *
8785   * @param {Object|String} item Index of child item set focus on
8786   * @method focus
8787   */
8788
8789  Menu.prototype.focus = function focus() {
8790    var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
8791
8792    var children = this.children();
8793
8794    if (children.length > 0) {
8795      if (item < 0) {
8796        item = 0;
8797      } else if (item >= children.length) {
8798        item = children.length - 1;
8799      }
8800
8801      this.focusedChild_ = item;
8802
8803      children[item].el_.focus();
8804    }
8805  };
8806
8807  return Menu;
8808})(_componentJs2['default']);
8809
8810_componentJs2['default'].registerComponent('Menu', Menu);
8811exports['default'] = Menu;
8812module.exports = exports['default'];
8813
8814},{"../component.js":66,"../utils/dom.js":131,"../utils/events.js":132,"../utils/fn.js":133}],106:[function(_dereq_,module,exports){
8815/**
8816 * @file modal-dialog.js
8817 */
8818'use strict';
8819
8820exports.__esModule = true;
8821
8822function _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; } }
8823
8824function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8825
8826function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
8827
8828function _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
8828onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8829
8830var _globalDocument = _dereq_('global/document');
8831
8832var _globalDocument2 = _interopRequireDefault(_globalDocument);
8833
8834var _utilsDom = _dereq_('./utils/dom');
8835
8836var Dom = _interopRequireWildcard(_utilsDom);
8837
8838var _utilsFn = _dereq_('./utils/fn');
8839
8840var Fn = _interopRequireWildcard(_utilsFn);
8841
8842var _utilsLog = _dereq_('./utils/log');
8843
8844var _utilsLog2 = _interopRequireDefault(_utilsLog);
8845
8846var _component = _dereq_('./component');
8847
8848var _component2 = _interopRequireDefault(_component);
8849
8850var _closeButton = _dereq_('./close-button');
8851
8852var _closeButton2 = _interopRequireDefault(_closeButton);
8853
8854var MODAL_CLASS_NAME = 'vjs-modal-dialog';
8855var ESC = 27;
8856
8857/**
8858 * The `ModalDialog` displays over the video and its controls, which blocks
8859 * interaction with the player until it is closed.
8860 *
8861 * Modal dialogs include a "Close" button and will close when that button
8862 * is activated - or when ESC is pressed anywhere.
8863 *
8864 * @extends Component
8865 * @class ModalDialog
8866 */
8867
8868var ModalDialog = (function (_Component) {
8869  _inherits(ModalDialog, _Component);
8870
8871  /**
8872   * Constructor for modals.
8873   *
8874   * @param  {Player} player
8875   * @param  {Object} [options]
8876   * @param  {Mixed} [options.content=undefined]
8877   *         Provide customized content for this modal.
8878   *
8879   * @param  {String} [options.description]
8880   *         A text description for the modal, primarily for accessibility.
8881   *
8882   * @param  {Boolean} [options.fillAlways=false]
8883   *         Normally, modals are automatically filled only the first time
8884   *         they open. This tells the modal to refresh its content
8885   *         every time it opens.
8886   *
8887   * @param  {String} [options.label]
8888   *         A text label for the modal, primarily for accessibility.
8889   *
8890   * @param  {Boolean} [options.temporary=true]
8891   *         If `true`, the modal can only be opened once; it will be
8892   *         disposed as soon as it's closed.
8893   *
8894   * @param  {Boolean} [options.uncloseable=false]
8895   *         If `true`, the user will not be able to close the modal
8896   *         through the UI in the normal ways. Programmatic closing is
8897   *         still possible.
8898   *
8899   */
8900
8901  function ModalDialog(player, options) {
8902    _classCallCheck(this, ModalDialog);
8903
8904    _Component.call(this, player, options);
8905    this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;
8906
8907    this.closeable(!this.options_.uncloseable);
8908    this.content(this.options_.content);
8909
8910    // Make sure the contentEl is defined AFTER any children are initialized
8911    // because we only want the contents of the modal in the contentEl
8912    // (not the UI elements like the close button).
8913    this.contentEl_ = Dom.createEl('div', {
8914      className: MODAL_CLASS_NAME + '-content'
8915    }, {
8916      role: 'document'
8917    });
8918
8919    this.descEl_ = Dom.createEl('p', {
8920      className: MODAL_CLASS_NAME + '-description vjs-offscreen',
8921      id: this.el().getAttribute('aria-describedby')
8922    });
8923
8924    Dom.textContent(this.descEl_, this.description());
8925    this.el_.appendChild(this.descEl_);
8926    this.el_.appendChild(this.contentEl_);
8927  }
8928
8929  /*
8930   * Modal dialog default options.
8931   *
8932   * @type {Object}
8933   * @private
8934   */
8935
8936  /**
8937   * Create the modal's DOM element
8938   *
8939   * @method createEl
8940   * @return {Element}
8941   */
8942
8943  ModalDialog.prototype.createEl = function createEl() {
8944    return _Component.prototype.createEl.call(this, 'div', {
8945      className: this.buildCSSClass(),
8946      tabIndex: -1
8947    }, {
8948      'aria-describedby': this.id() + '_description',
8949      'aria-hidden': 'true',
8950      'aria-label': this.label(),
8951      role: 'dialog'
8952    });
8953  };
8954
8955  /**
8956   * Build the modal's CSS class.
8957   *
8958   * @method buildCSSClass
8959   * @return {String}
8960   */
8961
8962  ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
8963    return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
8964  };
8965
8966  /**
8967   * Handles key presses on the document, looking for ESC, which closes
8968   * the modal.
8969   *
8970   * @method handleKeyPress
8971   * @param  {Event} e
8972   */
8973
8974  ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
8975    if (e.which === ESC && this.closeable()) {
8976      this.close();
8977    }
8978  };
8979
8980  /**
8981   * Returns the label string for this modal. Primarily used for accessibility.
8982   *
8983   * @return {String}
8984   */
8985
8986  ModalDialog.prototype.label = function label() {
8987    return this.options_.label || this.localize('Modal Window');
8988  };
8989
8990  /**
8991   * Returns the description string for this modal. Primarily used for
8992   * accessibility.
8993   *
8994   * @return {String}
8995   */
8996
8997  ModalDialog.prototype.description = function description() {
8998    var desc = this.options_.description || this.localize('This is a modal window.');
8999
9000    // Append a universal closeability message if the modal is closeable.
9001    if (this.closeable()) {
9002      desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
9003    }
9004
9005    return desc;
9006  };
9007
9008  /**
9009   * Opens the modal.
9010   *
9011   * @method open
9012   * @return {ModalDialog}
9013   */
9014
9015  ModalDialog.prototype.open = function open() {
9016    if (!this.opened_) {
9017      var player = this.player();
9018
9019      this.trigger('beforemodalopen');
9020      this.opened_ = true;
9021
9022      // Fill content if the modal has never opened before and
9023      // never been filled.
9024      if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
9025        this.fill();
9026      }
9027
9028      // If the player was playing, pause it and take note of its previously
9029      // playing state.
9030      this.wasPlaying_ = !player.paused();
9031
9032      if (this.wasPlaying_) {
9033        player.pause();
9034      }
9035
9036      if (this.closeable()) {
9037        this.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
9038      }
9039
9040      player.controls(false);
9041      this.show();
9042      this.el().setAttribute('aria-hidden', 'false');
9043      this.trigger('modalopen');
9044      this.hasBeenOpened_ = true;
9045    }
9046    return this;
9047  };
9048
9049  /**
9050   * Whether or not the modal is opened currently.
9051   *
9052   * @method opened
9053   * @param  {Boolean} [value]
9054   *         If given, it will open (`true`) or close (`false`) the modal.
9055   *
9056   * @return {Boolean}
9057   */
9058
9059  ModalDialog.prototype.opened = function opened(value) {
9060    if (typeof value === 'boolean') {
9061      this[value ? 'open' : 'close']();
9062    }
9063    return this.opened_;
9064  };
9065
9066  /**
9067   * Closes the modal.
9068   *
9069   * @method close
9070   * @return {ModalDialog}
9071   */
9072
9073  ModalDialog.prototype.close = function close() {
9074    if (this.opened_) {
9075      var player = this.player();
9076
9077      this.trigger('beforemodalclose');
9078      this.opened_ = false;
9079
9080      if (this.wasPlaying_) {
9081        player.play();
9082      }
9083
9084      if (this.closeable()) {
9085        this.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
9086      }
9087
9088      player.controls(true);
9089      this.hide();
9090      this.el().setAttribute('aria-hidden', 'true');
9091      this.trigger('modalclose');
9092
9093      if (this.options_.temporary) {
9094        this.dispose();
9095      }
9096    }
9097    return this;
9098  };
9099
9100  /**
9101   * Whether or not the modal is closeable via the UI.
9102   *
9103   * @method closeable
9104   * @param  {Boolean} [value]
9105   *         If given as a Boolean, it will set the `closeable` option.
9106   *
9107   * @return {Boolean}
9108   */
9109
9110  ModalDialog.prototype.closeable = function closeable(value) {
9111    if (typeof value === 'boolean') {
9112      var closeable = this.closeable_ = !!value;
9113      var _close = this.getChild('closeButton');
9114
9115      // If this is being made closeable and has no close button, add one.
9116      if (closeable && !_close) {
9117
9118        // The close button should be a child of the modal - not its
9119        // content element, so temporarily change the content element.
9120        var temp = this.contentEl_;
9121        this.contentEl_ = this.el_;
9122        _close = this.addChild('closeButton');
9123        this.contentEl_ = temp;
9124        this.on(_close, 'close', this.close);
9125      }
9126
9127      // If this is being made uncloseable and has a close button, remove it.
9128      if (!closeable && _close) {
9129        this.off(_close, 'close', this.close);
9130        this.removeChild(_close);
9131        _close.dispose();
9132      }
9133    }
9134    return this.closeable_;
9135  };
9136
9137  /**
9138   * Fill the modal's content element with the modal's "content" option.
9139   *
9140   * The content element will be emptied before this change takes place.
9141   *
9142   * @method fill
9143   * @return {ModalDialog}
9144   */
9145
9146  ModalDialog.prototype.fill = function fill() {
9147    return this.fillWith(this.content());
9148  };
9149
9150  /**
9151   * Fill the modal's content element with arbitrary content.
9152   *
9153   * The content element will be emptied before this change takes place.
9154   *
9155   * @method fillWith
9156   * @param  {Mixed} [content]
9157   *         The same rules apply to this as apply to the `content` option.
9158   *
9159   * @return {ModalDialog}
9160   */
9161
9162  ModalDialog.prototype.fillWith = function fillWith(content) {
9163    var contentEl = this.contentEl();
9164    var parentEl = contentEl.parentNode;
9165    var nextSiblingEl = contentEl.nextSibling;
9166
9167    this.trigger('beforemodalfill');
9168    this.hasBeenFilled_ = true;
9169
9170    // Detach the content element from the DOM before performing
9171    // manipulation to avoid modifying the live DOM multiple times.
9172    parentEl.removeChild(contentEl);
9173    this.empty();
9174    Dom.insertContent(contentEl, content);
9175    this.trigger('modalfill');
9176
9177    // Re-inject the re-filled content element.
9178    if (nextSiblingEl) {
9179      parentEl.insertBefore(contentEl, nextSiblingEl);
9180    } else {
9181      parentEl.appendChild(contentEl);
9182    }
9183
9184    return this;
9185  };
9186
9187  /**
9188   * Empties the content element.
9189   *
9190   * This happens automatically anytime the modal is filled.
9191   *
9192   * @method empty
9193   * @return {ModalDialog}
9194   */
9195
9196  ModalDialog.prototype.empty = function empty() {
9197    this.trigger('beforemodalempty');
9198    Dom.emptyEl(this.contentEl());
9199    this.trigger('modalempty');
9200    return this;
9201  };
9202
9203  /**
9204   * Gets or sets the modal content, which gets normalized before being
9205   * rendered into the DOM.
9206   *
9207   * This does not update the DOM or fill the modal, but it is called during
9208   * that process.
9209   *
9210   * @method content
9211   * @param  {Mixed} [value]
9212   *         If defined, sets the internal content value to be used on the
9213   *         next call(s) to `fill`. This value is normalized before being
9214   *         inserted. To "clear" the internal content value, pass `null`.
9215   *
9216   * @return {Mixed}
9217   */
9218
9219  ModalDialog.prototype.content = function content(value) {
9220    if (typeof value !== 'undefined') {
9221      this.content_ = value;
9222    }
9223    return this.content_;
9224  };
9225
9226  return ModalDialog;
9227})(_component2['default']);
9228
9229ModalDialog.prototype.options_ = {
9230  temporary: true
9231};
9232
9233_component2['default'].registerComponent('ModalDialog', ModalDialog);
9234exports['default'] = ModalDialog;
9235module.exports = exports['default'];
9236
9237},{"./close-button":65,"./component":66,"./utils/dom":131,"./utils/fn":133,"./utils/log":136,"global/document":1}],107:[function(_dereq_,module,exports){
9238/**
9239 * @file player.js
9240 */
9241// Subclasses Component
9242'use strict';
9243
9244exports.__esModule = true;
9245
9246function _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; } }
9247
9248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
9249
9250function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
9251
9252function _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
9252onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
9253
9254var _componentJs = _dereq_('./component.js');
9255
9256var _componentJs2 = _interopRequireDefault(_componentJs);
9257
9258var _globalDocument = _dereq_('global/document');
9259
9260var _globalDocument2 = _interopRequireDefault(_globalDocument);
9261
9262var _globalWindow = _dereq_('global/window');
9263
9264var _globalWindow2 = _interopRequireDefault(_globalWindow);
9265
9266var _utilsEventsJs = _dereq_('./utils/events.js');
9267
9268var Events = _interopRequireWildcard(_utilsEventsJs);
9269
9270var _utilsDomJs = _dereq_('./utils/dom.js');
9271
9272var Dom = _interopRequireWildcard(_utilsDomJs);
9273
9274var _utilsFnJs = _dereq_('./utils/fn.js');
9275
9276var Fn = _interopRequireWildcard(_utilsFnJs);
9277
9278var _utilsGuidJs = _dereq_('./utils/guid.js');
9279
9280var Guid = _interopRequireWildcard(_utilsGuidJs);
9281
9282var _utilsBrowserJs = _dereq_('./utils/browser.js');
9283
9284var browser = _interopRequireWildcard(_utilsBrowserJs);
9285
9286var _utilsLogJs = _dereq_('./utils/log.js');
9287
9288var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
9289
9290var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
9291
9292var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
9293
9294var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
9295
9296var _utilsBufferJs = _dereq_('./utils/buffer.js');
9297
9298var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
9299
9300var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
9301
9302var _fullscreenApiJs = _dereq_('./fullscreen-api.js');
9303
9304var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs);
9305
9306var _mediaErrorJs = _dereq_('./media-error.js');
9307
9308var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
9309
9310var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
9311
9312var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
9313
9314var _objectAssign = _dereq_('object.assign');
9315
9316var _objectAssign2 = _interopRequireDefault(_objectAssign);
9317
9318var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
9319
9320var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
9321
9322var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js');
9323
9324var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs);
9325
9326// Include required child components (importing also registers them)
9327
9328var _techLoaderJs = _dereq_('./tech/loader.js');
9329
9330var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs);
9331
9332var _posterImageJs = _dereq_('./poster-image.js');
9333
9334var _posterImageJs2 = _interopRequireDefault(_posterImageJs);
9335
9336var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js');
9337
9338var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs);
9339
9340var _loadingSpinnerJs = _dereq_('./loading-spinner.js');
9341
9342var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs);
9343
9344var _bigPlayButtonJs = _dereq_('./big-play-button.js');
9345
9346var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs);
9347
9348var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js');
9349
9350var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs);
9351
9352var _errorDisplayJs = _dereq_('./error-display.js');
9353
9354var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs);
9355
9356var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js');
9357
9358var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs);
9359
9360var _modalDialog = _dereq_('./modal-dialog');
9361
9362var _modalDialog2 = _interopRequireDefault(_modalDialog);
9363
9364// Require html5 tech, at least for disposing the original video tag
9365
9366var _techTechJs = _dereq_('./tech/tech.js');
9367
9368var _techTechJs2 = _interopRequireDefault(_techTechJs);
9369
9370var _techHtml5Js = _dereq_('./tech/html5.js');
9371
9372var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
9373
9374/**
9375 * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video.
9376 * ```js
9377 * var myPlayer = videojs('example_video_1');
9378 * ```
9379 * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready.
9380 * ```html
9381 * <video id="example_video_1" data-setup='{}' controls>
9382 *   <source src="my-source.mp4" type="video/mp4">
9383 * </video>
9384 * ```
9385 * After an instance has been created it can be accessed globally using `Video('example_video_1')`.
9386 *
9387 * @param {Element}
9387 tag        The original video tag used for configuring options
9388 * @param {Object=} options    Object of option names and values
9389 * @param {Function=} ready    Ready callback function
9390 * @extends Component
9391 * @class Player
9392 */
9393
9394var Player = (function (_Component) {
9395  _inherits(Player, _Component);
9396
9397  /**
9398   * player's constructor function
9399   *
9400   * @constructs
9401   * @method init
9402   * @param {Element} tag        The original video tag used for configuring options
9403   * @param {Object=} options    Player options
9404   * @param {Function=} ready    Ready callback function
9405   */
9406
9407  function Player(tag, options, ready) {
9408    var _this = this;
9409
9410    _classCallCheck(this, Player);
9411
9412    // Make sure tag ID exists
9413    tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
9414
9415    // Set Options
9416    // The options argument overrides options set in the video tag
9417    // which overrides globally set options.
9418    // This latter part coincides with the load order
9419    // (tag must exist before Player)
9420    options = _objectAssign2['default'](Player.getTagSettings(tag), options);
9421
9422    // Delay the initialization of children because we need to set up
9423    // player properties first, and can't use `this` before `super()`
9424    options.initChildren = false;
9425
9426    // Same with creating the element
9427    options.createEl = false;
9428
9429    // we don't want the player to report touch activity on itself
9430    // see enableTouchActivity in Component
9431    options.reportTouchActivity = false;
9432
9433    // Run base component initializing with new options
9434    _Component.call(this, null, options, ready);
9435
9436    // if the global option object was accidentally blown away by
9437    // someone, bail early with an informative error
9438    if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) {
9439      throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
9440    }
9441
9442    this.tag = tag; // Store the original tag used to set options
9443
9444    // Store the tag attributes used to restore html5 element
9445    this.tagAttributes = tag && Dom.getElAttributes(tag);
9446
9447    // Update current language
9448    this.language(this.options_.language);
9449
9450    // Update Supported Languages
9451    if (options.languages) {
9452      (function () {
9453        // Normalise player option languages to lowercase
9454        var languagesToLower = {};
9455
9456        Object.getOwnPropertyNames(options.languages).forEach(function (name) {
9457          languagesToLower[name.toLowerCase()] = options.languages[name];
9458        });
9459        _this.languages_ = languagesToLower;
9460      })();
9461    } else {
9462      this.languages_ = Player.prototype.options_.languages;
9463    }
9464
9465    // Cache for video property values.
9466    this.cache_ = {};
9467
9468    // Set poster
9469    this.poster_ = options.poster || '';
9470
9471    // Set controls
9472    this.controls_ = !!options.controls;
9473
9474    // Original tag settings stored in options
9475    // now remove immediately so native controls don't flash.
9476    // May be turned back on by HTML5 tech if nativeControlsForTouch is true
9477    tag.controls = false;
9478
9479    /*
9480     * Store the internal state of scrubbing
9481     *
9482     * @private
9483     * @return {Boolean} True if the user is scrubbing
9484     */
9485    this.scrubbing_ = false;
9486
9487    this.el_ = this.createEl();
9488
9489    // We also want to pass the original player options to each component and plugin
9490    // as well so they don't need to reach back into the player for options later.
9491    // We also need to do another copy of this.options_ so we don't end up with
9492    // an infinite loop.
9493    var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_);
9494
9495    // Load plugins
9496    if (options.plugins) {
9497      (function () {
9498        var plugins = options.plugins;
9499
9500        Object.getOwnPropertyNames(plugins).forEach(function (name) {
9501          if (typeof this[name] === 'function') {
9502            this[name](plugins[name]);
9503          } else {
9504            _utilsLogJs2['default'].error('Unable to find plugin:', name);
9505          }
9506        }, _this);
9507      })();
9508    }
9509
9510    this.options_.playerOptions = playerOptionsCopy;
9511
9512    this.initChildren();
9513
9514    // Set isAudio based on whether or not an audio tag was used
9515    this.isAudio(tag.nodeName.toLowerCase() === 'audio');
9516
9517    // Update controls className. Can't do this when the controls are initially
9518    // set because the element doesn't exist yet.
9519    if (this.controls()) {
9520      this.addClass('vjs-controls-enabled');
9521    } else {
9522      this.addClass('vjs-controls-disabled');
9523    }
9524
9525    if (this.isAudio()) {
9526      this.addClass('vjs-audio');
9527    }
9528
9529    if (this.flexNotSupported_()) {
9530      this.addClass('vjs-no-flex');
9531    }
9532
9533    // TODO: Make this smarter. Toggle user state between touching/mousing
9534    // using events, since devices can have both touch and mouse events.
9535    // if (browser.TOUCH_ENABLED) {
9536    //   this.addClass('vjs-touch-enabled');
9537    // }
9538
9539    // Make player easily findable by ID
9540    Player.players[this.id_] = this;
9541
9542    // When the player is first initialized, trigger activity so components
9543    // like the control bar show themselves if needed
9544    this.userActive(true);
9545    this.reportUserActivity();
9546    this.listenForUserActivity_();
9547
9548    this.on('fullscreenchange', this.handleFullscreenChange_);
9549    this.on('stageclick', this.handleStageClick_);
9550  }
9551
9552  /*
9553   * Global player list
9554   *
9555   * @type {Object}
9556   */
9557
9558  /**
9559   * Destroys the video player and does any necessary cleanup
9560   * ```js
9561   *     myPlayer.dispose();
9562   * ```
9563   * This is especially helpful if you are dynamically adding and removing videos
9564   * to/from the DOM.
9565   *
9566   * @method dispose
9567   */
9568
9569  Player.prototype.dispose = function dispose() {
9570    this.trigger('dispose');
9571    // prevent dispose from being called twice
9572    this.off('dispose');
9573
9574    if (this.styleEl_ && this.styleEl_.parentNode) {
9575      this.styleEl_.parentNode.removeChild(this.styleEl_);
9576    }
9577
9578    // Kill reference to this player
9579    Player.players[this.id_] = null;
9580    if (this.tag && this.tag.player) {
9581      this.tag.player = null;
9582    }
9583    if (this.el_ && this.el_.player) {
9584      this.el_.player = null;
9585    }
9586
9587    if (this.tech_) {
9588      this.tech_.dispose();
9589    }
9590
9591    _Component.prototype.dispose.call(this);
9592  };
9593
9594  /**
9595   * Create the component's DOM element
9596   *
9597   * @return {Element}
9598   * @method createEl
9599   */
9600
9601  Player.prototype.createEl = function createEl() {
9602    var el = this.el_ = _Component.prototype.createEl.call(this, 'div');
9603    var tag = this.tag;
9604
9605    // Remove width/height attrs from tag so CSS can make it 100% width/height
9606    tag.removeAttribute('width');
9607    tag.removeAttribute('height');
9608
9609    // Copy over all the attributes from the tag, including ID and class
9610    // ID will now reference player box, not the video tag
9611    var attrs = Dom.getElAttributes(tag);
9612
9613    Object.getOwnPropertyNames(attrs).forEach(function (attr) {
9614      // workaround so we don't totally break IE7
9615      // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
9616      if (attr === 'class') {
9617        el.className = attrs[attr];
9618      } else {
9619        el.setAttribute(attr, attrs[attr]);
9620      }
9621    });
9622
9623    // Update tag id/class for use as HTML5 playback tech
9624    // Might think we should do this after embedding in container so .vjs-tech class
9625    // doesn't flash 100% width/height, but class only applies with .video-js parent
9626    tag.playerId = tag.id;
9627    tag.id += '_html5_api';
9628    tag.className = 'vjs-tech';
9629
9630    // Make player findable on elements
9631    tag.player = el.player = this;
9632    // Default state of video is paused
9633    this.addClass('vjs-paused');
9634
9635    // Add a style element in the player that we'll use to set the width/height
9636    // of the player in a way that's still overrideable by CSS, just like the
9637    // video element
9638    this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
9639    var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
9640    var head = Dom.$('head');
9641    head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
9642
9643    // Pass in the width/height/aspectRatio options which will update the style el
9644    this.width(this.options_.width);
9645    this.height(this.options_.height);
9646    this.fluid(this.options_.fluid);
9647    this.aspectRatio(this.options_.aspectRatio);
9648
9649    // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
9650    // keep track of the original for later so we can know if the source originally failed
9651    tag.initNetworkState_ = tag.networkState;
9652
9653    // Wrap video tag in div (el/box) container
9654    if (tag.parentNode) {
9655      tag.parentNode.insertBefore(el, tag);
9656    }
9657
9658    // insert the tag as the first child of the player element
9659    // then manually add it to the children array so that this.addChild
9660    // will work properly for other components
9661    Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.
9662    this.children_.unshift(tag);
9663
9664    this.el_ = el;
9665
9666    return el;
9667  };
9668
9669  /**
9670   * Get/set player width
9671   *
9672   * @param {Number=} value Value for width
9673   * @return {Number} Width when getting
9674   * @method width
9675   */
9676
9677  Player.prototype.width = function width(value) {
9678    return this.dimension('width', value);
9679  };
9680
9681  /**
9682   * Get/set player height
9683   *
9684   * @param {Number=} value Value for height
9685   * @return {Number} Height when getting
9686   * @method height
9687   */
9688
9689  Player.prototype.height = function height(value) {
9690    return this.dimension('height', value);
9691  };
9692
9693  /**
9694   * Get/set dimension for player
9695   *
9696   * @param {String} dimension Either width or height
9697   * @param {Number=} value Value for dimension
9698   * @return {Component}
9699   * @method dimension
9700   */
9701
9702  Player.prototype.dimension = function dimension(_dimension, value) {
9703    var privDimension = _dimension + '_';
9704
9705    if (value === undefined) {
9706      return this[privDimension] || 0;
9707    }
9708
9709    if (value === '') {
9710      // If an empty string is given, reset the dimension to be automatic
9711      this[privDimension] = undefined;
9712    } else {
9713      var parsedVal = parseFloat(value);
9714
9715      if (isNaN(parsedVal)) {
9716        _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
9717        return this;
9718      }
9719
9720      this[privDimension] = parsedVal;
9721    }
9722
9723    this.updateStyleEl_();
9724    return this;
9725  };
9726
9727  /**
9728   * Add/remove the vjs-fluid class
9729   *
9730   * @param {Boolean} bool Value of true adds the class, value of false removes the class
9731   * @method fluid
9732   */
9733
9734  Player.prototype.fluid = function fluid(bool) {
9735    if (bool === undefined) {
9736      return !!this.fluid_;
9737    }
9738
9739    this.fluid_ = !!bool;
9740
9741    if (bool) {
9742      this.addClass('vjs-fluid');
9743    } else {
9744      this.removeClass('vjs-fluid');
9745    }
9746  };
9747
9748  /**
9749   * Get/Set the aspect ratio
9750   *
9751   * @param {String=} ratio Aspect ratio for player
9752   * @return aspectRatio
9753   * @method aspectRatio
9754   */
9755
9756  Player.prototype.aspectRatio = function aspectRatio(ratio) {
9757    if (ratio === undefined) {
9758      return this.aspectRatio_;
9759    }
9760
9761    // Check for width:height format
9762    if (!/^\d+\:\d+$/.test(ratio)) {
9763      throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
9764    }
9765    this.aspectRatio_ = ratio;
9766
9767    // We're assuming if you set an aspect ratio you want fluid mode,
9768    // because in fixed mode you could calculate width and height yourself.
9769    this.fluid(true);
9770
9771    this.updateStyleEl_();
9772  };
9773
9774  /**
9775   * Update styles of the player element (height, width and aspect ratio)
9776   *
9777   * @method updateStyleEl_
9778   */
9779
9780  Player.prototype.updateStyleEl_ = function updateStyleEl_() {
9781    var width = undefined;
9782    var height = undefined;
9783    var aspectRatio = undefined;
9784    var idClass = undefined;
9785
9786    // The aspect ratio is either used directly or to calculate width and height.
9787    if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
9788      // Use any aspectRatio that's been specifically set
9789      aspectRatio = this.aspectRatio_;
9790    } else if (this.videoWidth()) {
9791      // Otherwise try to get the aspect ratio from the video metadata
9792      aspectRatio = this.videoWidth() + ':' + this.videoHeight();
9793    } else {
9794      // Or use a default. The video element's is 2:1, but 16:9 is more common.
9795      aspectRatio = '16:9';
9796    }
9797
9798    // Get the ratio as a decimal we can use to calculate dimensions
9799    var ratioParts = aspectRatio.split(':');
9800    var ratioMultiplier = ratioParts[1] / ratioParts[0];
9801
9802    if (this.width_ !== undefined) {
9803      // Use any width that's been specifically set
9804      width = this.width_;
9805    } else if (this.height_ !== undefined) {
9806      // Or calulate the width from the aspect ratio if a height has been set
9807      width = this.height_ / ratioMultiplier;
9808    } else {
9809      // Or use the video's metadata, or use the video el's default of 300
9810      width = this.videoWidth() || 300;
9811    }
9812
9813    if (this.height_ !== undefined) {
9814      // Use any height that's been specifically set
9815      height = this.height_;
9816    } else {
9817      // Otherwise calculate the height from the ratio and the width
9818      height = width * ratioMultiplier;
9819    }
9820
9821    // Ensure the CSS class is valid by starting with an alpha character
9822    if (/^[^a-zA-Z]/.test(this.id())) {
9823      idClass = 'dimensions-' + this.id();
9824    } else {
9825      idClass = this.id() + '-dimensions';
9826    }
9827
9828    // Ensure the right class is still on the player for the style element
9829    this.addClass(idClass);
9830
9831    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    ');
9832  };
9833
9834  /**
9835   * Load the Media Playback Technology (tech)
9836   * Load/Create an instance of playback technology including element and API methods
9837   * And append playback element in player div.
9838   *
9839   * @param {String} techName Name of the playback technology
9840   * @param {String} source Video source
9841   * @method loadTech_
9842   * @private
9843   */
9844
9845  Player.prototype.loadTech_ = function loadTech_(techName, source) {
9846
9847    // Pause and remove current playback technology
9848    if (this.tech_) {
9849      this.unloadTech_();
9850    }
9851
9852    // get rid of the HTML5 video tag as soon as we are using another tech
9853    if (techName !== 'Html5' && this.tag) {
9854      _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag);
9855      this.tag.player = null;
9856      this.tag = null;
9857    }
9858
9859    this.techName_ = techName;
9860
9861    // Turn off API access because we're loading a new tech that might load asynchronously
9862    this.isReady_ = false;
9863
9864    // Grab tech-specific options from player options and add source and parent element to use.
9865    var techOptions = _objectAssign2['default']({
9866      'nativeControlsForTouch': this.options_.nativeControlsForTouch,
9867      'source': source,
9868      'playerId': this.id(),
9869      'techId': this.id() + '_' + techName + '_api',
9870      'textTracks': this.textTracks_,
9871      'autoplay': this.options_.autoplay,
9872      'preload': this.options_.preload,
9873      'loop': this.options_.loop,
9874      'muted': this.options_.muted,
9875      'poster': this.poster(),
9876      'language': this.language(),
9877      'vtt.js': this.options_['vtt.js']
9878    }, this.options_[techName.toLowerCase()]);
9879
9880    if (this.tag) {
9881      techOptions.tag = this.tag;
9882    }
9883
9884    if (source) {
9885      this.currentType_ = source.type;
9886      if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
9887        techOptions.startTime = this.cache_.currentTime;
9888      }
9889
9890      this.cache_.src = source.src;
9891    }
9892
9893    // Initialize tech instance
9894    var techComponent = _techTechJs2['default'].getTech(techName);
9895    // Support old behavior of techs being registered as components.
9896    // Remove once that deprecated behavior is removed.
9897    if (!techComponent) {
9898      techComponent = _componentJs2['default'].getComponent(techName);
9899    }
9900    this.tech_ = new techComponent(techOptions);
9901
9902    // player.triggerReady is always async, so don't need this to be async
9903    this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
9904
9905    _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
9906
9907    // Listen to all HTML5-defined events and trigger them on the player
9908    this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
9909    this.on(this.tech_, 'waiting', this.handleTechWaiting_);
9910    this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
9911    this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
9912    this.on(this.tech_, 'playing', this.handleTechPlaying_);
9913    this.on(this.tech_, 'ended', this.handleTechEnded_);
9914    this.on(this.tech_, 'seeking', this.handleTechSeeking_);
9915    this.on(this.tech_, 'seeked', this.handleTechSeeked_);
9916    this.on(this.tech_, 'play', this.handleTechPlay_);
9917    this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
9918    this.on(this.tech_, 'pause', this.handleTechPause_);
9919    this.on(this.tech_, 'progress', this.handleTechProgress_);
9920    this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
9921    this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
9922    this.on(this.tech_, 'error', this.handleTechError_);
9923    this.on(this.tech_, 'suspend', this.handleTechSuspend_);
9924    this.on(this.tech_, 'abort', this.handleTechAbort_);
9925    this.on(this.tech_, 'emptied', this.handleTechEmptied_);
9926    this.on(this.tech_, 'stalled', this.handleTechStalled_);
9927    this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_);
9928    this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_);
9929    this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_);
9930    this.on(this.tech_, 'ratechange', this.handleTechRateChange_);
9931    this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_);
9932    this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_);
9933    this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
9934    this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
9935
9936    this.usingNativeControls(this.techGet_('controls'));
9937
9938    if (this.controls() && !this.usingNativeControls()) {
9939      this.addTechControlsListeners_();
9940    }
9941
9942    // Add the tech element in the DOM if it was not already there
9943    // Make sure to not insert the original video element if using Html5
9944    if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
9945      Dom.insertElFirst(this.tech_.el(), this.el());
9946    }
9947
9948    // Get rid of the original video tag reference after the first tech is loaded
9949    if (this.tag) {
9950      this.tag.player = null;
9951      this.tag = null;
9952    }
9953  };
9954
9955  /**
9956   * Unload playback technology
9957   *
9958   * @method unloadTech_
9959   * @private
9960   */
9961
9962  Player.prototype.unloadTech_ = function unloadTech_() {
9963    // Save the current text tracks so that we can reuse the same text tracks with the next tech
9964    this.textTracks_ = this.textTracks();
9965    this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_);
9966
9967    this.isReady_ = false;
vendor: 16,384 bytes, lines 9968-10567
9968
9969    this.tech_.dispose();
9970
9971    this.tech_ = false;
9972  };
9973
9974  /**
9975   * Return a reference to the current tech.
9976   * It will only return a reference to the tech if given an object with the
9977   * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse
9978   * of techs by plugins.
9979   *
9980   * @param {Object}
9981   * @return {Object} The Tech
9982   * @method tech
9983   */
9984
9985  Player.prototype.tech = function tech(safety) {
9986    if (safety && safety.IWillNotUseThisInPlugins) {
9987      return this.tech_;
9988    }
9989    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    ';
9990    _globalWindow2['default'].alert(errorText);
9991    throw new Error(errorText);
9992  };
9993
9994  /**
9995   * Set up click and touch listeners for the playback element
9996   *
9997   * On desktops, a click on the video itself will toggle playback,
9998   * on a mobile device a click on the video toggles controls.
9999   * (toggling controls is done by toggling the user state between active and
10000   * inactive)
10001   * A tap can signal that a user has become active, or has become inactive
10002   * e.g. a quick tap on an iPhone movie should reveal the controls. Another
10003   * quick tap should hide them again (signaling the user is in an inactive
10004   * viewing state)
10005   * In addition to this, we still want the user to be considered inactive after
10006   * a few seconds of inactivity.
10007   * Note: the only part of iOS interaction we can't mimic with this setup
10008   * is a touch and hold on the video element counting as activity in order to
10009   * keep the controls showing, but that shouldn't be an issue. A touch and hold
10010   * on any controls will still keep the user active
10011   *
10012   * @private
10013   * @method addTechControlsListeners_
10014   */
10015
10016  Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
10017    // Make sure to remove all the previous listeners in case we are called multiple times.
10018    this.removeTechControlsListeners_();
10019
10020    // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
10021    // trigger mousedown/up.
10022    // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
10023    // Any touch events are set to block the mousedown event from happening
10024    this.on(this.tech_, 'mousedown', this.handleTechClick_);
10025
10026    // If the controls were hidden we don't want that to change without a tap event
10027    // so we'll check if the controls were already showing before reporting user
10028    // activity
10029    this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
10030    this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
10031    this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
10032
10033    // The tap listener needs to come after the touchend listener because the tap
10034    // listener cancels out any reportedUserActivity when setting userActive(false)
10035    this.on(this.tech_, 'tap', this.handleTechTap_);
10036  };
10037
10038  /**
10039   * Remove the listeners used for click and tap controls. This is needed for
10040   * toggling to controls disabled, where a tap/touch should do nothing.
10041   *
10042   * @method removeTechControlsListeners_
10043   * @private
10044   */
10045
10046  Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
10047    // We don't want to just use `this.off()` because there might be other needed
10048    // listeners added by techs that extend this.
10049    this.off(this.tech_, 'tap', this.handleTechTap_);
10050    this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
10051    this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
10052    this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
10053    this.off(this.tech_, 'mousedown', this.handleTechClick_);
10054  };
10055
10056  /**
10057   * Player waits for the tech to be ready
10058   *
10059   * @method handleTechReady_
10060   * @private
10061   */
10062
10063  Player.prototype.handleTechReady_ = function handleTechReady_() {
10064    this.triggerReady();
10065
10066    // Keep the same volume as before
10067    if (this.cache_.volume) {
10068      this.techCall_('setVolume', this.cache_.volume);
10069    }
10070
10071    // Look if the tech found a higher resolution poster while loading
10072    this.handleTechPosterChange_();
10073
10074    // Update the duration if available
10075    this.handleTechDurationChange_();
10076
10077    // Chrome and Safari both have issues with autoplay.
10078    // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
10079    // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
10080    // This fixes both issues. Need to wait for API, so it updates displays correctly
10081    if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
10082      delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
10083      this.play();
10084    }
10085  };
10086
10087  /**
10088   * Fired when the user agent begins looking for media data
10089   *
10090   * @private
10091   * @method handleTechLoadStart_
10092   */
10093
10094  Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
10095    // TODO: Update to use `emptied` event instead. See #1277.
10096
10097    this.removeClass('vjs-ended');
10098
10099    // reset the error state
10100    this.error(null);
10101
10102    // If it's already playing we want to trigger a firstplay event now.
10103    // The firstplay event relies on both the play and loadstart events
10104    // which can happen in any order for a new source
10105    if (!this.paused()) {
10106      this.trigger('loadstart');
10107      this.trigger('firstplay');
10108    } else {
10109      // reset the hasStarted state
10110      this.hasStarted(false);
10111      this.trigger('loadstart');
10112    }
10113  };
10114
10115  /**
10116   * Add/remove the vjs-has-started class
10117   *
10118   * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class
10119   * @return {Boolean} Boolean value if has started
10120   * @private
10121   * @method hasStarted
10122   */
10123
10124  Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10125    if (_hasStarted !== undefined) {
10126      // only update if this is a new value
10127      if (this.hasStarted_ !== _hasStarted) {
10128        this.hasStarted_ = _hasStarted;
10129        if (_hasStarted) {
10130          this.addClass('vjs-has-started');
10131          // trigger the firstplay event if this newly has played
10132          this.trigger('firstplay');
10133        } else {
10134          this.removeClass('vjs-has-started');
10135        }
10136      }
10137      return this;
10138    }
10139    return !!this.hasStarted_;
10140  };
10141
10142  /**
10143   * Fired whenever the media begins or resumes playback
10144   *
10145   * @private
10146   * @method handleTechPlay_
10147   */
10148
10149  Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10150    this.removeClass('vjs-ended');
10151    this.removeClass('vjs-paused');
10152    this.addClass('vjs-playing');
10153
10154    // hide the poster when the user hits play
10155    // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
10156    this.hasStarted(true);
10157
10158    this.trigger('play');
10159  };
10160
10161  /**
10162   * Fired whenever the media begins waiting
10163   *
10164   * @private
10165   * @method handleTechWaiting_
10166   */
10167
10168  Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10169    this.addClass('vjs-waiting');
10170    this.trigger('waiting');
10171  };
10172
10173  /**
10174   * A handler for events that signal that waiting has ended
10175   * which is not consistent between browsers. See #1351
10176   *
10177   * @private
10178   * @method handleTechCanPlay_
10179   */
10180
10181  Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10182    this.removeClass('vjs-waiting');
10183    this.trigger('canplay');
10184  };
10185
10186  /**
10187   * A handler for events that signal that waiting has ended
10188   * which is not consistent between browsers. See #1351
10189   *
10190   * @private
10191   * @method handleTechCanPlayThrough_
10192   */
10193
10194  Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10195    this.removeClass('vjs-waiting');
10196    this.trigger('canplaythrough');
10197  };
10198
10199  /**
10200   * A handler for events that signal that waiting has ended
10201   * which is not consistent between browsers. See #1351
10202   *
10203   * @private
10204   * @method handleTechPlaying_
10205   */
10206
10207  Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
10208    this.removeClass('vjs-waiting');
10209    this.trigger('playing');
10210  };
10211
10212  /**
10213   * Fired whenever the player is jumping to a new time
10214   *
10215   * @private
10216   * @method handleTechSeeking_
10217   */
10218
10219  Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
10220    this.addClass('vjs-seeking');
10221    this.trigger('seeking');
10222  };
10223
10224  /**
10225   * Fired when the player has finished jumping to a new time
10226   *
10227   * @private
10228   * @method handleTechSeeked_
10229   */
10230
10231  Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
10232    this.removeClass('vjs-seeking');
10233    this.trigger('seeked');
10234  };
10235
10236  /**
10237   * Fired the first time a video is played
10238   * Not part of the HLS spec, and we're not sure if this is the best
10239   * implementation yet, so use sparingly. If you don't have a reason to
10240   * prevent playback, use `myPlayer.one('play');` instead.
10241   *
10242   * @private
10243   * @method handleTechFirstPlay_
10244   */
10245
10246  Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
10247    //If the first starttime attribute is specified
10248    //then we will start at the given offset in seconds
10249    if (this.options_.starttime) {
10250      this.currentTime(this.options_.starttime);
10251    }
10252
10253    this.addClass('vjs-has-started');
10254    this.trigger('firstplay');
10255  };
10256
10257  /**
10258   * Fired whenever the media has been paused
10259   *
10260   * @private
10261   * @method handleTechPause_
10262   */
10263
10264  Player.prototype.handleTechPause_ = function handleTechPause_() {
10265    this.removeClass('vjs-playing');
10266    this.addClass('vjs-paused');
10267    this.trigger('pause');
10268  };
10269
10270  /**
10271   * Fired while the user agent is downloading media data
10272   *
10273   * @private
10274   * @method handleTechProgress_
10275   */
10276
10277  Player.prototype.handleTechProgress_ = function handleTechProgress_() {
10278    this.trigger('progress');
10279  };
10280
10281  /**
10282   * Fired when the end of the media resource is reached (currentTime == duration)
10283   *
10284   * @private
10285   * @method handleTechEnded_
10286   */
10287
10288  Player.prototype.handleTechEnded_ = function handleTechEnded_() {
10289    this.addClass('vjs-ended');
10290    if (this.options_.loop) {
10291      this.currentTime(0);
10292      this.play();
10293    } else if (!this.paused()) {
10294      this.pause();
10295    }
10296
10297    this.trigger('ended');
10298  };
10299
10300  /**
10301   * Fired when the duration of the media resource is first known or changed
10302   *
10303   * @private
10304   * @method handleTechDurationChange_
10305   */
10306
10307  Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
10308    this.duration(this.techGet_('duration'));
10309  };
10310
10311  /**
10312   * Handle a click on the media element to play/pause
10313   *
10314   * @param {Object=} event Event object
10315   * @private
10316   * @method handleTechClick_
10317   */
10318
10319  Player.prototype.handleTechClick_ = function handleTechClick_(event) {
10320    // We're using mousedown to detect clicks thanks to Flash, but mousedown
10321    // will also be triggered with right-clicks, so we need to prevent that
10322    if (event.button !== 0) return;
10323
10324    // When controls are disabled a click should not toggle playback because
10325    // the click is considered a control
10326    if (this.controls()) {
10327      if (this.paused()) {
10328        this.play();
10329      } else {
10330        this.pause();
10331      }
10332    }
10333  };
10334
10335  /**
10336   * Handle a tap on the media element. It will toggle the user
10337   * activity state, which hides and shows the controls.
10338   *
10339   * @private
10340   * @method handleTechTap_
10341   */
10342
10343  Player.prototype.handleTechTap_ = function handleTechTap_() {
10344    this.userActive(!this.userActive());
10345  };
10346
10347  /**
10348   * Handle touch to start
10349   *
10350   * @private
10351   * @method handleTechTouchStart_
10352   */
10353
10354  Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
10355    this.userWasActive = this.userActive();
10356  };
10357
10358  /**
10359   * Handle touch to move
10360   *
10361   * @private
10362   * @method handleTechTouchMove_
10363   */
10364
10365  Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
10366    if (this.userWasActive) {
10367      this.reportUserActivity();
10368    }
10369  };
10370
10371  /**
10372   * Handle touch to end
10373   *
10374   * @private
10375   * @method handleTechTouchEnd_
10376   */
10377
10378  Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
10379    // Stop the mouse events from also happening
10380    event.preventDefault();
10381  };
10382
10383  /**
10384   * Fired when the player switches in or out of fullscreen mode
10385   *
10386   * @private
10387   * @method handleFullscreenChange_
10388   */
10389
10390  Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
10391    if (this.isFullscreen()) {
10392      this.addClass('vjs-fullscreen');
10393    } else {
10394      this.removeClass('vjs-fullscreen');
10395    }
10396  };
10397
10398  /**
10399   * native click events on the SWF aren't triggered on IE11, Win8.1RT
10400   * use stageclick events triggered from inside the SWF instead
10401   *
10402   * @private
10403   * @method handleStageClick_
10404   */
10405
10406  Player.prototype.handleStageClick_ = function handleStageClick_() {
10407    this.reportUserActivity();
10408  };
10409
10410  /**
10411   * Handle Tech Fullscreen Change
10412   *
10413   * @private
10414   * @method handleTechFullscreenChange_
10415   */
10416
10417  Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
10418    if (data) {
10419      this.isFullscreen(data.isFullscreen);
10420    }
10421    this.trigger('fullscreenchange');
10422  };
10423
10424  /**
10425   * Fires when an error occurred during the loading of an audio/video
10426   *
10427   * @private
10428   * @method handleTechError_
10429   */
10430
10431  Player.prototype.handleTechError_ = function handleTechError_() {
10432    var error = this.tech_.error();
10433    this.error(error && error.code);
10434  };
10435
10436  /**
10437   * Fires when the browser is intentionally not getting media data
10438   *
10439   * @private
10440   * @method handleTechSuspend_
10441   */
10442
10443  Player.prototype.handleTechSuspend_ = function handleTechSuspend_() {
10444    this.trigger('suspend');
10445  };
10446
10447  /**
10448   * Fires when the loading of an audio/video is aborted
10449   *
10450   * @private
10451   * @method handleTechAbort_
10452   */
10453
10454  Player.prototype.handleTechAbort_ = function handleTechAbort_() {
10455    this.trigger('abort');
10456  };
10457
10458  /**
10459   * Fires when the current playlist is empty
10460   *
10461   * @private
10462   * @method handleTechEmptied_
10463   */
10464
10465  Player.prototype.handleTechEmptied_ = function handleTechEmptied_() {
10466    this.trigger('emptied');
10467  };
10468
10469  /**
10470   * Fires when the browser is trying to get media data, but data is not available
10471   *
10472   * @private
10473   * @method handleTechStalled_
10474   */
10475
10476  Player.prototype.handleTechStalled_ = function handleTechStalled_() {
10477    this.trigger('stalled');
10478  };
10479
10480  /**
10481   * Fires when the browser has loaded meta data for the audio/video
10482   *
10483   * @private
10484   * @method handleTechLoadedMetaData_
10485   */
10486
10487  Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() {
10488    this.trigger('loadedmetadata');
10489  };
10490
10491  /**
10492   * Fires when the browser has loaded the current frame of the audio/video
10493   *
10494   * @private
10495   * @method handleTechLoadedData_
10496   */
10497
10498  Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() {
10499    this.trigger('loadeddata');
10500  };
10501
10502  /**
10503   * Fires when the current playback position has changed
10504   *
10505   * @private
10506   * @method handleTechTimeUpdate_
10507   */
10508
10509  Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() {
10510    this.trigger('timeupdate');
10511  };
10512
10513  /**
10514   * Fires when the playing speed of the audio/video is changed
10515   *
10516   * @private
10517   * @method handleTechRateChange_
10518   */
10519
10520  Player.prototype.handleTechRateChange_ = function handleTechRateChange_() {
10521    this.trigger('ratechange');
10522  };
10523
10524  /**
10525   * Fires when the volume has been changed
10526   *
10527   * @private
10528   * @method handleTechVolumeChange_
10529   */
10530
10531  Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() {
10532    this.trigger('volumechange');
10533  };
10534
10535  /**
10536   * Fires when the text track has been changed
10537   *
10538   * @private
10539   * @method handleTechTextTrackChange_
10540   */
10541
10542  Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() {
10543    this.trigger('texttrackchange');
10544  };
10545
10546  /**
10547   * Get object for cached values.
10548   *
10549   * @return {Object}
10550   * @method getCache
10551   */
10552
10553  Player.prototype.getCache = function getCache() {
10554    return this.cache_;
10555  };
10556
10557  /**
10558   * Pass values to the playback tech
10559   *
10560   * @param {String=} method Method
10561   * @param {Object=} arg Argument
10562   * @private
10563   * @method techCall_
10564   */
10565
10566  Player.prototype.techCall_ = function techCall_(method, arg) {
10567    // 
10567If it's not ready yet, call method when it is
10568    if (this.tech_ && !this.tech_.isReady_) {
10569      this.tech_.ready(function () {
10570        this[method](arg);
10571      }, true);
10572
10573      // Otherwise call method now
10574    } else {
10575        try {
10576          this.tech_[method](arg);
10577        } catch (e) {
10578          _utilsLogJs2['default'](e);
10579          throw e;
10580        }
10581      }
10582  };
10583
10584  /**
10585   * Get calls can't wait for the tech, and sometimes don't need to.
10586   *
10587   * @param {String} method Tech method
10588   * @return {Method}
10589   * @private
10590   * @method techGet_
10591   */
10592
10593  Player.prototype.techGet_ = function techGet_(method) {
10594    if (this.tech_ && this.tech_.isReady_) {
10595
10596      // Flash likes to die and reload when you hide or reposition it.
10597      // In these cases the object methods go away and we get errors.
10598      // When that happens we'll catch the errors and inform tech that it's not ready any more.
10599      try {
10600        return this.tech_[method]();
10601      } catch (e) {
10602        // When building additional tech libs, an expected method may not be defined yet
10603        if (this.tech_[method] === undefined) {
10604          _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
10605        } else {
10606          // When a method isn't available on the object it throws a TypeError
10607          if (e.name === 'TypeError') {
10608            _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
10609            this.tech_.isReady_ = false;
10610          } else {
10611            _utilsLogJs2['default'](e);
10612          }
10613        }
10614        throw e;
10615      }
10616    }
10617
10618    return;
10619  };
10620
10621  /**
10622   * start media playback
10623   * ```js
10624   *     myPlayer.play();
10625   * ```
10626   *
10627   * @return {Player} self
10628   * @method play
10629   */
10630
10631  Player.prototype.play = function play() {
10632    this.techCall_('play');
10633    return this;
10634  };
10635
10636  /**
10637   * Pause the video playback
10638   * ```js
10639   *     myPlayer.pause();
10640   * ```
10641   *
10642   * @return {Player} self
10643   * @method pause
10644   */
10645
10646  Player.prototype.pause = function pause() {
10647    this.techCall_('pause');
10648    return this;
10649  };
10650
10651  /**
10652   * Check if the player is paused
10653   * ```js
10654   *     var isPaused = myPlayer.paused();
10655   *     var isPlaying = !myPlayer.paused();
10656   * ```
10657   *
10658   * @return {Boolean} false if the media is currently playing, or true otherwise
10659   * @method paused
10660   */
10661
10662  Player.prototype.paused = function paused() {
10663    // The initial state of paused should be true (in Safari it's actually false)
10664    return this.techGet_('paused') === false ? false : true;
10665  };
10666
10667  /**
10668   * Returns whether or not the user is "scrubbing". Scrubbing is when the user
10669   * has clicked the progress bar handle and is dragging it along the progress bar.
10670   *
10671   * @param  {Boolean} isScrubbing   True/false the user is scrubbing
10672   * @return {Boolean}               The scrubbing status when getting
10673   * @return {Object}                The player when setting
10674   * @method scrubbing
10675   */
10676
10677  Player.prototype.scrubbing = function scrubbing(isScrubbing) {
10678    if (isScrubbing !== undefined) {
10679      this.scrubbing_ = !!isScrubbing;
10680
10681      if (isScrubbing) {
10682        this.addClass('vjs-scrubbing');
10683      } else {
10684        this.removeClass('vjs-scrubbing');
10685      }
10686
10687      return this;
10688    }
10689
10690    return this.scrubbing_;
10691  };
10692
10693  /**
10694   * Get or set the current time (in seconds)
10695   * ```js
10696   *     // get
10697   *     var whereYouAt = myPlayer.currentTime();
10698   *     // set
10699   *     myPlayer.currentTime(120); // 2 minutes into the video
10700   * ```
10701   *
10702   * @param  {Number|String=} seconds The time to seek to
10703   * @return {Number}        The time in seconds, when not setting
10704   * @return {Player}    self, when the current time is set
10705   * @method currentTime
10706   */
10707
10708  Player.prototype.currentTime = function currentTime(seconds) {
10709    if (seconds !== undefined) {
10710
10711      this.techCall_('setCurrentTime', seconds);
10712
10713      return this;
10714    }
10715
10716    // cache last currentTime and return. default to 0 seconds
10717    //
10718    // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10719    // currentTime when scrubbing, but may not provide much performance benefit afterall.
10720    // Should be tested. Also something has to read the actual current time or the cache will
10721    // never get updated.
10722    return this.cache_.currentTime = this.techGet_('currentTime') || 0;
10723  };
10724
10725  /**
10726   * Get the length in time of the video in seconds
10727   * ```js
10728   *     var lengthOfVideo = myPlayer.duration();
10729   * ```
10730   * **NOTE**: The video must have started loading before the duration can be
10731   * known, and in the case of Flash, may not be known until the video starts
10732   * playing.
10733   *
10734   * @param {Number} seconds Duration when setting
10735   * @return {Number} The duration of the video in seconds when getting
10736   * @method duration
10737   */
10738
10739  Player.prototype.duration = function duration(seconds) {
10740    if (seconds === undefined) {
10741      return this.cache_.duration || 0;
10742    }
10743
10744    seconds = parseFloat(seconds) || 0;
10745
10746    // Standardize on Inifity for signaling video is live
10747    if (seconds < 0) {
10748      seconds = Infinity;
10749    }
10750
10751    if (seconds !== this.cache_.duration) {
10752      // Cache the last set value for optimized scrubbing (esp. Flash)
10753      this.cache_.duration = seconds;
10754
10755      if (seconds === Infinity) {
10756        this.addClass('vjs-live');
10757      } else {
10758        this.removeClass('vjs-live');
10759      }
10760
10761      this.trigger('durationchange');
10762    }
10763
10764    return this;
10765  };
10766
10767  /**
10768   * Calculates how much time is left.
10769   * ```js
10770   *     var timeLeft = myPlayer.remainingTime();
10771   * ```
10772   * Not a native video element function, but useful
10773   *
10774   * @return {Number} The time remaining in seconds
10775   * @method remainingTime
10776   */
10777
10778  Player.prototype.remainingTime = function remainingTime() {
10779    return this.duration() - this.currentTime();
10780  };
10781
10782  // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
10783  // Buffered returns a timerange object.
10784  // Kind of like an array of portions of the video that have been downloaded.
10785
10786  /**
10787   * Get a TimeRange object with the times of the video that have been downloaded
10788   * If you just want the percent of the video that's been downloaded,
10789   * use bufferedPercent.
10790   * ```js
10791   *     // Number of different ranges of time have been buffered. Usually 1.
10792   *     numberOfRanges = bufferedTimeRange.length,
10793   *     // Time in seconds when the first range starts. Usually 0.
10794   *     firstRangeStart = bufferedTimeRange.start(0),
10795   *     // Time in seconds when the first range ends
10796   *     firstRangeEnd = bufferedTimeRange.end(0),
10797   *     // Length in seconds of the first time range
10798   *     firstRangeLength = firstRangeEnd - firstRangeStart;
10799   * ```
10800   *
10801   * @return {Object} A mock TimeRange object (following HTML spec)
10802   * @method buffered
10803   */
10804
10805  Player.prototype.buffered = function buffered() {
10806    var buffered = this.techGet_('buffered');
10807
10808    if (!buffered || !buffered.length) {
10809      buffered = _utilsTimeRangesJs.createTimeRange(0, 0);
10810    }
10811
10812    return buffered;
10813  };
10814
10815  /**
10816   * Get the percent (as a decimal) of the video that's been downloaded
10817   * ```js
10818   *     var howMuchIsDownloaded = myPlayer.bufferedPercent();
10819   * ```
10820   * 0 means none, 1 means all.
10821   * (This method isn't in the HTML5 spec, but it's very convenient)
10822   *
10823   * @return {Number} A decimal between 0 and 1 representing the percent
10824   * @method bufferedPercent
10825   */
10826
10827  Player.prototype.bufferedPercent = function bufferedPercent() {
10828    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration());
10829  };
10830
10831  /**
10832   * Get the ending time of the last buffered time range
10833   * This is used in the progress bar to encapsulate all time ranges.
10834   *
10835   * @return {Number} The end of the last buffered time range
10836   * @method bufferedEnd
10837   */
10838
10839  Player.prototype.bufferedEnd = function bufferedEnd() {
10840    var buffered = this.buffered(),
10841        duration = this.duration(),
10842        end = buffered.end(buffered.length - 1);
10843
10844    if (end > duration) {
10845      end = duration;
10846    }
10847
10848    return end;
10849  };
10850
10851  /**
10852   * Get or set the current volume of the media
10853   * ```js
10854   *     // get
10855   *     var howLoudIsIt = myPlayer.volume();
10856   *     // set
10857   *     myPlayer.volume(0.5); // Set volume to half
10858   * ```
10859   * 0 is off (muted), 1.0 is all the way up, 0.5 is half way.
10860   *
10861   * @param  {Number} percentAsDecimal The new volume as a decimal percent
10862   * @return {Number}              The current volume when getting
10863   * @return {Player}              self when setting
10864   * @method volume
10865   */
10866
10867  Player.prototype.volume = function volume(percentAsDecimal) {
10868    var vol = undefined;
10869
10870    if (percentAsDecimal !== undefined) {
10871      vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
10872      this.cache_.volume = vol;
10873      this.techCall_('setVolume', vol);
10874
10875      return this;
10876    }
10877
10878    // Default to 1 when returning current volume.
10879    vol = parseFloat(this.techGet_('volume'));
10880    return isNaN(vol) ? 1 : vol;
10881  };
10882
10883  /**
10884   * Get the current muted state, or turn mute on or off
10885   * ```js
10886   *     // get
10887   *     var isVolumeMuted = myPlayer.muted();
10888   *     // set
10889   *     myPlayer.muted(true); // mute the volume
10890   * ```
10891   *
10892   * @param  {Boolean=} muted True to mute, false to unmute
10893   * @return {Boolean} True if mute is on, false if not when getting
10894   * @return {Player} self when setting mute
10895   * @method muted
10896   */
10897
10898  Player.prototype.muted = function muted(_muted) {
10899    if (_muted !== undefined) {
10900      this.techCall_('setMuted', _muted);
10901      return this;
10902    }
10903    return this.techGet_('muted') || false; // Default to false
10904  };
10905
10906  // Check if current tech can support native fullscreen
10907  // (e.g. with built in controls like iOS, so not our flash swf)
10908  /**
10909   * Check to see if fullscreen is supported
10910   *
10911   * @return {Boolean}
10912   * @method supportsFullScreen
10913   */
10914
10915  Player.prototype.supportsFullScreen = function supportsFullScreen() {
10916    return this.techGet_('supportsFullScreen') || false;
10917  };
10918
10919  /**
10920   * Check if the player is in fullscreen mode
10921   * ```js
10922   *     // get
10923   *     var fullscreenOrNot = myPlayer.isFullscreen();
10924   *     // set
10925   *     myPlayer.isFullscreen(true); // tell the player it's in fullscreen
10926   * ```
10927   * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
10928   * property and instead document.fullscreenElement is used. But isFullscreen is
10929   * still a valuable property for internal player workings.
10930   *
10931   * @param  {Boolean=} isFS Update the player's fullscreen state
10932   * @return {Boolean} true if fullscreen false if not when getting
10933   * @return {Player} self when setting
10934   * @method isFullscreen
10935   */
10936
10937  Player.prototype.isFullscreen = function isFullscreen(isFS) {
10938    if (isFS !== undefined) {
10939      this.isFullscreen_ = !!isFS;
10940      return this;
10941    }
10942    return !!this.isFullscreen_;
10943  };
10944
10945  /**
10946   * Increase the size of the video to full screen
10947   * ```js
10948   *     myPlayer.requestFullscreen();
10949   * ```
10950   * In some browsers, full screen is not supported natively, so it enters
10951   * "full window mode", where the video fills the browser window.
10952   * In browsers and devices that support native full screen, sometimes the
10953   * browser's default controls will be shown, and not the Video.js custom skin.
10954   * This includes most mobile devices (iOS, Android) and older versions of
10955   * Safari.
10956   *
10957   * @return {Player} self
10958   * @method requestFullscreen
10959   */
10960
10961  Player.prototype.requestFullscreen = function requestFullscreen() {
10962    var fsApi = _fullscreenApiJs2['default'];
10963
10964    this.isFullscreen(true);
10965
10966    if (fsApi.requestFullscreen) {
10967      // the browser supports going fullscreen at the element level so we can
10968      // take the controls fullscreen as well as the video
10969
10970      // Trigger fullscreenchange event after change
10971      // We have to specifically add this each time, and remove
10972      // when canceling fullscreen. Otherwise if there's multiple
10973      // players on a page, they would all be reacting to the same fullscreen
10974      // events
10975      Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
10976        this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]);
10977
10978        // If cancelling fullscreen, remove event listener.
10979        if (this.isFullscreen() === false) {
10980          Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange);
10981        }
10982
10983        this.trigger('fullscreenchange');
10984      }));
10985
10986      this.el_[fsApi.requestFullscreen]();
10987    } else if (this.tech_.supportsFullScreen()) {
10988      // we can't take the video.js controls fullscreen but we can go fullscreen
10989      // with native controls
10990      this.techCall_('enterFullScreen');
10991    } else {
10992      // fullscreen isn't supported so we'll just stretch the video element to
10993      // fill the viewport
10994      this.enterFullWindow();
10995      this.trigger('fullscreenchange');
10996    }
10997
10998    return this;
10999  };
11000
11001  /**
11002   * Return the video to its normal size after having been in full screen mode
11003   * ```js
11004   *     myPlayer.exitFullscreen();
11005   * ```
11006   *
11007   * @return {Player} self
11008   * @method exitFullscreen
11009   */
11010
11011  Player.prototype.exitFullscreen = function exitFullscreen() {
11012    var fsApi = _fullscreenApiJs2['default'];
11013    this.isFullscreen(false);
11014
11015    // Check for browser element fullscreen support
11016    if (fsApi.requestFullscreen) {
11017      _globalDocument2['default'][fsApi.exitFullscreen]();
11018    } else if (this.tech_.supportsFullScreen()) {
11019      this.techCall_('exitFullScreen');
11020    } else {
11021      this.exitFullWindow();
11022      this.trigger('fullscreenchange');
11023    }
11024
11025    return this;
11026  };
11027
11028  /**
11029   * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
11030   *
11031   * @method enterFullWindow
11032   */
11033
11034  Player.prototype.enterFullWindow = function enterFullWindow() {
11035    this.isFullWindow = true;
11036
11037    // Storing original doc overflow value to return to when fullscreen is off
11038    this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow;
11039
11040    // Add listener for esc key to exit fullscreen
11041    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
11042
11043    // Hide any scroll bars
11044    _globalDocument2['default'].documentElement.style.overflow = 'hidden';
11045
11046    // Apply fullscreen styles
11047    Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window');
11048
11049    this.trigger('enterFullWindow');
11050  };
11051
11052  /**
11053   * Check for call to either exit full window or full screen on ESC key
11054   *
11055   * @param {String} event Event to check for key press
11056   * @method fullWindowOnEscKey
11057   */
11058
11059  Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11060    if (event.keyCode === 27) {
11061      if (this.isFullscreen() === true) {
11062        this.exitFullscreen();
11063      } else {
11064        this.exitFullWindow();
11065      }
11066    }
11067  };
11068
11069  /**
11070   * Exit full window
11071   *
11072   * @method exitFullWindow
11073   */
11074
11075  Player.prototype.exitFullWindow = function exitFullWindow() {
11076    this.isFullWindow = false;
11077    Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey);
11078
11079    // Unhide scroll bars.
11080    _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow;
11081
11082    // Remove fullscreen styles
11083    Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window');
11084
11085    // Resize the box, controller, and poster to original sizes
11086    // this.positionAll();
11087    this.trigger('exitFullWindow');
11088  };
11089
11090  /**
11091   * Check whether the player can play a given mimetype
11092   *
11093   * @param {String} type The mimetype to check
11094   * @return {String} 'probably', 'maybe', or '' (empty string)
11095   * @method canPlayType
11096   */
11097
11098  Player.prototype.canPlayType = function canPlayType(type) {
11099    var can = undefined;
11100
11101    // Loop through each playback technology in the options order
11102    for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11103      var techName = _utilsToTitleCaseJs2['default'](j[i]);
11104      var tech = _techTechJs2['default'].getTech(techName);
11105
11106      // Support old behavior of techs being registered as components.
11107      // Remove once that deprecated behavior is removed.
11108      if (!tech) {
11109        tech = _componentJs2['default'].getComponent(techName);
11110      }
11111
11112      // Check if the current tech is defined before continuing
11113      if (!tech) {
11114        _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11115        continue;
11116      }
11117
11118      // Check if the browser supports this technology
11119      if (tech.isSupported()) {
11120        can = tech.canPlayType(type);
11121
11122        if (can) {
11123          return can;
11124        }
11125      }
11126    }
11127
11128    return '';
11129  };
11130
11131  /**
11132   * Select source based on tech-order or source-order
11133   * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11134   * defaults to tech-order selection
11135   *
11136   * @param {Array} sources The sources for a media asset
11137   * @return {Object|Boolean} Object of source and tech order, otherwise false
11138   * @method selectSource
11139   */
11140
11141  Player.prototype.selectSource = function selectSource(sources) {
11142    // Get only the techs specified in `techOrder` that exist and are supported by the
11143    // current platform
11144    var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) {
11145      // `Component.getComponent(...)` is for support of old behavior of techs
11146      // being registered as components.
11147      // Remove once that deprecated behavior is removed.
11148      return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)];
11149    }).filter(function (_ref) {
11150      var techName = _ref[0];
11151      var tech = _ref[1];
11152
11153      // Check if the current tech is defined before continuing
11154      if (tech) {
11155        // Check if the browser supports this technology
11156        return tech.isSupported();
11157      }
11158
11159      _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11160      return false;
11161    });
11162
11163    // Iterate over each `innerArray` element once per `outerArray` element and execute
11164    // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11165    // that value.
11166    var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11167      var found = undefined;
11168
11169      outerArray.some(function (outerChoice) {
11170        return innerArray.some(function (innerChoice) {
11171          found = tester(outerChoice, innerChoice);
11172
11173          if (found) {
11174            return true;
11175          }
11176        });
11177      });
11178
11179      return found;
11180    };
11181
11182    var foundSourceAndTech = undefined;
11183    var flip = function flip(fn) {
11184      return function (a, b) {
11185        return fn(b, a);
11186      };
11187    };
11188    var finder = function finder(_ref2, source) {
11189      var techName = _ref2[0];
11190      var tech = _ref2[1];
11191
11192      if (tech.canPlaySource(source)) {
11193        return { source: source, tech: techName };
11194      }
11195    };
11196
11197    // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11198    // to select from them based on their priority.
11199    if (this.options_.sourceOrder) {
11200      // Source-first ordering
11201      foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11202    } else {
11203      // Tech-first ordering
11204      foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11205    }
11206
11207    return foundSourceAndTech || false;
11208  };
11209
11210  /**
11211   * The source function updates the video source
11212   * There are three types of variables you can pass as the argument.
11213   * **URL String**: A URL to the the video file. Use this method if you are sure
11214   * the current playback technology (HTML5/Flash) can support the source you
11215   * provide. Currently only MP4 files can be used in both HTML5 and Flash.
11216   * ```js
11217   *     myPlayer.src("http://www.example.com/path/to/video.mp4");
11218   * ```
11219   * **Source Object (or element):* * A javascript object containing information
11220   * about the source file. Use this method if you want the player to determine if
11221   * it can support the file using the type information.
11222   * ```js
11223   *     myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" });
11224   * ```
11225   * **Array of Source Objects:* * To provide multiple versions of the source so
11226   * that it can be played using HTML5 across browsers you can use an array of
11227   * source objects. Video.js will detect which version is supported and load that
11228   * file.
11229   * ```js
11230   *     myPlayer.src([
11231   *       { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" },
11232   *       { type: "video/webm", src: "http://www.example.com/path/to/video.webm" },
11233   *       { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" }
11234   *     ]);
11235   * ```
11236   *
11237   * @param  {String|Object|Array=} source The source URL, object, or array of sources
11238   * @return {String} The current video source when getting
11239   * @return {String} The player when setting
11240   * @method src
11241   */
11242
11243  Player.prototype.src = function src(source) {
11244    if (source === undefined) {
11245      return this.techGet_('src');
11246    }
11247
11248    var currentTech = _techTechJs2['default'].getTech(this.techName_);
11249    // Support old behavior of techs being registered as components.
11250    // Remove once that deprecated behavior is removed.
11251    if (!currentTech) {
11252      currentTech = _componentJs2['default'].getComponent(this.techName_);
11253    }
11254
11255    // case: Array of source objects to choose from and pick the best to play
11256    if (Array.isArray(source)) {
11257      this.sourceList_(source);
11258
11259      // case: URL String (http://myvideo...)
11260    } else if (typeof source === 'string') {
11261        // create a source object from the string
11262        this.src({ src: source });
11263
11264        // case: Source object { src: '', type: '' ... }
11265      } else if (source instanceof Object) {
11266          // check if the source has a type and the loaded tech cannot play the source
11267          // if there's no type we'll just try the current tech
11268          if (source.type && !currentTech.canPlaySource(source)) {
11269            // create a source list with the current source and send through
11270            // the tech loop to check for a compatible technology
11271            this.sourceList_([source]);
11272          } else {
11273            this.cache_.src = source.src;
11274            this.currentType_ = source.type || '';
11275
11276            // wait until the tech is ready to set the source
11277            this.ready(function () {
11278
11279              // The setSource tech method was added with source handlers
11280              // so older techs won't support it
11281              // We need to check the direct prototype for the case where subclasses
11282              // of the tech do not support source handlers
11283              if (currentTech.prototype.hasOwnProperty('setSource')) {
11284                this.techCall_('setSource', source);
11285              } else {
11286                this.techCall_('src', source.src);
11287              }
11288
11289              if (this.options_.preload === 'auto') {
11290                this.load();
11291              }
11292
11293              if (this.options_.autoplay) {
11294                this.play();
11295              }
11296
11297              // Set the source synchronously if possible (#2326)
11298            }, true);
11299          }
11300        }
11301
11302    return this;
11303  };
11304
11305  /**
11306   * Handle an array of source objects
11307   *
11308   * @param  {Array} sources Array of source objects
11309   * @private
11310   * @method sourceList_
11311   */
11312
11313  Player.prototype.sourceList_ = function sourceList_(sources) {
11314    var sourceTech = this.selectSource(sources);
11315
11316    if (sourceTech) {
11317      if (sourceTech.tech === this.techName_) {
11318        // if this technology is already loaded, set the source
11319        this.src(sourceTech.source);
11320      } else {
11321        // load this technology with the chosen source
11322        this.loadTech_(sourceTech.tech, sourceTech.source);
11323      }
11324    } else {
11325      // We need to wrap this in a timeout to give folks a chance to add error event handlers
11326      this.setTimeout(function () {
11327        this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
11328      }, 0);
11329
11330      // we could not find an appropriate tech, but let's still notify the delegate that this is it
11331      // this needs a better comment about why this is needed
11332      this.triggerReady();
11333    }
11334  };
11335
11336  /**
11337   * Begin loading the src data.
11338   *
11339   * @return {Player} Returns the player
11340   * @method load
11341   */
11342
11343  Player.prototype.load = function load() {
11344    this.techCall_('load');
11345    return this;
11346  };
11347
11348  /**
11349   * Reset the player. Loads the first tech in the techOrder,
11350   * and calls `reset` on the tech`.
11351   *
11352   * @return {Player} Returns the player
11353   * @method reset
11354   */
11355
11356  Player.prototype.reset = function reset() {
11357    this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null);
11358    this.techCall_('reset');
11359    return this;
11360  };
11361
11362  /**
11363   * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
11364   * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
11365   *
11366   * @return {String} The current source
11367   * @method currentSrc
11368   */
11369
11370  Player.prototype.currentSrc = function currentSrc() {
11371    return this.techGet_('currentSrc') || this.cache_.src || '';
11372  };
11373
11374  /**
11375   * Get the current source type e.g. video/mp4
11376   * This can allow you rebuild the current source object so that you could load the same
11377   * source and tech later
11378   *
11379   * @return {String} The source MIME type
11380   * @method currentType
11381   */
11382
11383  Player.prototype.currentType = function currentType() {
11384    return this.currentType_ || '';
11385  };
11386
11387  /**
11388   * Get or set the preload attribute
11389   *
11390   * @param {Boolean} value Boolean to determine if preload should be used
11391   * @return {String} The preload attribute value when getting
11392   * @return {Player} Returns the player when setting
11393   * @method preload
11394   */
11395
11396  Player.prototype.preload = function preload(value) {
11397    if (value !== undefined) {
11398      this.techCall_('setPreload', value);
11399      this.options_.preload = value;
11400      return this;
11401    }
11402    return this.techGet_('preload');
11403  };
11404
11405  /**
11406   * Get or set the autoplay attribute.
11407   *
11408   * @param {Boolean} value Boolean to determine if video should autoplay
11409   * @return {String} The autoplay attribute value when getting
11410   * @return {Player} Returns the player when setting
11411   * @method autoplay
11412   */
11413
11414  Player.prototype.autoplay = function autoplay(value) {
11415    if (value !== undefined) {
11416      this.techCall_('setAutoplay', value);
11417      this.options_.autoplay = value;
11418      return this;
11419    }
11420    return this.techGet_('autoplay', value);
11421  };
11422
11423  /**
11424   * Get or set the loop attribute on the video element.
11425   *
11426   * @param {Boolean} value Boolean to determine if video should loop
11427   * @return {String} The loop attribute value when getting
11428   * @return {Player} Returns the player when setting
11429   * @method loop
11430   */
11431
11432  Player.prototype.loop = function loop(value) {
11433    if (value !== undefined) {
11434      this.techCall_('setLoop', value);
11435      this.options_['loop'] = value;
11436      return this;
11437    }
11438    return this.techGet_('loop');
11439  };
11440
11441  /**
11442   * Get or set the poster image source url
11443   *
11444   * ##### EXAMPLE:
11445   * ```js
11446   *     // get
11447   *     var currentPoster = myPlayer.poster();
11448   *     // set
11449   *     myPlayer.poster('http://example.com/myImage.jpg');
11450   * ```
11451   *
11452   * @param  {String=} src Poster image source URL
11453   * @return {String} poster URL when getting
11454   * @return {Player} self when setting
11455   * @method poster
11456   */
11457
11458  Player.prototype.poster = function poster(src) {
11459    if (src === undefined) {
11460      return this.poster_;
11461    }
11462
11463    // The correct way to remove a poster is to set as an empty string
11464    // other falsey values will throw errors
11465    if (!src) {
11466      src = '';
11467    }
11468
11469    // update the internal poster variable
11470    this.poster_ = src;
11471
11472    // update the tech's poster
11473    this.techCall_('setPoster', src);
11474
11475    // alert components that the poster has been set
11476    this.trigger('posterchange');
11477
11478    return this;
11479  };
11480
11481  /**
11482   * Some techs (e.g. YouTube) can provide a poster source in an
11483   * asynchronous way. We want the poster component to use this
11484   * poster source so that it covers up the tech's controls.
11485   * (YouTube's play button). However we only want to use this
11486   * soruce if the player user hasn't set a poster through
11487   * the normal APIs.
11488   *
11489   * @private
11490   * @method handleTechPosterChange_
11491   */
11492
11493  Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
11494    if (!this.poster_ && this.tech_ && this.tech_.poster) {
11495      this.poster_ = this.tech_.poster() || '';
11496
11497      // Let components know the poster has changed
11498      this.trigger('posterchange');
11499    }
11500  };
11501
11502  /**
11503   * Get or set whether or not the controls are showing.
11504   *
11505   * @param  {Boolean} bool Set controls to showing or not
11506   * @return {Boolean}    Controls are showing
11507   * @method controls
11508   */
11509
11510  Player.prototype.controls = function controls(bool) {
11511    if (bool !== undefined) {
11512      bool = !!bool; // force boolean
11513      // Don't trigger a change event unless it actually changed
11514      if (this.controls_ !== bool) {
11515        this.controls_ = bool;
11516
11517        if (this.usingNativeControls()) {
11518          this.techCall_('setControls', bool);
11519        }
11520
11521        if (bool) {
11522          this.removeClass('vjs-controls-disabled');
11523          this.addClass('vjs-controls-enabled');
11524          this.trigger('controlsenabled');
11525
11526          if (!this.usingNativeControls()) {
11527            this.addTechControlsListeners_();
11528          }
11529        } else {
11530          this.removeClass('vjs-controls-enabled');
11531          this.addClass('vjs-controls-disabled');
11532          this.trigger('controlsdisabled');
11533
11534          if (!this.usingNativeControls()) {
11535            this.removeTechControlsListeners_();
11536          }
11537        }
11538      }
11539      return this;
11540    }
11541    return !!this.controls_;
11542  };
11543
11544  /**
11545   * Toggle native controls on/off. Native controls are the controls built into
11546   * devices (e.g. default iPhone controls), Flash, or other techs
11547   * (e.g. Vimeo Controls)
11548   * **This should only be set by the current tech, because only the tech knows
11549   * if it can support native controls**
11550   *
11551   * @param  {Boolean} bool    True signals that native controls are on
11552   * @return {Player}      Returns the player
11553   * @private
11554   * @method usingNativeControls
11555   */
11556
11557  Player.prototype.usingNativeControls = function usingNativeControls(bool) {
11558    if (bool !== undefined) {
11559      bool = !!bool; // force boolean
11560      // Don't trigger a change event unless it actually changed
11561      if (this.usingNativeControls_ !== bool) {
11562        this.usingNativeControls_ = bool;
11563        if (bool) {
11564          this.addClass('vjs-using-native-controls');
11565
11566          /**
11567            * player is using the native device controls
11568           *
11569            * @event usingnativecontrols
11570            * @memberof Player
11571            * @instance
11572            * @private
11573            */
11574          this.trigger('usingnativecontrols');
11575        } else {
11576          this.removeClass('vjs-using-native-controls');
11577
11578          /**
11579            * player is using the custom HTML controls
11580           *
11581            * @event usingcustomcontrols
11582            * @memberof Player
11583            * @instance
11584            * @private
11585            */
11586          this.trigger('usingcustomcontrols');
11587        }
11588      }
11589      return this;
11590    }
11591    return !!this.usingNativeControls_;
11592  };
11593
11594  /**
11595   * Set or get the current MediaError
11596   *
11597   * @param  {*} err A MediaError or a String/Number to be turned into a MediaError
11598   * @return {MediaError|null}     when getting
11599   * @return {Player}              when setting
11600   * @method error
11601   */
11602
11603  Player.prototype.error = function error(err) {
11604    if (err === undefined) {
11605      return this.error_ || null;
11606    }
11607
11608    // restoring to default
11609    if (err === null) {
11610      this.error_ = err;
11611      this.removeClass('vjs-error');
11612      this.errorDisplay.close();
11613      return this;
11614    }
11615
11616    // error instance
11617    if (err instanceof _mediaErrorJs2['default']) {
11618      this.error_ = err;
11619    } else {
11620      this.error_ = new _mediaErrorJs2['default'](err);
11621    }
11622
11623    // add the vjs-error classname to the player
11624    this.addClass('vjs-error');
11625
11626    // log the name of the error type and any message
11627    // ie8 just logs "[object object]" if you just log the error object
11628    _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
11629
11630    // fire an error event on the player
11631    this.trigger('error');
11632
11633    return this;
11634  };
11635
11636  /**
11637   * Returns whether or not the player is in the "ended" state.
11638   *
11639   * @return {Boolean} True if the player is in the ended state, false if not.
11640   * @method ended
11641   */
11642
11643  Player.prototype.ended = function ended() {
11644    return this.techGet_('ended');
11645  };
11646
11647  /**
11648   * Returns whether or not the player is in the "seeking" state.
11649   *
11650   * @return {Boolean} True if the player is in the seeking state, false if not.
11651   * @method seeking
11652   */
11653
11654  Player.prototype.seeking = function seeking() {
11655    return this.techGet_('seeking');
11656  };
11657
11658  /**
11659   * Returns the TimeRanges of the media that are currently available
11660   * for seeking to.
11661   *
11662   * @return {TimeRanges} the seekable intervals of the media timeline
11663   * @method seekable
11664   */
11665
11666  Player.prototype.seekable = function seekable() {
11667    return this.techGet_('seekable');
11668  };
11669
11670  /**
11671   * Report user activity
11672   *
11673   * @param {Object} event Event object
11674   * @method reportUserActivity
11675   */
11676
11677  Player.prototype.reportUserActivity = function reportUserActivity(event) {
11678    this.userActivity_ = true;
11679  };
11680
11681  /**
11682   * Get/set if user is active
11683   *
11684   * @param {Boolean} bool Value when setting
11685   * @return {Boolean} Value if user is active user when getting
11686   * @method userActive
11687   */
11688
11689  Player.prototype.userActive = function userActive(bool) {
11690    if (bool !== undefined) {
11691      bool = !!bool;
11692      if (bool !== this.userActive_) {
11693        this.userActive_ = bool;
11694        if (bool) {
11695          // If the user was inactive and is now active we want to reset the
11696          // inactivity timer
11697          this.userActivity_ = true;
11698          this.removeClass('vjs-user-inactive');
11699          this.addClass('vjs-user-active');
11700          this.trigger('useractive');
11701        } else {
11702          // We're switching the state to inactive manually, so erase any other
11703          // activity
11704          this.userActivity_ = false;
11705
11706          // Chrome/Safari/IE have bugs where when you change the cursor it can
11707          // trigger a mousemove event. This causes an issue when you're hiding
11708          // the cursor when the user is inactive, and a mousemove signals user
11709          // activity. Making it impossible to go into inactive mode. Specifically
11710          // this happens in fullscreen when we really need to hide the cursor.
11711          //
11712          // When this gets resolved in ALL browsers it can be removed
11713          // https://code.google.com/p/chromium/issues/detail?id=103041
11714          if (this.tech_) {
11715            this.tech_.one('mousemove', function (e) {
11716              e.stopPropagation();
11717              e.preventDefault();
11718            });
11719          }
11720
11721          this.removeClass('vjs-user-active');
11722          this.addClass('vjs-user-inactive');
11723          this.trigger('userinactive');
11724        }
11725      }
11726      return this;
11727    }
11728    return this.userActive_;
11729  };
11730
11731  /**
11732   * Listen for user activity based on timeout value
11733   *
11734   * @private
11735   * @method listenForUserActivity_
11736   */
11737
11738  Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
11739    var mouseInProgress = undefined,
11740        lastMoveX = undefined,
11741        lastMoveY = undefined;
11742
11743    var handleActivity = Fn.bind(this, this.reportUserActivity);
11744
11745    var handleMouseMove = function handleMouseMove(e) {
11746      // #1068 - Prevent mousemove spamming
11747      // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
11748      if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
11749        lastMoveX = e.screenX;
11750        lastMoveY = e.screenY;
11751        handleActivity();
11752      }
11753    };
11754
11755    var handleMouseDown = function handleMouseDown() {
11756      handleActivity();
11757      // For as long as the they are touching the device or have their mouse down,
11758      // we consider them active even if they're not moving their finger or mouse.
11759      // So we want to continue to update that they are active
11760      this.clearInterval(mouseInProgress);
11761      // Setting userActivity=true now and setting the interval to the same time
11762      // as the activityCheck interval (250) should ensure we never miss the
11763      // next activityCheck
11764      mouseInProgress = this.setInterval(handleActivity, 250);
11765    };
11766
11767    var handleMouseUp = function handleMouseUp(event) {
11768      handleActivity();
11769      // Stop the interval that maintains activity if the mouse/touch is down
11770      this.clearInterval(mouseInProgress);
11771    };
11772
11773    // Any mouse movement will be considered user activity
11774    this.on('mousedown', handleMouseDown);
11775    this.on('mousemove', handleMouseMove);
11776    this.on('mouseup', handleMouseUp);
11777
11778    // Listen for keyboard navigation
11779    // Shouldn't need to use inProgress interval because of key repeat
11780    this.on('keydown', handleActivity);
11781    this.on('keyup', handleActivity);
11782
11783    // Run an interval every 250 milliseconds instead of stuffing everything into
11784    // the mousemove/touchmove function itself, to prevent performance degradation.
11785    // `this.reportUserActivity` simply sets this.userActivity_ to true, which
11786    // then gets picked up by this loop
11787    // http://ejohn.org/blog/learning-from-twitter/
11788    var inactivityTimeout = undefined;
11789    var activityCheck = this.setInterval(function () {
11790      // Check to see if mouse/touch activity has happened
11791      if (this.userActivity_) {
11792        // Reset the activity tracker
11793        this.userActivity_ = false;
11794
11795        // If the user state was inactive, set the state to active
11796        this.userActive(true);
11797
11798        // Clear any existing inactivity timeout to start the timer over
11799        this.clearTimeout(inactivityTimeout);
11800
11801        var timeout = this.options_['inactivityTimeout'];
11802        if (timeout > 0) {
11803          // In <timeout> milliseconds, if no more activity has occurred the
11804          // user will be considered inactive
11805          inactivityTimeout = this.setTimeout(function () {
11806            // Protect against the case where the inactivityTimeout can trigger just
11807            // before the next user activity is picked up by the activityCheck loop
11808            // causing a flicker
11809            if (!this.userActivity_) {
11810              this.userActive(false);
11811            }
11812          }, timeout);
11813        }
11814      }
11815    }, 250);
11816  };
11817
11818  /**
11819   * Gets or sets the current playback rate.  A playback rate of
11820   * 1.0 represents normal speed and 0.5 would indicate half-speed
11821   * playback, for instance.
11822   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
11823   *
11824   * @param  {Number} rate    New playback rate to set.
11825   * @return {Number}         Returns the new playback rate when setting
11826   * @return {Number}         Returns the current playback rate when getting
11827   * @method playbackRate
11828   */
11829
11830  Player.prototype.playbackRate = function playbackRate(rate) {
11831    if (rate !== undefined) {
11832      this.techCall_('setPlaybackRate', rate);
11833      return this;
11834    }
11835
11836    if (this.tech_ && this.tech_['featuresPlaybackRate']) {
11837      return this.techGet_('playbackRate');
11838    } else {
11839      return 1.0;
11840    }
11841  };
11842
11843  /**
11844   * Gets or sets the audio flag
11845   *
11846   * @param  {Boolean} bool    True signals that this is an audio player.
11847   * @return {Boolean}         Returns true if player is audio, false if not when getting
11848   * @return {Player}      Returns the player if setting
11849   * @private
11850   * @method isAudio
11851   */
11852
11853  Player.prototype.isAudio = function isAudio(bool) {
11854    if (bool !== undefined) {
11855      this.isAudio_ = !!bool;
11856      return this;
11857    }
11858
11859    return !!this.isAudio_;
11860  };
11861
11862  /**
11863   * Returns the current state of network activity for the element, from
11864   * the codes in the list below.
11865   * - NETWORK_EMPTY (numeric value 0)
11866   *   The element has not yet been initialised. All attributes are in
11867   *   their initial states.
11868   * - NETWORK_IDLE (numeric value 1)
11869   *   The element's resource selection algorithm is active and has
11870   *   selected a resource, but it is not actually using the network at
11871   *   this time.
11872   * - NETWORK_LOADING (numeric value 2)
11873   *   The user agent is actively trying to download data.
11874   * - NETWORK_NO_SOURCE (numeric value 3)
11875   *   The element's resource selection algorithm is active, but it has
11876   *   not yet found a resource to use.
11877   *
11878   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
11879   * @return {Number} the current network activity state
11880   * @method networkState
11881   */
11882
11883  Player.prototype.networkState = function networkState() {
11884    return this.techGet_('networkState');
11885  };
11886
11887  /**
11888   * Returns a value that expresses the current state of the element
11889   * with respect to rendering the current playback position, from the
11890   * codes in the list below.
11891   * - HAVE_NOTHING (numeric value 0)
11892   *   No information regarding the media resource is available.
11893   * - HAVE_METADATA (numeric value 1)
11894   *   Enough of the resource has been obtained that the duration of the
11895   *   resource is available.
11896   * - HAVE_CURRENT_DATA (numeric value 2)
11897   *   Data for the immediate current playback position is available.
11898   * - HAVE_FUTURE_DATA (numeric value 3)
11899   *   Data for the immediate current playback position is available, as
11900   *   well as enough data for the user agent to advance the current
11901   *   playback position in the direction of playback.
11902   * - HAVE_ENOUGH_DATA (numeric value 4)
11903   *   The user agent estimates that enough data is available for
11904   *   playback to proceed uninterrupted.
11905   *
11906   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
11907   * @return {Number} the current playback rendering state
11908   * @method readyState
11909   */
11910
11911  Player.prototype.readyState = function readyState() {
11912    return this.techGet_('readyState');
11913  };
11914
11915  /*
11916    * Text tracks are tracks of timed text events.
11917    * Captions - text displayed over the video for the hearing impaired
11918    * Subtitles - text displayed over the video for those who don't understand language in the video
11919    * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
11920    * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
11921    */
11922
11923  /**
11924   * Get an array of associated text tracks. captions, subtitles, chapters, descriptions
11925   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
11926   *
11927   * @return {Array}           Array of track objects
11928   * @method textTracks
11929   */
11930
11931  Player.prototype.textTracks = function textTracks() {
11932    // cannot use techGet_ directly because it checks to see whether the tech is ready.
11933    // Flash is unlikely to be ready in time but textTracks should still work.
11934    return this.tech_ && this.tech_['textTracks']();
11935  };
11936
11937  /**
11938   * Get an array of remote text tracks
11939   *
11940   * @return {Array}
11941   * @method remoteTextTracks
11942   */
11943
11944  Player.prototype.remoteTextTracks = function remoteTextTracks() {
11945    return this.tech_ && this.tech_['remoteTextTracks']();
11946  };
11947
11948  /**
11949   * Get an array of remote html track elements
11950   *
11951   * @return {HTMLTrackElement[]}
11952   * @method remoteTextTrackEls
11953   */
11954
11955  Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
11956    return this.tech_ && this.tech_['remoteTextTrackEls']();
11957  };
11958
11959  /**
11960   * Add a text track
11961   * In addition to the W3C settings we allow adding additional info through options.
11962   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
11963   *
11964   * @param {String}  kind        Captions, subtitles, chapters, descriptions, or metadata
11965   * @param {String=} label       Optional label
11966   * @param {String=} language    Optional language
11967   * @method addTextTrack
11968   */
11969
11970  Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
11971    return this.tech_ && this.tech_['addTextTrack'](kind, label, language);
11972  };
11973
11974  /**
11975   * Add a remote text track
11976   *
11977   * @param {Object} options    Options for remote text track
11978   * @method addRemoteTextTrack
11979   */
11980
11981  Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
11982    return this.tech_ && this.tech_['addRemoteTextTrack'](options);
11983  };
11984
11985  /**
11986   * Remove a remote text track
11987   *
11988   * @param {Object} track    Remote text track to remove
11989   * @method removeRemoteTextTrack
11990   */
11991
11992  Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
11993    this.tech_ && this.tech_['removeRemoteTextTrack'](track);
11994  };
11995
11996  /**
11997   * Get video width
11998   *
11999   * @return {Number} Video width
12000   * @method videoWidth
12001   */
12002
12003  Player.prototype.videoWidth = function videoWidth() {
12004    return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12005  };
12006
12007  /**
12008   * Get video height
12009   *
12010   * @return {Number} Video height
12011   * @method videoHeight
12012   */
12013
12014  Player.prototype.videoHeight = function videoHeight() {
12015    return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12016  };
12017
12018  // Methods to add support for
12019  // initialTime: function(){ return this.techCall_('initialTime'); },
12020  // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
12021  // played: function(){ return this.techCall_('played'); },
12022  // videoTracks: function(){ return this.techCall_('videoTracks'); },
12023  // audioTracks: function(){ return this.techCall_('audioTracks'); },
12024  // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
12025  // defaultMuted: function(){ return this.techCall_('defaultMuted'); }
12026
12027  /**
12028   * The player's language code
12029   * NOTE: The language should be set in the player options if you want the
12030   * the controls to be built with a specific language. Changing the lanugage
12031   * later will not update controls text.
12032   *
12033   * @param {String} code  The locale string
12034   * @return {String}      The locale string when getting
12035   * @return {Player}      self when setting
12036   * @method language
12037   */
12038
12039  Player.prototype.language = function language(code) {
12040    if (code === undefined) {
12041      return this.language_;
12042    }
12043
12044    this.language_ = ('' + code).toLowerCase();
12045    return this;
12046  };
12047
12048  /**
12049   * Get the player's language dictionary
12050   * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12051   * Languages specified directly in the player options have precedence
12052   *
12053   * @return {Array} Array of languages
12054   * @method languages
12055   */
12056
12057  Player.prototype.languages = function languages() {
12058    return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_);
12059  };
12060
12061  /**
12062   * Converts track info to JSON
12063   *
12064   * @return {Object} JSON object of options
12065   * @method toJSON
12066   */
12067
12068  Player.prototype.toJSON = function toJSON() {
12069    var options = _utilsMergeOptionsJs2['default'](this.options_);
12070    var tracks = options.tracks;
12071
12072    options.tracks = [];
12073
12074    for (var i = 0; i < tracks.length; i++) {
12075      var track = tracks[i];
12076
12077      // deep merge tracks and null out player so no circular references
12078      track = _utilsMergeOptionsJs2['default'](track);
12079      track.player = undefined;
12080      options.tracks[i] = track;
12081    }
12082
12083    return options;
12084  };
12085
12086  /**
12087   * Creates a simple modal dialog (an instance of the `ModalDialog`
12088   * component) that immediately overlays the player with arbitrary
12089   * content and removes itself when closed.
12090   *
12091   * @param {String|Function|Element|Array|Null} content
12092   *        Same as `ModalDialog#content`'s param of the same name.
12093   *
12094   *        The most straight-forward usage is to provide a string or DOM
12095   *        element.
12096   *
12097   * @param {Object} [options]
12098   *        Extra options which will be passed on to the `ModalDialog`.
12099   *
12100   * @return {ModalDialog}
12101   */
12102
12103  Player.prototype.createModal = function createModal(content, options) {
12104    var player = this;
12105
12106    options = options || {};
12107    options.content = content || '';
12108
12109    var modal = new _modalDialog2['default'](player, options);
12110
12111    player.addChild(modal);
12112    modal.on('dispose', function () {
12113      player.removeChild(modal);
12114    });
12115
12116    return modal.open();
12117  };
12118
12119  /**
12120   * Gets tag settings
12121   *
12122   * @param {Element} tag The player tag
12123   * @return {Array} An array of sources and track objects
12124   * @static
12125   * @method getTagSettings
12126   */
12127
12128  Player.getTagSettings = function getTagSettings(tag) {
12129    var baseOptions = {
12130      'sources': [],
12131      'tracks': []
12132    };
12133
12134    var tagOptions = Dom.getElAttributes(tag);
12135    var dataSetup = tagOptions['data-setup'];
12136
12137    // Check if data-setup attr exists.
12138    if (dataSetup !== null) {
12139      // Parse options JSON
12140
12141      var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}');
12142
12143      var err = _safeParseTuple[0];
12144      var data = _safeParseTuple[1];
12145
12146      if (err) {
12147        _utilsLogJs2['default'].error(err);
12148      }
12149      _objectAssign2['default'](tagOptions, data);
12150    }
12151
12152    _objectAssign2['default'](baseOptions, tagOptions);
12153
12154    // Get tag children settings
12155    if (tag.hasChildNodes()) {
12156      var children = tag.childNodes;
12157
12158      for (var i = 0, j = children.length; i < j; i++) {
12159        var child = children[i];
12160        // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12161        var childName = child.nodeName.toLowerCase();
12162        if (childName === 'source') {
12163          baseOptions.sources.push(Dom.getElAttributes(child));
12164        } else if (childName === 'track') {
12165          baseOptions.tracks.push(Dom.getElAttributes(child));
12166        }
12167      }
12168    }
12169
12170    return baseOptions;
12171  };
12172
12173  return Player;
12174})(_componentJs2['default']);
12175
12176Player.players = {};
12177
12178var navigator = _globalWindow2['default'].navigator;
12179/*
12180 * Player instance options, surfaced using options
12181 * options = Player.prototype.options_
12182 * Make changes in options, not here.
12183 *
12184 * @type {Object}
12185 * @private
12186 */
12187Player.prototype.options_ = {
12188  // Default order of fallback technology
12189  techOrder: ['html5', 'flash'],
12190  // techOrder: ['flash','html5'],
12191
12192  html5: {},
12193  flash: {},
12194
12195  // defaultVolume: 0.85,
12196  defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
12197
12198  // default inactivity timeout
12199  inactivityTimeout: 2000,
12200
12201  // default playback rates
12202  playbackRates: [],
12203  // Add playback rate selection by adding rates
12204  // 'playbackRates': [0.5, 1, 1.5, 2],
12205
12206  // Included control sets
12207  children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
12208
12209  language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',
12210
12211  // locales and their language translations
12212  languages: {},
12213
12214  // Default message to show when a video cannot be played.
12215  notSupportedMessage: 'No compatible source was found for this video.'
12216};
12217
12218/**
12219 * Fired when the player has initial duration and dimension information
12220 *
12221 * @event loadedmetadata
12222 */
12223Player.prototype.handleLoadedMetaData_;
12224
12225/**
12226 * Fired when the player has downloaded data at the current playback position
12227 *
12228 * @event loadeddata
12229 */
12230Player.prototype.handleLoadedData_;
12231
12232/**
12233 * Fired when the user is active, e.g. moves the mouse over the player
12234 *
12235 * @event useractive
12236 */
12237Player.prototype.handleUserActive_;
12238
12239/**
12240 * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction
12241 *
12242 * @event userinactive
12243 */
12244Player.prototype.handleUserInactive_;
12245
12246/**
12247 * Fired when the current playback position has changed *
12248 * During playback this is fired every 15-250 milliseconds, depending on the
12249 * playback technology in use.
12250 *
12251 * @event timeupdate
12252 */
12253Player.prototype.handleTimeUpdate_;
12254
12255/**
12256 * Fired when video playback ends
12257 *
12258 * @event ended
12259 */
12260Player.prototype.handleTechEnded_;
12261
12262/**
12263 * Fired when the volume changes
12264 *
12265 * @event volumechange
12266 */
12267Player.prototype.handleVolumeChange_;
12268
12269/**
12270 * Fired when an error occurs
12271 *
12272 * @event error
12273 */
12274Player.prototype.handleError_;
12275
12276Player.prototype.flexNotSupported_ = function () {
12277  var elem = _globalDocument2['default'].createElement('i');
12278
12279  // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
12280  // common flex features that we can rely on when checking for flex support.
12281  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)  */;
12282};
12283
12284_componentJs2['default'].registerComponent('Player', Player);
12285exports['default'] = Player;
12286module.exports = exports['default'];
12287// If empty string, make it a parsable json object.
12288
12289},{"./big-play-button.js":62,"./component.js":66,"./control-bar/control-bar.js":67,"./error-display.js":97,"./fullscreen-api.js":100,"./loading-spinner.js":101,"./media-error.js":102,"./modal-dialog":106,"./poster-image.js":111,"./tech/html5.js":116,"./tech/loader.js":117,"./tech/tech.js":118,"./tracks/text-track-display.js":122,"./tracks/text-track-list-converter.js":124,"./tracks/text-track-settings.js":126,"./utils/browser.js":128,"./utils/buffer.js":129,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/guid.js":135,"./utils/log.js":136,"./utils/merge-options.js":137,"./utils/stylesheet.js":138,"./utils/time-ranges.js":139,"./utils/to-title-case.js":140,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":53}],108:[function(_dereq_,module,exports){
12290/**
12291 * @file plugins.js
12292 */
12293'use strict';
12294
12295exports.__esModule = true;
12296
12297function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12298
12299var _playerJs = _dereq_('./player.js');
12300
12301var _playerJs2 = _interopRequireDefault(_playerJs);
12302
12303/**
12304 * The method for registering a video.js plugin
12305 *
12306 * @param  {String} name The name of the plugin
12307 * @param  {Function} init The function that is run when the player inits
12308 * @method plugin
12309 */
12310var plugin = function plugin(name, init) {
12311  _playerJs2['default'].prototype[name] = init;
12312};
12313
12314exports['default'] = plugin;
12315module.exports = exports['default'];
12316
12317},{"./player.js":107}],109:[function(_dereq_,module,exports){
12318/**
12319 * @file popup-button.js
12320 */
12321'use strict';
12322
12323exports.__esModule = true;
12324
12325function _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; } }
12326
12327function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12328
12329function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
12330
12331function _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
12331onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
12332
12333var _clickableComponentJs = _dereq_('../clickable-component.js');
12334
12335var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
12336
12337var _componentJs = _dereq_('../component.js');
12338
12339var _componentJs2 = _interopRequireDefault(_componentJs);
12340
12341var _popupJs = _dereq_('./popup.js');
12342
12343var _popupJs2 = _interopRequireDefault(_popupJs);
12344
12345var _utilsDomJs = _dereq_('../utils/dom.js');
12346
12347var Dom = _interopRequireWildcard(_utilsDomJs);
12348
12349var _utilsFnJs = _dereq_('../utils/fn.js');
12350
12351var Fn = _interopRequireWildcard(_utilsFnJs);
12352
12353var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
12354
12355var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
12356
12357/**
12358 * A button class with a popup control
12359 *
12360 * @param {Player|Object} player
12361 * @param {Object=} options
12362 * @extends ClickableComponent
12363 * @class PopupButton
12364 */
12365
12366var PopupButton = (function (_ClickableComponent) {
12367  _inherits(PopupButton, _ClickableComponent);
12368
12369  function PopupButton(player) {
12370    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
12371
12372    _classCallCheck(this, PopupButton);
12373
12374    _ClickableComponent.call(this, player, options);
12375
12376    this.update();
12377  }
12378
12379  /**
12380   * Update popup
12381   *
12382   * @method update
12383   */
12384
12385  PopupButton.prototype.update = function update() {
12386    var popup = this.createPopup();
12387
12388    if (this.popup) {
12389      this.removeChild(this.popup);
12390    }
12391
12392    this.popup = popup;
12393    this.addChild(popup);
12394
12395    if (this.items && this.items.length === 0) {
12396      this.hide();
12397    } else if (this.items && this.items.length > 1) {
12398      this.show();
12399    }
12400  };
12401
12402  /**
12403   * Create popup - Override with specific functionality for component
12404   *
12405   * @return {Popup} The constructed popup
12406   * @method createPopup
12407   */
12408
12409  PopupButton.prototype.createPopup = function createPopup() {};
12410
12411  /**
12412   * Create the component's DOM element
12413   *
12414   * @return {Element}
12415   * @method createEl
12416   */
12417
12418  PopupButton.prototype.createEl = function createEl() {
12419    return _ClickableComponent.prototype.createEl.call(this, 'div', {
12420      className: this.buildCSSClass()
12421    });
12422  };
12423
12424  /**
12425   * Allow sub components to stack CSS class names
12426   *
12427   * @return {String} The constructed class name
12428   * @method buildCSSClass
12429   */
12430
12431  PopupButton.prototype.buildCSSClass = function buildCSSClass() {
12432    var menuButtonClass = 'vjs-menu-button';
12433
12434    // If the inline option is passed, we want to use different styles altogether.
12435    if (this.options_.inline === true) {
12436      menuButtonClass += '-inline';
12437    } else {
12438      menuButtonClass += '-popup';
12439    }
12440
12441    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
12442  };
12443
12444  return PopupButton;
12445})(_clickableComponentJs2['default']);
12446
12447_componentJs2['default'].registerComponent('PopupButton', PopupButton);
12448exports['default'] = PopupButton;
12449module.exports = exports['default'];
12450
12451},{"../clickable-component.js":64,"../component.js":66,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/to-title-case.js":140,"./popup.js":110}],110:[function(_dereq_,module,exports){
12452/**
12453 * @file popup.js
12454 */
12455'use strict';
12456
12457exports.__esModule = true;
12458
12459function _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; } }
12460
12461function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12462
12463function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
12464
12465function _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
12465onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
12466
12467var _componentJs = _dereq_('../component.js');
12468
12469var _componentJs2 = _interopRequireDefault(_componentJs);
12470
12471var _utilsDomJs = _dereq_('../utils/dom.js');
12472
12473var Dom = _interopRequireWildcard(_utilsDomJs);
12474
12475var _utilsFnJs = _dereq_('../utils/fn.js');
12476
12477var Fn = _interopRequireWildcard(_utilsFnJs);
12478
12479var _utilsEventsJs = _dereq_('../utils/events.js');
12480
12481var Events = _interopRequireWildcard(_utilsEventsJs);
12482
12483/**
12484 * The Popup component is used to build pop up controls.
12485 *
12486 * @extends Component
12487 * @class Popup
12488 */
12489
12490var Popup = (function (_Component) {
12491  _inherits(Popup, _Component);
12492
12493  function Popup() {
12494    _classCallCheck(this, Popup);
12495
12496    _Component.apply(this, arguments);
12497  }
12498
12499  /**
12500   * Add a popup item to the popup
12501   *
12502   * @param {Object|String} component Component or component type to add
12503   * @method addItem
12504   */
12505
12506  Popup.prototype.addItem = function addItem(component) {
12507    this.addChild(component);
12508    component.on('click', Fn.bind(this, function () {
12509      this.unlockShowing();
12510    }));
12511  };
12512
12513  /**
12514   * Create the component's DOM element
12515   *
12516   * @return {Element}
12517   * @method createEl
12518   */
12519
12520  Popup.prototype.createEl = function createEl() {
12521    var contentElType = this.options_.contentElType || 'ul';
12522    this.contentEl_ = Dom.createEl(contentElType, {
12523      className: 'vjs-menu-content'
12524    });
12525    var el = _Component.prototype.createEl.call(this, 'div', {
12526      append: this.contentEl_,
12527      className: 'vjs-menu'
12528    });
12529    el.appendChild(this.contentEl_);
12530
12531    // Prevent clicks from bubbling up. Needed for Popup Buttons,
12532    // where a click on the parent is significant
12533    Events.on(el, 'click', function (event) {
12534      event.preventDefault();
12535      event.stopImmediatePropagation();
12536    });
12537
12538    return el;
12539  };
12540
12541  return Popup;
12542})(_componentJs2['default']);
12543
12544_componentJs2['default'].registerComponent('Popup', Popup);
12545exports['default'] = Popup;
12546module.exports = exports['default'];
12547
12548},{"../component.js":66,"../utils/dom.js":131,"../utils/events.js":132,"../utils/fn.js":133}],111:[function(_dereq_,module,exports){
12549/**
12550 * @file poster-image.js
12551 */
12552'use strict';
12553
12554exports.__esModule = true;
12555
12556function _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; } }
12557
12558function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12559
12560function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
12561
12562function _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; }
12563
12564var _clickableComponentJs = _dereq_('./clickable-component.js');
12565
12566var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
12567
12568var _componentJs = _dereq_('./component.js');
12569
12570var _componentJs2 = _interopRequireDefault(_componentJs);
12571
12572var _utilsFnJs = _dereq_('./utils/fn.js');
12573
12574var Fn = _interopRequireWildcard(_utilsFnJs);
12575
12576var _utilsDomJs = _dereq_('./utils/dom.js');
12577
12578var Dom = _interopRequireWildcard(_utilsDomJs);
12579
12580var _utilsBrowserJs = _dereq_('./utils/browser.js');
12581
12582var browser = _interopRequireWildcard(_utilsBrowserJs);
12583
12584/**
12585 * The component that handles showing the poster image.
12586 *
12587 * @param {Player|Object} player
12588 * @param {Object=} options
12589 * @extends Button
12590 * @class PosterImage
12591 */
12592
12593var PosterImage = (function (_ClickableComponent) {
12594  _inherits(PosterImage, _ClickableComponent);
12595
12596  function PosterImage(player, options) {
12597    _classCallCheck(this, PosterImage);
12598
12599    _ClickableComponent.call(this, player, options);
12600
12601    this.update();
12602    player.on('posterchange', Fn.bind(this, this.update));
12603  }
12604
12605  /**
12606   * Clean up the poster image
12607   *
12608   * @method dispose
12609   */
12610
12611  PosterImage.prototype.dispose = function dispose() {
12612    this.player().off('posterchange', this.update);
12613    _ClickableComponent.prototype.dispose.call(this);
12614  };
12615
12616  /**
12617   * Create the poster's image element
12618   *
12619   * @return {Element}
12620   * @method createEl
12621   */
12622
12623  PosterImage.prototype.createEl = function createEl() {
12624    var el = Dom.createEl('div', {
12625      className: 'vjs-poster',
12626
12627      // Don't want poster to be tabbable.
12628      tabIndex: -1
12629    });
12630
12631    // To ensure the poster image resizes while maintaining its original aspect
12632    // ratio, use a div with `background-size` when available. For browsers that
12633    // do not support `background-size` (e.g. IE8), fall back on using a regular
12634    // img element.
12635    if (!browser.BACKGROUND_SIZE_SUPPORTED) {
12636      this.fallbackImg_ = Dom.createEl('img');
12637      el.appendChild(this.fallbackImg_);
12638    }
12639
12640    return el;
12641  };
12642
12643  /**
12644   * Event handler for updates to the player's poster source
12645   *
12646   * @method update
12647   */
12648
12649  PosterImage.prototype.update = function update() {
12650    var url = this.player().poster();
12651
12652    this.setSrc(url);
12653
12654    // If there's no poster source we should display:none on this component
12655    // so it's not still clickable or right-clickable
12656    if (url) {
12657      this.show();
12658    } else {
12659      this.hide();
12660    }
12661  };
12662
12663  /**
12664   * Set the poster source depending on the display method
12665   *
12666   * @param {String} url The URL to the poster source
12667   * @method setSrc
12668   */
12669
12670  PosterImage.prototype.setSrc = function setSrc(url) {
12671    if (this.fallbackImg_) {
12672      this.fallbackImg_.src = url;
12673    } else {
12674      var backgroundImage = '';
12675      // Any falsey values should stay as an empty string, otherwise
12676      // this will throw an extra error
12677      if (url) {
12678        backgroundImage = 'url("' + url + '")';
12679      }
12680
12681      this.el_.style.backgroundImage = backgroundImage;
12682    }
12683  };
12684
12685  /**
12686   * Event handler for clicks on the poster image
12687   *
12688   * @method handleClick
12689   */
12690
12691  PosterImage.prototype.handleClick = function handleClick() {
12692    // We don't want a click to trigger playback when controls are disabled
12693    // but CSS should be hiding the poster to prevent that from happening
12694    if (this.player_.paused()) {
12695      this.player_.play();
12696    } else {
12697      this.player_.pause();
12698    }
12699  };
12700
12701  return PosterImage;
12702})(_clickableComponentJs2['default']);
12703
12704_componentJs2['default'].registerComponent('PosterImage', PosterImage);
12705exports['default'] = PosterImage;
12706module.exports = exports['default'];
12707
12708},{"./clickable-component.js":64,"./component.js":66,"./utils/browser.js":128,"./utils/dom.js":131,"./utils/fn.js":133}],112:[function(_dereq_,module,exports){
12709/**
12710 * @file setup.js
12711 *
12712 * Functions for automatically setting up a player
12713 * based on the data-setup attribute of the video tag
12714 */
12715'use strict';
12716
12717exports.__esModule = true;
12718
12719function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12720
12721function _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; } }
12722
12723var _utilsEventsJs = _dereq_('./utils/events.js');
12724
12725var Events = _interopRequireWildcard(_utilsEventsJs);
12726
12727var _globalDocument = _dereq_('global/document');
12728
12729var _globalDocument2 = _interopRequireDefault(_globalDocument);
12730
12731var _globalWindow = _dereq_('global/window');
12732
12733var _globalWindow2 = _interopRequireDefault(_globalWindow);
12734
12735var _windowLoaded = false;
12736var videojs = undefined;
12737
12738// Automatically set up any tags that have a data-setup attribute
12739var autoSetup = function autoSetup() {
12740  // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
12741  // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
12742  // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
12743  // var mediaEls = vids.concat(audios);
12744
12745  // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements
12746  // to build up a new, combined list of elements.
12747  var vids = _globalDocument2['default'].getElementsByTagName('video');
12748  var audios = _globalDocument2['default'].getElementsByTagName('audio');
12749  var mediaEls = [];
12750  if (vids && vids.length > 0) {
12751    for (var i = 0, e = vids.length; i < e; i++) {
12752      mediaEls.push(vids[i]);
12753    }
12754  }
12755  if (audios && audios.length > 0) {
12756    for (var i = 0, e = audios.length; i < e; i++) {
12757      mediaEls.push(audios[i]);
12758    }
12759  }
12760
12761  // Check if any media elements exist
12762  if (mediaEls && mediaEls.length > 0) {
12763
12764    for (var i = 0, e = mediaEls.length; i < e; i++) {
12765      var mediaEl = mediaEls[i];
12766
12767      // Check if element exists, has getAttribute func.
12768      // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately.
12769      if (mediaEl && mediaEl.getAttribute) {
12770
12771        // Make sure this player hasn't already been set up.
12772        if (mediaEl['player'] === undefined) {
12773          var options = mediaEl.getAttribute('data-setup');
12774
12775          // Check if data-setup attr exists.
12776          // We only auto-setup if they've added the data-setup attr.
12777          if (options !== null) {
12778            // Create new video.js instance.
12779            var player = videojs(mediaEl);
12780          }
12781        }
12782
12783        // If getAttribute isn't defined, we need to wait for the DOM.
12784      } else {
12785          autoSetupTimeout(1);
12786          break;
12787        }
12788    }
12789
12790    // No videos were found, so keep looping unless page is finished loading.
12791  } else if (!_windowLoaded) {
12792      autoSetupTimeout(1);
12793    }
12794};
12795
12796// Pause to let the DOM keep processing
12797var autoSetupTimeout = function autoSetupTimeout(wait, vjs) {
12798  videojs = vjs;
12799  setTimeout(autoSetup, wait);
12800};
12801
12802if (_globalDocument2['default'].readyState === 'complete') {
12803  _windowLoaded = true;
12804} else {
12805  Events.one(_globalWindow2['default'], 'load', function () {
12806    _windowLoaded = true;
12807  });
12808}
12809
12810var hasLoaded = function hasLoaded() {
12811  return _windowLoaded;
12812};
12813
12814exports.autoSetup = autoSetup;
12815exports.autoSetupTimeout = autoSetupTimeout;
12816exports.hasLoaded = hasLoaded;
12817
12818},{"./utils/events.js":132,"global/document":1,"global/window":2}],113:[function(_dereq_,module,exports){
12819/**
12820 * @file slider.js
12821 */
12822'use strict';
12823
12824exports.__esModule = true;
12825
12826function _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; } }
12827
12828function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12829
12830function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
12831
12832function _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
12832onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
12833
12834var _componentJs = _dereq_('../component.js');
12835
12836var _componentJs2 = _interopRequireDefault(_componentJs);
12837
12838var _utilsDomJs = _dereq_('../utils/dom.js');
12839
12840var Dom = _interopRequireWildcard(_utilsDomJs);
12841
12842var _globalDocument = _dereq_('global/document');
12843
12844var _globalDocument2 = _interopRequireDefault(_globalDocument);
12845
12846var _objectAssign = _dereq_('object.assign');
12847
12848var _objectAssign2 = _interopRequireDefault(_objectAssign);
12849
12850/**
12851 * The base functionality for sliders like the volume bar and seek bar
12852 *
12853 * @param {Player|Object} player
12854 * @param {Object=} options
12855 * @extends Component
12856 * @class Slider
12857 */
12858
12859var Slider = (function (_Component) {
12860  _inherits(Slider, _Component);
12861
12862  function Slider(player, options) {
12863    _classCallCheck(this, Slider);
12864
12865    _Component.call(this, player, options);
12866
12867    // Set property names to bar to match with the child Slider class is looking for
12868    this.bar = this.getChild(this.options_.barName);
12869
12870    // Set a horizontal or vertical class on the slider depending on the slider type
12871    this.vertical(!!this.options_.vertical);
12872
12873    this.on('mousedown', this.handleMouseDown);
12874    this.on('touchstart', this.handleMouseDown);
12875    this.on('focus', this.handleFocus);
12876    this.on('blur', this.handleBlur);
12877    this.on('click', this.handleClick);
12878
12879    this.on(player, 'controlsvisible', this.update);
12880    this.on(player, this.playerEvent, this.update);
12881  }
12882
12883  /**
12884   * Create the component's DOM element
12885   *
12886   * @param {String} type Type of element to create
12887   * @param {Object=} props List of properties in Object form
12888   * @return {Element}
12889   * @method createEl
12890   */
12891
12892  Slider.prototype.createEl = function createEl(type) {
12893    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
12894    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
12895
12896    // Add the slider element class to all sub classes
12897    props.className = props.className + ' vjs-slider';
12898    props = _objectAssign2['default']({
12899      tabIndex: 0
12900    }, props);
12901
12902    attributes = _objectAssign2['default']({
12903      'role': 'slider',
12904      'aria-valuenow': 0,
12905      'aria-valuemin': 0,
12906      'aria-valuemax': 100,
12907      tabIndex: 0
12908    }, attributes);
12909
12910    return _Component.prototype.createEl.call(this, type, props, attributes);
12911  };
12912
12913  /**
12914   * Handle mouse down on slider
12915   *
12916   * @param {Object} event Mouse down event object
12917   * @method handleMouseDown
12918   */
12919
12920  Slider.prototype.handleMouseDown = function handleMouseDown(event) {
12921    event.preventDefault();
12922    Dom.blockTextSelection();
12923
12924    this.addClass('vjs-sliding');
12925    this.trigger('slideractive');
12926
12927    this.on(_globalDocument2['default'], 'mousemove', this.handleMouseMove);
12928    this.on(_globalDocument2['default'], 'mouseup', this.handleMouseUp);
12929    this.on(_globalDocument2['default'], 'touchmove', this.handleMouseMove);
12930    this.on(_globalDocument2['default'], 'touchend', this.handleMouseUp);
12931
12932    this.handleMouseMove(event);
12933  };
12934
12935  /**
12936   * To be overridden by a subclass
12937   *
12938   * @method handleMouseMove
12939   */
12940
12941  Slider.prototype.handleMouseMove = function handleMouseMove() {};
12942
12943  /**
12944   * Handle mouse up on Slider
12945   *
12946   * @method handleMouseUp
12947   */
12948
12949  Slider.prototype.handleMouseUp = function handleMouseUp() {
12950    Dom.unblockTextSelection();
12951
12952    this.removeClass('vjs-sliding');
12953    this.trigger('sliderinactive');
12954
12955    this.off(_globalDocument2['default'], 'mousemove', this.handleMouseMove);
12956    this.off(_globalDocument2['default'], 'mouseup', this.handleMouseUp);
12957    this.off(_globalDocument2['default'], 'touchmove', this.handleMouseMove);
12958    this.off(_globalDocument2['default'], 'touchend', this.handleMouseUp);
12959
12960    this.update();
12961  };
12962
12963  /**
12964   * Update slider
12965   *
12966   * @method update
12967   */
12968
12969  Slider.prototype.update = function update() {
12970    // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
12971    // execution stack. The player is destroyed before then update will cause an error
12972    if (!this.el_) return;
12973
12974    // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
12975    // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
12976    // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
12977    var progress = this.getPercent();
12978    var bar = this.bar;
12979
12980    // If there's no bar...
12981    if (!bar) return;
12982
12983    // Protect against no duration and other division issues
12984    if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
12985      progress = 0;
12986    }
12987
12988    // Convert to a percentage for setting
12989    var percentage = (progress * 100).toFixed(2) + '%';
12990
12991    // Set the new bar width or height
12992    if (this.vertical()) {
12993      bar.el().style.height = percentage;
12994    } else {
12995      bar.el().style.width = percentage;
12996    }
12997  };
12998
12999  /**
13000   * Calculate distance for slider
13001   *
13002   * @param {Object} event Event object
13003   * @method calculateDistance
13004   */
13005
13006  Slider.prototype.calculateDistance = function calculateDistance(event) {
13007    var position = Dom.getPointerPosition(this.el_, event);
13008    if (this.vertical()) {
13009      return position.y;
13010    }
13011    return position.x;
13012  };
13013
13014  /**
13015   * Handle on focus for slider
13016   *
13017   * @method handleFocus
13018   */
13019
13020  Slider.prototype.handleFocus = function handleFocus() {
13021    this.on(_globalDocument2['default'], 'keydown', this.handleKeyPress);
13022  };
13023
13024  /**
13025   * Handle key press for slider
13026   *
13027   * @param {Object} event Event object
13028   * @method handleKeyPress
13029   */
13030
13031  Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13032    if (event.which === 37 || event.which === 40) {
13033      // Left and Down Arrows
13034      event.preventDefault();
13035      this.stepBack();
13036    } else if (event.which === 38 || event.which === 39) {
13037      // Up and Right Arrows
13038      event.preventDefault();
13039      this.stepForward();
13040    }
13041  };
13042
13043  /**
13044   * Handle on blur for slider
13045   *
13046   * @method handleBlur
13047   */
13048
13049  Slider.prototype.handleBlur = function handleBlur() {
13050    this.off(_globalDocument2['default'], 'keydown', this.handleKeyPress);
13051  };
13052
13053  /**
13054   * Listener for click events on slider, used to prevent clicks
13055   *   from bubbling up to parent elements like button menus.
13056   *
13057   * @param {Object} event Event object
13058   * @method handleClick
13059   */
13060
13061  Slider.prototype.handleClick = function handleClick(event) {
13062    event.stopImmediatePropagation();
13063    event.preventDefault();
13064  };
13065
13066  /**
13067   * Get/set if slider is horizontal for vertical
13068   *
13069   * @param {Boolean} bool True if slider is vertical, false is horizontal
13070   * @return {Boolean} True if slider is vertical, false is horizontal
13071   * @method vertical
13072   */
13073
13074  Slider.prototype.vertical = function vertical(bool) {
13075    if (bool === undefined) {
13076      return this.vertical_ || false;
13077    }
13078
13079    this.vertical_ = !!bool;
13080
13081    if (this.vertical_) {
13082      this.addClass('vjs-slider-vertical');
13083    } else {
13084      this.addClass('vjs-slider-horizontal');
13085    }
13086
13087    return this;
13088  };
13089
13090  return Slider;
13091})(_componentJs2['default']);
13092
13093_componentJs2['default'].registerComponent('Slider', Slider);
13094exports['default'] = Slider;
13095module.exports = exports['default'];
13096
13097},{"../component.js":66,"../utils/dom.js":131,"global/document":1,"object.assign":45}],114:[function(_dereq_,module,exports){
13098/**
13099 * @file flash-rtmp.js
13100 */
13101'use strict';
13102
13103exports.__esModule = true;
13104function FlashRtmpDecorator(Flash) {
13105  Flash.streamingFormats = {
13106    'rtmp/mp4': 'MP4',
13107    'rtmp/flv': 'FLV'
13108  };
13109
13110  Flash.streamFromParts = function (connection, stream) {
13111    return connection + '&' + stream;
13112  };
13113
13114  Flash.streamToParts = function (src) {
13115    var parts = {
13116      connection: '',
13117      stream: ''
13118    };
13119
13120    if (!src) return parts;
13121
13122    // Look for the normal URL separator we expect, '&'.
13123    // If found, we split the URL into two pieces around the
13124    // first '&'.
13125    var connEnd = src.search(/&(?!\w+=)/);
13126    var streamBegin = undefined;
13127    if (connEnd !== -1) {
13128      streamBegin = connEnd + 1;
13129    } else {
13130      // If there's not a '&', we use the last '/' as the delimiter.
13131      connEnd = streamBegin = src.lastIndexOf('/') + 1;
13132      if (connEnd === 0) {
13133        // really, there's not a '/'?
13134        connEnd = streamBegin = src.length;
13135      }
13136    }
13137    parts.connection = src.substring(0, connEnd);
13138    parts.stream = src.substring(streamBegin, src.length);
13139
13140    return parts;
13141  };
13142
13143  Flash.isStreamingType = function (srcType) {
13144    return srcType in Flash.streamingFormats;
13145  };
13146
13147  // RTMP has four variations, any string starting
13148  // with one of these protocols should be valid
13149  Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13150
13151  Flash.isStreamingSrc = function (src) {
13152    return Flash.RTMP_RE.test(src);
13153  };
13154
13155  /**
13156   * A source handler for RTMP urls
13157   * @type {Object}
13158   */
13159  Flash.rtmpSourceHandler = {};
13160
13161  /**
13162   * Check if Flash can play the given videotype
13163   * @param  {String} type    The mimetype to check
13164   * @return {String}         'probably', 'maybe', or '' (empty string)
13165   */
13166  Flash.rtmpSourceHandler.canPlayType = function (type) {
13167    if (Flash.isStreamingType(type)) {
13168      return 'maybe';
13169    }
13170
13171    return '';
13172  };
13173
13174  /**
13175   * Check if Flash can handle the source natively
13176   * @param  {Object} source  The source object
13177   * @return {String}         'probably', 'maybe', or '' (empty string)
13178   */
13179  Flash.rtmpSourceHandler.canHandleSource = function (source) {
13180    var can = Flash.rtmpSourceHandler.canPlayType(source.type);
13181
13182    if (can) {
13183      return can;
13184    }
13185
13186    if (Flash.isStreamingSrc(source.src)) {
13187      return 'maybe';
13188    }
13189
13190    return '';
13191  };
13192
13193  /**
13194   * Pass the source to the flash object
13195   * Adaptive source handlers will have more complicated workflows before passing
13196   * video data to the video element
13197   * @param  {Object} source    The source object
13198   * @param  {Flash} tech   The instance of the Flash tech
13199   */
13200  Flash.rtmpSourceHandler.handleSource = function (source, tech) {
13201    var srcParts = Flash.streamToParts(source.src);
13202
13203    tech['setRtmpConnection'](srcParts.connection);
13204    tech['setRtmpStream'](srcParts.stream);
13205  };
13206
13207  // Register the native source handler
13208  Flash.registerSourceHandler(Flash.rtmpSourceHandler);
13209
13210  return Flash;
13211}
13212
13213exports['default'] = FlashRtmpDecorator;
13214module.exports = exports['default'];
13215
13216},{}],115:[function(_dereq_,module,exports){
13217/**
13218 * @file flash.js
13219 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
13220 * https://github.com/zencoder/video-js-swf
13221 * Not using setupTriggers. Using global onEvent func to distribute events
13222 */
13223
13224'use strict';
13225
13226exports.__esModule = true;
13227
13228function _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; } }
13229
13230function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13231
13232function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13233
13234function _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; }
13235
13236var _tech = _dereq_('./tech');
13237
13238var _tech2 = _interopRequireDefault(_tech);
13239
13240var _utilsDomJs = _dereq_('../utils/dom.js');
13241
13242var Dom = _interopRequireWildcard(_utilsDomJs);
13243
13244var _utilsUrlJs = _dereq_('../utils/url.js');
13245
13246var Url = _interopRequireWildcard(_utilsUrlJs);
13247
13248var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
13249
13250var _flashRtmp = _dereq_('./flash-rtmp');
13251
13252var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
13253
13254var _component = _dereq_('../component');
13255
13256var _component2 = _interopRequireDefault(_component);
13257
13258var _globalWindow = _dereq_('global/window');
13259
13260var _globalWindow2 = _interopRequireDefault(_globalWindow);
13261
13262var _objectAssign = _dereq_('object.assign');
13263
13264var _objectAssign2 = _interopRequireDefault(_objectAssign);
13265
13266var navigator = _globalWindow2['default'].navigator;
13267/**
13268 * Flash Media Controller - Wrapper for fallback SWF API
13269 *
13270 * @param {Object=} options Object of option names and values
13271 * @param {Function=} ready Ready callback function
13272 * @extends Tech
13273 * @class Flash
13274 */
13275
13276var Flash = (function (_Tech) {
13277  _inherits(Flash, _Tech);
13278
13279  function Flash(options, ready) {
13280    _classCallCheck(this, Flash);
13281
13282    _Tech.call(this, options, ready);
13283
13284    // Set the source when ready
13285    if (options.source) {
13286      this.ready(function () {
13287        this.setSource(options.source);
13288      }, true);
13289    }
13290
13291    // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
13292    // This allows resetting the playhead when we catch the reload
13293    if (options.startTime) {
13294      this.ready(function () {
13295        this.load();
13296        this.play();
13297        this.currentTime(options.startTime);
13298      }, true);
13299    }
13300
13301    // Add global window functions that the swf expects
13302    // A 4.x workflow we weren't able to solve for in 5.0
13303    // because of the need to hard code these functions
13304    // into the swf for security reasons
13305    _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {};
13306    _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {};
13307    _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady;
13308    _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent;
13309    _globalWindow2['default'].videojs.Flash.onError = Flash.onError;
13310
13311    this.on('seeked', function () {
13312      this.lastSeekTarget_ = undefined;
13313    });
13314  }
13315
13316  // Create setters and getters for attributes
13317
13318  /**
13319   * Create the component's DOM element
13320   *
13321   * @return {Element}
13322   * @method createEl
13323   */
13324
13325  Flash.prototype.createEl = function createEl() {
13326    var options = this.options_;
13327
13328    // If video.js is hosted locally you should also set the location
13329    // for the hosted swf, which should be relative to the page (not video.js)
13330    // Otherwise this adds a CDN url.
13331    // The CDN also auto-adds a swf URL for that specific version.
13332    if (!options.swf) {
13333      options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf';
13334    }
13335
13336    // Generate ID for swf object
13337    var objId = options.techId;
13338
13339    // Merge default flashvars with ones passed in to init
13340    var flashVars = _objectAssign2['default']({
13341
13342      // SWF Callback Functions
13343      'readyFunction': 'videojs.Flash.onReady',
13344      'eventProxyFunction': 'videojs.Flash.onEvent',
13345      'errorEventProxyFunction': 'videojs.Flash.onError',
13346
13347      // Player Settings
13348      'autoplay': options.autoplay,
13349      'preload': options.preload,
13350      'loop': options.loop,
13351      'muted': options.muted
13352
13353    }, options.flashVars);
13354
13355    // Merge default parames with ones passed in
13356    var params = _objectAssign2['default']({
13357      'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance
13358      'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading
13359    }, options.params);
13360
13361    // Merge default attributes with ones passed in
13362    var attributes = _objectAssign2['default']({
13363      'id': objId,
13364      'name': objId, // Both ID and Name needed or swf to identify itself
13365      'class': 'vjs-tech'
13366    }, options.attributes);
13367
13368    this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
13369    this.el_.tech = this;
13370
13371    return this.el_;
13372  };
13373
13374  /**
13375   * Play for flash tech
13376   *
13377   * @method play
13378   */
13379
13380  Flash.prototype.play = function play() {
13381    if (this.ended()) {
13382      this.setCurrentTime(0);
13383    }
13384    this.el_.vjs_play();
13385  };
13386
13387  /**
13388   * Pause for flash tech
13389   *
13390   * @method pause
13391   */
13392
13393  Flash.prototype.pause = function pause() {
13394    this.el_.vjs_pause();
13395  };
13396
13397  /**
13398   * Get/set video
13399   *
13400   * @param {Object=} src Source object
13401   * @return {Object}
13402   * @method src
13403   */
13404
13405  Flash.prototype.src = function src(_src) {
13406    if (_src === undefined) {
13407      return this.currentSrc();
13408    }
13409
13410    // Setting src through `src` not `setSrc` will be deprecated
13411    return this.setSrc(_src);
13412  };
13413
13414  /**
13415   * Set video
13416   *
13417   * @param {Object=} src Source object
13418   * @deprecated
13419   * @method setSrc
13420   */
13421
13422  Flash.prototype.setSrc = function setSrc(src) {
13423    // Make sure source URL is absolute.
13424    src = Url.getAbsoluteURL(src);
13425    this.el_.vjs_src(src);
13426
13427    // Currently the SWF doesn't autoplay if you load a source later.
13428    // e.g. Load player w/ no source, wait 2s, set src.
13429    if (this.autoplay()) {
13430      var tech = this;
13431      this.setTimeout(function () {
13432        tech.play();
13433      }, 0);
13434    }
13435  };
13436
13437  /**
13438   * Returns true if the tech is currently seeking.
13439   * @return {boolean} true if seeking
13440   */
13441
13442  Flash.prototype.seeking = function seeking() {
13443    return this.lastSeekTarget_ !== undefined;
13444  };
13445
13446  /**
13447   * Set current time
13448   *
13449   * @param {Number} time Current time of video
13450   * @method setCurrentTime
13451   */
13452
13453  Flash.prototype.setCurrentTime = function setCurrentTime(time) {
13454    var seekable = this.seekable();
13455    if (seekable.length) {
13456      // clamp to the current seekable range
13457      time = time > seekable.start(0) ? time : seekable.start(0);
13458      time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
13459
13460      this.lastSeekTarget_ = time;
13461      this.trigger('seeking');
13462      this.el_.vjs_setProperty('currentTime', time);
13463      _Tech.prototype.setCurrentTime.call(this);
13464    }
13465  };
13466
13467  /**
13468   * Get current time
13469   *
13470   * @param {Number=}
13470 time Current time of video
13471   * @return {Number} Current time
13472   * @method currentTime
13473   */
13474
13475  Flash.prototype.currentTime = function currentTime(time) {
13476    // when seeking make the reported time keep up with the requested time
13477    // by reading the time we're seeking to
13478    if (this.seeking()) {
13479      return this.lastSeekTarget_ || 0;
13480    }
13481    return this.el_.vjs_getProperty('currentTime');
13482  };
13483
13484  /**
13485   * Get current source
13486   *
13487   * @method currentSrc
13488   */
13489
13490  Flash.prototype.currentSrc = function currentSrc() {
13491    if (this.currentSource_) {
13492      return this.currentSource_.src;
13493    } else {
13494      return this.el_.vjs_getProperty('currentSrc');
13495    }
13496  };
13497
13498  /**
13499   * Load media into player
13500   *
13501   * @method load
13502   */
13503
13504  Flash.prototype.load = function load() {
13505    this.el_.vjs_load();
13506  };
13507
13508  /**
13509   * Get poster
13510   *
13511   * @method poster
13512   */
13513
13514  Flash.prototype.poster = function poster() {
13515    this.el_.vjs_getProperty('poster');
13516  };
13517
13518  /**
13519   * Poster images are not handled by the Flash tech so make this a no-op
13520   *
13521   * @method setPoster
13522   */
13523
13524  Flash.prototype.setPoster = function setPoster() {};
13525
13526  /**
13527   * Determine if can seek in media
13528   *
13529   * @return {TimeRangeObject}
13530   * @method seekable
13531   */
13532
13533  Flash.prototype.seekable = function seekable() {
13534    var duration = this.duration();
13535    if (duration === 0) {
13536      return _utilsTimeRangesJs.createTimeRange();
13537    }
13538    return _utilsTimeRangesJs.createTimeRange(0, duration);
13539  };
13540
13541  /**
13542   * Get buffered time range
13543   *
13544   * @return {TimeRangeObject}
13545   * @method buffered
13546   */
13547
13548  Flash.prototype.buffered = function buffered() {
13549    var ranges = this.el_.vjs_getProperty('buffered');
13550    if (ranges.length === 0) {
13551      return _utilsTimeRangesJs.createTimeRange();
13552    }
13553    return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]);
13554  };
13555
13556  /**
13557   * Get fullscreen support -
13558   * Flash does not allow fullscreen through javascript
13559   * so always returns false
13560   *
13561   * @return {Boolean} false
13562   * @method supportsFullScreen
13563   */
13564
13565  Flash.prototype.supportsFullScreen = function supportsFullScreen() {
13566    return false; // Flash does not allow fullscreen through javascript
13567  };
13568
13569  /**
13570   * Request to enter fullscreen
13571   * Flash does not allow fullscreen through javascript
13572   * so always returns false
13573   *
13574   * @return {Boolean} false
13575   * @method enterFullScreen
13576   */
13577
13578  Flash.prototype.enterFullScreen = function enterFullScreen() {
13579    return false;
13580  };
13581
13582  return Flash;
13583})(_tech2['default']);
13584
13585var _api = Flash.prototype;
13586var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
13587var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoTracks,audioTracks,videoWidth,videoHeight'.split(',');
13588
13589function _createSetter(attr) {
13590  var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
13591  _api['set' + attrUpper] = function (val) {
13592    return this.el_.vjs_setProperty(attr, val);
13593  };
13594}
13595function _createGetter(attr) {
13596  _api[attr] = function () {
13597    return this.el_.vjs_getProperty(attr);
13598  };
13599}
13600
13601// Create getter and setters for all read/write attributes
13602for (var i = 0; i < _readWrite.length; i++) {
13603  _createGetter(_readWrite[i]);
13604  _createSetter(_readWrite[i]);
13605}
13606
13607// Create getters for read-only attributes
13608for (var i = 0; i < _readOnly.length; i++) {
13609  _createGetter(_readOnly[i]);
13610}
13611
13612/* Flash Support Testing -------------------------------------------------------- */
13613
13614Flash.isSupported = function () {
13615  return Flash.version()[0] >= 10;
13616  // return swfobject.hasFlashPlayerVersion('10');
13617};
13618
13619// Add Source Handler pattern functions to this tech
13620_tech2['default'].withSourceHandlers(Flash);
13621
13622/*
13623 * The default native source handler.
13624 * This simply passes the source to the video element. Nothing fancy.
13625 *
13626 * @param  {Object} source   The source object
13627 * @param  {Flash} tech  The instance of the Flash tech
13628 */
13629Flash.nativeSourceHandler = {};
13630
13631/**
13632 * Check if Flash can play the given videotype
13633 * @param  {String} type    The mimetype to check
13634 * @return {String}         'probably', 'maybe', or '' (empty string)
13635 */
13636Flash.nativeSourceHandler.canPlayType = function (type) {
13637  if (type in Flash.formats) {
13638    return 'maybe';
13639  }
13640
13641  return '';
13642};
13643
13644/*
13645 * Check Flash can handle the source natively
13646 *
13647 * @param  {Object} source  The source object
13648 * @return {String}         'probably', 'maybe', or '' (empty string)
13649 */
13650Flash.nativeSourceHandler.canHandleSource = function (source) {
13651  var type;
13652
13653  function guessMimeType(src) {
13654    var ext = Url.getFileExtension(src);
13655    if (ext) {
13656      return 'video/' + ext;
13657    }
13658    return '';
13659  }
13660
13661  if (!source.type) {
13662    type = guessMimeType(source.src);
13663  } else {
13664    // Strip code information from the type because we don't get that specific
13665    type = source.type.replace(/;.*/, '').toLowerCase();
13666  }
13667
13668  return Flash.nativeSourceHandler.canPlayType(type);
13669};
13670
13671/*
13672 * Pass the source to the flash object
13673 * Adaptive source handlers will have more complicated workflows before passing
13674 * video data to the video element
13675 *
13676 * @param  {Object} source    The source object
13677 * @param  {Flash} tech   The instance of the Flash tech
13678 */
13679Flash.nativeSourceHandler.handleSource = function (source, tech) {
13680  tech.setSrc(source.src);
13681};
13682
13683/*
13684 * Clean up the source handler when disposing the player or switching sources..
13685 * (no cleanup is needed when supporting the format natively)
13686 */
13687Flash.nativeSourceHandler.dispose = function () {};
13688
13689// Register the native source handler
13690Flash.registerSourceHandler(Flash.nativeSourceHandler);
13691
13692Flash.formats = {
13693  'video/flv': 'FLV',
13694  'video/x-flv': 'FLV',
13695  'video/mp4': 'MP4',
13696  'video/m4v': 'MP4'
13697};
13698
13699Flash.onReady = function (currSwf) {
13700  var el = Dom.getEl(currSwf);
13701  var tech = el && el.tech;
13702
13703  // if there is no el then the tech has been disposed
13704  // and the tech element was removed from the player div
13705  if (tech && tech.el()) {
13706    // check that the flash object is really ready
13707    Flash.checkReady(tech);
13708  }
13709};
13710
13711// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
13712// If it's not ready, we set a timeout to check again shortly.
13713Flash.checkReady = function (tech) {
13714  // stop worrying if the tech has been disposed
13715  if (!tech.el()) {
13716    return;
13717  }
13718
13719  // check if API property exists
13720  if (tech.el().vjs_getProperty) {
13721    // tell tech it's ready
13722    tech.triggerReady();
13723  } else {
13724    // wait longer
13725    this.setTimeout(function () {
13726      Flash['checkReady'](tech);
13727    }, 50);
13728  }
13729};
13730
13731// Trigger events from the swf on the player
13732Flash.onEvent = function (swfID, eventName) {
13733  var tech = Dom.getEl(swfID).tech;
13734  tech.trigger(eventName);
13735};
13736
13737// Log errors from the swf
13738Flash.onError = function (swfID, err) {
13739  var tech = Dom.getEl(swfID).tech;
13740
13741  // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
13742  if (err === 'srcnotfound') {
13743    return tech.error(4);
13744  }
13745
13746  // trigger a custom error
13747  tech.error('FLASH: ' + err);
13748};
13749
13750// Flash Version Check
13751Flash.version = function () {
13752  var version = '0,0,0';
13753
13754  // IE
13755  try {
13756    version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
13757
13758    // other browsers
13759  } catch (e) {
13760    try {
13761      if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
13762        version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
13763      }
13764    } catch (err) {}
13765  }
13766  return version.split(',');
13767};
13768
13769// Flash embedding method. Only used in non-iframe mode
13770Flash.embed = function (swf, flashVars, params, attributes) {
13771  var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
13772
13773  // Get element by embedding code and retrieving created element
13774  var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
13775
13776  return obj;
13777};
13778
13779Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
13780  var objTag = '<object type="application/x-shockwave-flash" ';
13781  var flashVarsString = '';
13782  var paramsString = '';
13783  var attrsString = '';
13784
13785  // Convert flash vars to string
13786  if (flashVars) {
13787    Object.getOwnPropertyNames(flashVars).forEach(function (key) {
13788      flashVarsString += key + '=' + flashVars[key] + '&amp;';
13789    });
13790  }
13791
13792  // Add swf, flashVars, and other default params
13793  params = _objectAssign2['default']({
13794    'movie': swf,
13795    'flashvars': flashVarsString,
13796    'allowScriptAccess': 'always', // Required to talk to swf
13797    'allowNetworking': 'all' // All should be default, but having security issues.
13798  }, params);
13799
13800  // Create param tags string
13801  Object.getOwnPropertyNames(params).forEach(function (key) {
13802    paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
13803  });
13804
13805  attributes = _objectAssign2['default']({
13806    // Add swf to attributes (need both for IE and Others to work)
13807    'data': swf,
13808
13809    // Default to 100% width/height
13810    'width': '100%',
13811    'height': '100%'
13812
13813  }, attributes);
13814
13815  // Create Attributes string
13816  Object.getOwnPropertyNames(attributes).forEach(function (key) {
13817    attrsString += key + '="' + attributes[key] + '" ';
13818  });
13819
13820  return '' + objTag + attrsString + '>' + paramsString + '</object>';
13821};
13822
13823// Run Flash through the RTMP decorator
13824_flashRtmp2['default'](Flash);
13825
13826_component2['default'].registerComponent('Flash', Flash);
13827_tech2['default'].registerTech('Flash', Flash);
13828exports['default'] = Flash;
13829module.exports = exports['default'];
13830
13831},{"../component":66,"../utils/dom.js":131,"../utils/time-ranges.js":139,"../utils/url.js":141,"./flash-rtmp":114,"./tech":118,"global/window":2,"object.assign":45}],116:[function(_dereq_,module,exports){
13832/**
13833 * @file html5.js
13834 * HTML5 Media Controller - Wrapper for HTML5 Media API
13835 */
13836
13837'use strict';
13838
13839exports.__esModule = true;
13840
13841function _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; } }
13842
13843function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13844
13845function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
13846
13847function _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
13847onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
13848
13849var _techJs = _dereq_('./tech.js');
13850
13851var _techJs2 = _interopRequireDefault(_techJs);
13852
13853var _component = _dereq_('../component');
13854
13855var _component2 = _interopRequireDefault(_component);
13856
13857var _utilsDomJs = _dereq_('../utils/dom.js');
13858
13859var Dom = _interopRequireWildcard(_utilsDomJs);
13860
13861var _utilsUrlJs = _dereq_('../utils/url.js');
13862
13863var Url = _interopRequireWildcard(_utilsUrlJs);
13864
13865var _utilsFnJs = _dereq_('../utils/fn.js');
13866
13867var Fn = _interopRequireWildcard(_utilsFnJs);
13868
13869var _utilsLogJs = _dereq_('../utils/log.js');
13870
13871var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
13872
13873var _utilsBrowserJs = _dereq_('../utils/browser.js');
13874
13875var browser = _interopRequireWildcard(_utilsBrowserJs);
13876
13877var _globalDocument = _dereq_('global/document');
13878
13879var _globalDocument2 = _interopRequireDefault(_globalDocument);
13880
13881var _globalWindow = _dereq_('global/window');
13882
13883var _globalWindow2 = _interopRequireDefault(_globalWindow);
13884
13885var _objectAssign = _dereq_('object.assign');
13886
13887var _objectAssign2 = _interopRequireDefault(_objectAssign);
13888
13889var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
13890
13891var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
13892
13893/**
13894 * HTML5 Media Controller - Wrapper for HTML5 Media API
13895 *
13896 * @param {Object=} options Object of option names and values
13897 * @param {Function=} ready Ready callback function
13898 * @extends Tech
13899 * @class Html5
13900 */
13901
13902var Html5 = (function (_Tech) {
13903  _inherits(Html5, _Tech);
13904
13905  function Html5(options, ready) {
13906    _classCallCheck(this, Html5);
13907
13908    _Tech.call(this, options, ready);
13909
13910    var source = options.source;
13911
13912    // Set the source if one is provided
13913    // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
13914    // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
13915    // anyway so the error gets fired.
13916    if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.
13916initNetworkState_ === 3)) {
13917      this.setSource(source);
13918    } else {
13919      this.handleLateInit_(this.el_);
13920    }
13921
13922    if (this.el_.hasChildNodes()) {
13923
13924      var nodes = this.el_.childNodes;
13925      var nodesLength = nodes.length;
13926      var removeNodes = [];
13927
13928      while (nodesLength--) {
13929        var node = nodes[nodesLength];
13930        var nodeName = node.nodeName.toLowerCase();
13931
13932        if (nodeName === 'track') {
13933          if (!this.featuresNativeTextTracks) {
13934            // Empty video tag tracks so the built-in player doesn't use them also.
13935            // This may not be fast enough to stop HTML5 browsers from reading the tags
13936            // so we'll need to turn off any default tracks if we're manually doing
13937            // captions and subtitles. videoElement.textTracks
13938            removeNodes.push(node);
13939          } else {
13940            // store HTMLTrackElement and TextTrack to remote list
13941            this.remoteTextTrackEls().addTrackElement_(node);
13942            this.remoteTextTracks().addTrack_(node.track);
13943          }
13944        }
13945      }
13946
13947      for (var i = 0; i < removeNodes.length; i++) {
13948        this.el_.removeChild(removeNodes[i]);
13949      }
13950    }
13951
13952    if (this.featuresNativeTextTracks) {
13953      this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange);
13954      this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd);
13955      this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove);
13956      this.proxyNativeTextTracks_();
13957    }
13958
13959    // Determine if native controls should be used
13960    // Our goal should be to get the custom controls on mobile solid everywhere
13961    // so we can remove this all together. Right now this will block custom
13962    // controls on touch enabled laptops like the Chrome Pixel
13963    if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) {
13964      this.setControls(true);
13965    }
13966
13967    this.triggerReady();
13968  }
13969
13970  /* HTML5 Support Testing ---------------------------------------------------- */
13971
13972  /*
13973  * Element for testing browser HTML5 video capabilities
13974  *
13975  * @type {Element}
13976  * @constant
13977  * @private
13978  */
13979
13980  /**
13981   * Dispose of html5 media element
13982   *
13983   * @method dispose
13984   */
13985
13986  Html5.prototype.dispose = function dispose() {
13987    var tt = this.el().textTracks;
13988    var emulatedTt = this.textTracks();
13989
13990    // remove native event listeners
13991    if (tt && tt.removeEventListener) {
13992      tt.removeEventListener('change', this.handleTextTrackChange_);
13993      tt.removeEventListener('addtrack', this.handleTextTrackAdd_);
13994      tt.removeEventListener('removetrack', this.handleTextTrackRemove_);
13995    }
13996
13997    // clearout the emulated text track list.
13998    var i = emulatedTt.length;
13999
14000    while (i--) {
14001      emulatedTt.removeTrack_(emulatedTt[i]);
14002    }
14003
14004    Html5.disposeMediaElement(this.el_);
14005    _Tech.prototype.dispose.call(this);
14006  };
14007
14008  /**
14009   * Create the component's DOM element
14010   *
14011   * @return {Element}
14012   * @method createEl
14013   */
14014
14015  Html5.prototype.createEl = function createEl() {
14016    var el = this.options_.tag;
14017
14018    // Check if this browser supports moving the element into the box.
14019    // On the iPhone video will break if you move the element,
14020    // So we have to create a brand new element.
14021    if (!el || this['movingMediaElementInDOM'] === false) {
14022
14023      // If the original tag is still there, clone and remove it.
14024      if (el) {
14025        var clone = el.cloneNode(true);
14026        el.parentNode.insertBefore(clone, el);
14027        Html5.disposeMediaElement(el);
14028        el = clone;
14029      } else {
14030        el = _globalDocument2['default'].createElement('video');
14031
14032        // determine if native controls should be used
14033        var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
14034        var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes);
14035        if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
14036          delete attributes.controls;
14037        }
14038
14039        Dom.setElAttributes(el, _objectAssign2['default'](attributes, {
14040          id: this.options_.techId,
14041          'class': 'vjs-tech'
14042        }));
14043      }
14044    }
14045
14046    // Update specific tag settings, in case they were overridden
14047    var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
14048    for (var i = settingsAttrs.length - 1; i >= 0; i--) {
14049      var attr = settingsAttrs[i];
14050      var overwriteAttrs = {};
14051      if (typeof this.options_[attr] !== 'undefined') {
14052        overwriteAttrs[attr] = this.options_[attr];
14053      }
14054      Dom.setElAttributes(el, overwriteAttrs);
14055    }
14056
14057    return el;
14058    // jenniisawesome = true;
14059  };
14060
14061  // If we're loading the playback object after it has started loading
14062  // or playing the video (often with autoplay on) then the loadstart event
14063  // has already fired and we need to fire it manually because many things
14064  // rely on it.
14065
14066  Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
14067    var _this = this;
14068
14069    if (el.networkState === 0 || el.networkState === 3) {
14070      // The video element hasn't started loading the source yet
14071      // or didn't find a source
14072      return;
14073    }
14074
14075    if (el.readyState === 0) {
14076      var _ret = (function () {
14077        // NetworkState is set synchronously BUT loadstart is fired at the
14078        // end of the current stack, usually before setInterval(fn, 0).
14079        // So at this point we know loadstart may have already fired or is
14080        // about to fire, and either way the player hasn't seen it yet.
14081        // We don't want to fire loadstart prematurely here and cause a
14082        // double loadstart so we'll wait and see if it happens between now
14083        // and the next loop, and fire it if not.
14084        // HOWEVER, we also want to make sure it fires before loadedmetadata
14085        // which could also happen between now and the next loop, so we'll
14086        // watch for that also.
14087        var loadstartFired = false;
14088        var setLoadstartFired = function setLoadstartFired() {
14089          loadstartFired = true;
14090        };
14091        _this.on('loadstart', setLoadstartFired);
14092
14093        var triggerLoadstart = function triggerLoadstart() {
14094          // We did miss the original loadstart. Make sure the player
14095          // sees loadstart before loadedmetadata
14096          if (!loadstartFired) {
14097            this.trigger('loadstart');
14098          }
14099        };
14100        _this.on('loadedmetadata', triggerLoadstart);
14101
14102        _this.ready(function () {
14103          this.off('loadstart', setLoadstartFired);
14104          this.off('loadedmetadata', triggerLoadstart);
14105
14106          if (!loadstartFired) {
14107            // We did miss the original native loadstart. Fire it now.
14108            this.trigger('loadstart');
14109          }
14110        });
14111
14112        return {
14113          v: undefined
14114        };
14115      })();
14116
14117      if (typeof _ret === 'object') return _ret.v;
14118    }
14119
14120    // From here on we know that loadstart already fired and we missed it.
14121    // The other readyState events aren't as much of a problem if we double
14122    // them, so not going to go to as much trouble as loadstart to prevent
14123    // that unless we find reason to.
14124    var eventsToTrigger = ['loadstart'];
14125
14126    // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
14127    eventsToTrigger.push('loadedmetadata');
14128
14129    // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
14130    if (el.readyState >= 2) {
14131      eventsToTrigger.push('loadeddata');
14132    }
14133
14134    // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
14135    if (el.readyState >= 3) {
14136      eventsToTrigger.push('canplay');
14137    }
14138
14139    // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
14140    if (el.readyState >= 4) {
14141      eventsToTrigger.push('canplaythrough');
14142    }
14143
14144    // We still need to give the player time to add event listeners
14145    this.ready(function () {
14146      eventsToTrigger.forEach(function (type) {
14147        this.trigger(type);
14148      }, this);
14149    });
14150  };
14151
14152  Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
14153    var tt = this.el().textTracks;
14154
14155    if (tt && tt.addEventListener) {
14156      tt.addEventListener('change', this.handleTextTrackChange_);
14157      tt.addEventListener('addtrack', this.handleTextTrackAdd_);
14158      tt.addEventListener('removetrack', this.handleTextTrackRemove_);
14159    }
14160  };
14161
14162  Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
14163    var tt = this.textTracks();
14164    this.textTracks().trigger({
14165      type: 'change',
14166      target: tt,
14167      currentTarget: tt,
14168      srcElement: tt
14169    });
14170  };
14171
14172  Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
14173    this.textTracks().addTrack_(e.track);
14174  };
14175
14176  Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
14177    this.textTracks().removeTrack_(e.track);
14178  };
14179
14180  /**
14181   * Play for html5 tech
14182   *
14183   * @method play
14184   */
14185
14186  Html5.prototype.play = function play() {
14187    this.el_.play();
14188  };
14189
14190  /**
14191   * Pause for html5 tech
14192   *
14193   * @method pause
14194   */
14195
14196  Html5.prototype.pause = function pause() {
14197    this.el_.pause();
14198  };
14199
14200  /**
14201   * Paused for html5 tech
14202   *
14203   * @return {Boolean}
14204   * @method paused
14205   */
14206
14207  Html5.prototype.paused = function paused() {
14208    return this.el_.paused;
14209  };
14210
14211  /**
14212   * Get current time
14213   *
14214   * @return {Number}
14215   * @method currentTime
14216   */
14217
14218  Html5.prototype.currentTime = function currentTime() {
14219    return this.el_.currentTime;
14220  };
14221
14222  /**
14223   * Set current time
14224   *
14225   * @param {Number} seconds Current time of video
14226   * @method setCurrentTime
14227   */
14228
14229  Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
14230    try {
14231      this.el_.currentTime = seconds;
14232    } catch (e) {
14233      _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)');
14234      // this.warning(VideoJS.warnings.videoNotReady);
14235    }
14236  };
14237
14238  /**
14239   * Get duration
14240   *
14241   * @return {Number}
14242   * @method duration
14243   */
14244
14245  Html5.prototype.duration = function duration() {
14246    return this.el_.duration || 0;
14247  };
14248
14249  /**
14250   * Get a TimeRange object that represents the intersection
14251   * of the time ranges for which the user agent has all
14252   * relevant media
14253   *
14254   * @return {TimeRangeObject}
14255   * @method buffered
14256   */
14257
14258  Html5.prototype.buffered = function buffered() {
14259    return this.el_.buffered;
14260  };
14261
14262  /**
14263   * Get volume level
14264   *
14265   * @return {Number}
14266   * @method volume
14267   */
14268
14269  Html5.prototype.volume = function volume() {
14270    return this.el_.volume;
14271  };
14272
14273  /**
14274   * Set volume level
14275   *
14276   * @param {Number} percentAsDecimal Volume percent as a decimal
14277   * @method setVolume
14278   */
14279
14280  Html5.prototype.setVolume = function setVolume(percentAsDecimal) {
14281    this.el_.volume = percentAsDecimal;
14282  };
14283
14284  /**
14285   * Get if muted
14286   *
14287   * @return {Boolean}
14288   * @method muted
14289   */
14290
14291  Html5.prototype.muted = function muted() {
14292    return this.el_.muted;
14293  };
14294
14295  /**
14296   * Set muted
14297   *
14298   * @param {Boolean} If player is to be muted or note
14299   * @method setMuted
14300   */
14301
14302  Html5.prototype.setMuted = function setMuted(muted) {
14303    this.el_.muted = muted;
14304  };
14305
14306  /**
14307   * Get player width
14308   *
14309   * @return {Number}
14310   * @method width
14311   */
14312
14313  Html5.prototype.width = function width() {
14314    return this.el_.offsetWidth;
14315  };
14316
14317  /**
14318   * Get player height
14319   *
14320   * @return {Number}
14321   * @method height
14322   */
14323
14324  Html5.prototype.height = function height() {
14325    return this.el_.offsetHeight;
14326  };
14327
14328  /**
14329   * Get if there is fullscreen support
14330   *
14331   * @return {Boolean}
14332   * @method supportsFullScreen
14333   */
14334
14335  Html5.prototype.supportsFullScreen = function supportsFullScreen() {
14336    if (typeof this.el_.webkitEnterFullScreen === 'function') {
14337      var userAgent = _globalWindow2['default'].navigator.userAgent;
14338      // Seems to be broken in Chromium/Chrome && Safari in Leopard
14339      if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
14340        return true;
14341      }
14342    }
14343    return false;
14344  };
14345
14346  /**
14347   * Request to enter fullscreen
14348   *
14349   * @method enterFullScreen
14350   */
14351
14352  Html5.prototype.enterFullScreen = function enterFullScreen() {
14353    var video = this.el_;
14354
14355    if ('webkitDisplayingFullscreen' in video) {
14356      this.one('webkitbeginfullscreen', function () {
14357        this.one('webkitendfullscreen', function () {
14358          this.trigger('fullscreenchange', { isFullscreen: false });
14359        });
14360
14361        this.trigger('fullscreenchange', { isFullscreen: true });
14362      });
14363    }
14364
14365    if (video.paused && video.networkState <= video.HAVE_METADATA) {
14366      // attempt to prime the video element for programmatic access
14367      // this isn't necessary on the desktop but shouldn't hurt
14368      this.el_.play();
14369
14370      // playing and pausing synchronously during the transition to fullscreen
14371      // can get iOS ~6.1 devices into a play/pause loop
14372      this.setTimeout(function () {
14373        video.pause();
14374        video.webkitEnterFullScreen();
14375      }, 0);
14376    } else {
14377      video.webkitEnterFullScreen();
14378    }
14379  };
14380
14381  /**
14382   * Request to exit fullscreen
14383   *
14384   * @method exitFullScreen
14385   */
14386
14387  Html5.prototype.exitFullScreen = function exitFullScreen() {
14388    this.el_.webkitExitFullScreen();
14389  };
14390
14391  /**
14392   * Get/set video
14393   *
14394   * @param {Object=} src Source object
14395   * @return {Object}
14396   * @method src
14397   */
14398
14399  Html5.prototype.src = function src(_src) {
14400    if (_src === undefined) {
14401      return this.el_.src;
14402    } else {
14403      // Setting src through `src` instead of `setSrc` will be deprecated
14404      this.setSrc(_src);
14405    }
14406  };
14407
14408  /**
14409   * Set video
14410   *
14411   * @param {Object} src Source object
14412   * @deprecated
14413   * @method setSrc
14414   */
14415
14416  Html5.prototype.setSrc = function setSrc(src) {
14417    this.el_.src = src;
14418  };
14419
14420  /**
14421   * Load media into player
14422   *
14423   * @method load
14424   */
14425
14426  Html5.prototype.load = function load() {
14427    this.el_.load();
14428  };
14429
14430  /**
14431   * Reset the tech. Removes all sources and calls `load`.
14432   *
14433   * @method reset
14434   */
14435
14436  Html5.prototype.reset = function reset() {
14437    Html5.resetMediaElement(this.el_);
14438  };
14439
14440  /**
14441   * Get current source
14442   *
14443   * @return {Object}
14444   * @method currentSrc
14445   */
14446
14447  Html5.prototype.currentSrc = function currentSrc() {
14448    if (this.currentSource_) {
14449      return this.currentSource_.src;
14450    } else {
14451      return this.el_.currentSrc;
14452    }
14453  };
14454
14455  /**
14456   * Get poster
14457   *
14458   * @return {String}
14459   * @method poster
14460   */
14461
14462  Html5.prototype.poster = function poster() {
14463    return this.el_.poster;
14464  };
14465
14466  /**
14467   * Set poster
14468   *
14469   * @param {String} val URL to poster image
14470   * @method
14471   */
14472
14473  Html5.prototype.setPoster = function setPoster(val) {
14474    this.el_.poster = val;
14475  };
14476
14477  /**
14478   * Get preload attribute
14479   *
14480   * @return {String}
14481   * @method preload
14482   */
14483
14484  Html5.prototype.preload = function preload() {
14485    return this.el_.preload;
14486  };
14487
14488  /**
14489   * Set preload attribute
14490   *
14491   * @param {String} val Value for preload attribute
14492   * @method setPreload
14493   */
14494
14495  Html5.prototype.setPreload = function setPreload(val) {
14496    this.el_.preload = val;
14497  };
14498
14499  /**
14500   * Get autoplay attribute
14501   *
14502   * @return {String}
14503   * @method autoplay
14504   */
14505
14506  Html5.prototype.autoplay = function autoplay() {
14507    return this.el_.autoplay;
14508  };
14509
14510  /**
14511   * Set autoplay attribute
14512   *
14513   * @param {String} val Value for preload attribute
14514   * @method setAutoplay
14515   */
14516
14517  Html5.prototype.setAutoplay = function setAutoplay(val) {
14518    this.el_.autoplay = val;
14519  };
14520
14521  /**
14522   * Get controls attribute
14523   *
14524   * @return {String}
14525   * @method controls
14526   */
14527
14528  Html5.prototype.controls = function controls() {
14529    return this.el_.controls;
14530  };
14531
14532  /**
14533   * Set controls attribute
14534   *
14535   * @param {String} val Value for controls attribute
14536   * @method setControls
14537   */
14538
14539  Html5.prototype.setControls = function setControls(val) {
14540    this.el_.controls = !!val;
14541  };
14542
14543  /**
14544   * Get loop attribute
14545   *
14546   * @return {String}
14547   * @method loop
14548   */
14549
14550  Html5.prototype.loop = function loop() {
14551    return this.el_.loop;
14552  };
14553
14554  /**
14555   * Set loop attribute
14556   *
14557   * @param {String} val Value for loop attribute
14558   * @method setLoop
14559   */
14560
14561  Html5.prototype.setLoop = function setLoop(val) {
14562    this.el_.loop = val;
14563  };
14564
14565  /**
14566   * Get error value
14567   *
14568   * @return {String}
14569   * @method error
14570   */
14571
14572  Html5.prototype.error = function error() {
14573    return this.el_.error;
14574  };
14575
14576  /**
14577   * Get whether or not the player is in the "seeking" state
14578   *
14579   * @return {Boolean}
14580   * @method seeking
14581   */
14582
14583  Html5.prototype.seeking = function seeking() {
14584    return this.el_.seeking;
14585  };
14586
14587  /**
14588   * Get a TimeRanges object that represents the
14589   * ranges of the media resource to which it is possible
14590   * for the user agent to seek.
14591   *
14592   * @return {TimeRangeObject}
14593   * @method seekable
14594   */
14595
14596  Html5.prototype.seekable = function seekable() {
14597    return this.el_.seekable;
14598  };
14599
14600  /**
14601   * Get if video ended
14602   *
14603   * @return {Boolean}
14604   * @method ended
14605   */
14606
14607  Html5.prototype.ended = function ended() {
14608    return this.el_.ended;
14609  };
14610
14611  /**
14612   * Get the value of the muted content attribute
14613   * This attribute has no dynamic effect, it only
14614   * controls the default state of the element
14615   *
14616   * @return {Boolean}
14617   * @method defaultMuted
14618   */
14619
14620  Html5.prototype.defaultMuted = function defaultMuted() {
14621    return this.el_.defaultMuted;
14622  };
14623
14624  /**
14625   * Get desired speed at which the media resource is to play
14626   *
14627   * @return {Number}
14628   * @method playbackRate
14629   */
14630
14631  Html5.prototype.playbackRate = function playbackRate() {
14632    return this.el_.playbackRate;
14633  };
14634
14635  /**
14636   * Returns a TimeRanges object that represents the ranges of the
14637   * media resource that the user agent has played.
14638   * @return {TimeRangeObject} the range of points on the media
14639   * timeline that has been reached through normal playback
14640   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played
14641   */
14642
14643  Html5.prototype.played = function played() {
14644    return this.el_.played;
14645  };
14646
14647  /**
14648   * Set desired speed at which the media resource is to play
14649   *
14650   * @param {Number} val Speed at which the media resource is to play
14651   * @method setPlaybackRate
14652   */
14653
14654  Html5.prototype.setPlaybackRate = function setPlaybackRate(val) {
14655    this.el_.playbackRate = val;
14656  };
14657
14658  /**
14659   * Get the current state of network activity for the element, from
14660   * the list below
14661   * NETWORK_EMPTY (numeric value 0)
14662   * NETWORK_IDLE (numeric value 1)
14663   * NETWORK_LOADING (numeric value 2)
14664   * NETWORK_NO_SOURCE (numeric value 3)
14665   *
14666   * @return {Number}
14667   * @method networkState
14668   */
14669
14670  Html5.prototype.networkState = function networkState() {
14671    return this.el_.networkState;
14672  };
14673
14674  /**
14675   * Get a value that expresses the current state of the element
14676   * with respect to rendering the current playback position, from
14677   * the codes in the list below
14678   * HAVE_NOTHING (numeric value 0)
14679   * HAVE_METADATA (numeric value 1)
14680   * HAVE_CURRENT_DATA (numeric value 2)
14681   * HAVE_FUTURE_DATA (numeric value 3)
14682   * HAVE_ENOUGH_DATA (numeric value 4)
14683   *
14684   * @return {Number}
14685   * @method readyState
14686   */
14687
14688  Html5.prototype.readyState = function readyState() {
14689    return this.el_.readyState;
14690  };
14691
14692  /**
14693   * Get width of video
14694   *
14695   * @return {Number}
14696   * @method videoWidth
14697   */
14698
14699  Html5.prototype.videoWidth = function videoWidth() {
14700    return this.el_.videoWidth;
14701  };
14702
14703  /**
14704   * Get height of video
14705   *
14706   * @return {Number}
14707   * @method videoHeight
14708   */
14709
14710  Html5.prototype.videoHeight = function videoHeight() {
14711    return this.el_.videoHeight;
14712  };
14713
14714  /**
14715   * Get text tracks
14716   *
14717   * @return {TextTrackList}
14718   * @method textTracks
14719   */
14720
14721  Html5.prototype.textTracks = function textTracks() {
14722    return _Tech.prototype.textTracks.call(this);
14723  };
14724
14725  /**
14726   * Creates and returns a text track object
14727   *
14728   * @param {String} kind Text track kind (subtitles, captions, descriptions
14729   *                                       chapters and metadata)
14730   * @param {String=} label Label to identify the text track
14731   * @param {String=} language Two letter language abbreviation
14732   * @return {TextTrackObject}
14733   * @method addTextTrack
14734   */
14735
14736  Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
14737    if (!this['featuresNativeTextTracks']) {
14738      return _Tech.prototype.addTextTrack.call(this, kind, label, language);
14739    }
14740
14741    return this.el_.addTextTrack(kind, label, language);
14742  };
14743
14744  /**
14745   * Creates a remote text track object and returns a html track element
14746   *
14747   * @param {Object} options The object should contain values for
14748   * kind, language, label and src (location of the WebVTT file)
14749   * @return {HTMLTrackElement}
14750   * @method addRemoteTextTrack
14751   */
14752
14753  Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
14754    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
14755
14756    if (!this['featuresNativeTextTracks']) {
14757      return _Tech.prototype.addRemoteTextTrack.call(this, options);
14758    }
14759
14760    var htmlTrackElement = _globalDocument2['default'].createElement('track');
14761
14762    if (options.kind) {
14763      htmlTrackElement.kind = options.kind;
14764    }
14765    if (options.label) {
14766      htmlTrackElement.label = options.label;
14767    }
14768    if (options.language || options.srclang) {
14769      htmlTrackElement.srclang = options.language || options.srclang;
14770    }
14771    if (options['default']) {
14772      htmlTrackElement['default'] = options['default'];
14773    }
14774    if (options.id) {
14775      htmlTrackElement.id = options.id;
14776    }
14777    if (options.src) {
14778      htmlTrackElement.src = options.src;
14779    }
14780
14781    this.el().appendChild(htmlTrackElement);
14782
14783    // store HTMLTrackElement and TextTrack to remote list
14784    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
14785    this.remoteTextTracks().addTrack_(htmlTrackElement.track);
14786
14787    return htmlTrackElement;
14788  };
14789
14790  /**
14791   * Remove remote text track from TextTrackList object
14792   *
14793   * @param {TextTrackObject} track Texttrack object to remove
14794   * @method removeRemoteTextTrack
14795   */
14796
14797  Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
14798    if (!this['featuresNativeTextTracks']) {
14799      return _Tech.prototype.removeRemoteTextTrack.call(this, track);
14800    }
14801
14802    var tracks = undefined,
14803        i = undefined;
14804
14805    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
14806
14807    // remove HTMLTrackElement and TextTrack from remote list
14808    this.remoteTextTrackEls().removeTrackElement_(trackElement);
14809    this.remoteTextTracks().removeTrack_(track);
14810
14811    tracks = this.$$('track');
14812
14813    i = tracks.length;
14814    while (i--) {
14815      if (track === tracks[i] || track === tracks[i].track) {
14816        this.el().removeChild(tracks[i]);
14817      }
14818    }
14819  };
14820
14821  return Html5;
14822})(_techJs2['default']);
14823
14824Html5.TEST_VID = _globalDocument2['default'].createElement('video');
14825var track = _globalDocument2['default'].createElement('track');
14826track.kind = 'captions';
14827track.srclang = 'en';
14828track.label = 'English';
14829Html5.TEST_VID.appendChild(track);
14830
14831/*
14832 * Check if HTML5 video is supported by this browser/device
14833 *
14834 * @return {Boolean}
14835 */
14836Html5.isSupported = function () {
14837  // IE9 with no Media Player is a LIAR! (#984)
14838  try {
14839    Html5.TEST_VID['volume'] = 0.5;
14840  } catch (e) {
14841    return false;
14842  }
14843
14844  return !!Html5.TEST_VID.canPlayType;
14845};
14846
14847// Add Source Handler pattern functions to this tech
14848_techJs2['default'].withSourceHandlers(Html5);
14849
14850/*
14851 * The default native source handler.
14852 * This simply passes the source to the video element. Nothing fancy.
14853 *
14854 * @param  {Object} source   The source object
14855 * @param  {Html5} tech  The instance of the HTML5 tech
14856 */
14857Html5.nativeSourceHandler = {};
14858
14859/*
14860 * Check if the video element can play the given videotype
14861 *
14862 * @param  {String} type    The mimetype to check
14863 * @return {String}         'probably', 'maybe', or '' (empty string)
14864 */
14865Html5.nativeSourceHandler.canPlayType = function (type) {
14866  // IE9 on Windows 7 without MediaPlayer throws an error here
14867  // https://github.com/videojs/video.js/issues/519
14868  try {
14869    return Html5.TEST_VID.canPlayType(type);
14870  } catch (e) {
14871    return '';
14872  }
14873};
14874
14875/*
14876 * Check if the video element can handle the source natively
14877 *
14878 * @param  {Object} source  The source object
14879 * @return {String}         'probably', 'maybe', or '' (empty string)
14880 */
14881Html5.nativeSourceHandler.canHandleSource = function (source) {
14882  var match, ext;
14883
14884  // If a type was provided we should rely on that
14885  if (source.type) {
14886    return Html5.nativeSourceHandler.canPlayType(source.type);
14887  } else if (source.src) {
14888    // If no type, fall back to checking 'video/[EXTENSION]'
14889    ext = Url.getFileExtension(source.src);
14890
14891    return Html5.nativeSourceHandler.canPlayType('video/' + ext);
14892  }
14893
14894  return '';
14895};
14896
14897/*
14898 * Pass the source to the video element
14899 * Adaptive source handlers will have more complicated workflows before passing
14900 * video data to the video element
14901 *
14902 * @param  {Object} source    The source object
14903 * @param  {Html5} tech   The instance of the Html5 tech
14904 */
14905Html5.nativeSourceHandler.handleSource = function (source, tech) {
14906  tech.setSrc(source.src);
14907};
14908
14909/*
14910* Clean up the source handler when disposing the player or switching sources..
14911* (no cleanup is needed when supporting the format natively)
14912*/
14913Html5.nativeSourceHandler.dispose = function () {};
14914
14915// Register the native source handler
14916Html5.registerSourceHandler(Html5.nativeSourceHandler);
14917
14918/*
14919 * Check if the volume can be changed in this browser/device.
14920 * Volume cannot be changed in a lot of mobile devices.
14921 * Specifically, it can't be changed from 1 on iOS.
14922 *
14923 * @return {Boolean}
14924 */
14925Html5.canControlVolume = function () {
14926  var volume = Html5.TEST_VID.volume;
14927  Html5.TEST_VID.volume = volume / 2 + 0.1;
14928  return volume !== Html5.TEST_VID.volume;
14929};
14930
14931/*
14932 * Check if playbackRate is supported in this browser/device.
14933 *
14934 * @return {Number} [description]
14935 */
14936Html5.canControlPlaybackRate = function () {
14937  var playbackRate = Html5.TEST_VID.playbackRate;
14938  Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
14939  return playbackRate !== Html5.TEST_VID.playbackRate;
14940};
14941
14942/*
14943 * Check to see if native text tracks are supported by this browser/device
14944 *
14945 * @return {Boolean}
14946 */
14947Html5.supportsNativeTextTracks = function () {
14948  var supportsTextTracks;
14949
14950  // Figure out native text track support
14951  // If mode is a number, we cannot change it because it'll disappear from view.
14952  // Browsers with numeric modes include IE10 and older (<=2013) samsung android models.
14953  // Firefox isn't playing nice either with modifying the mode
14954  // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862
14955  supportsTextTracks = !!Html5.TEST_VID.textTracks;
14956  if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) {
14957    supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number';
14958  }
14959  if (supportsTextTracks && browser.IS_FIREFOX) {
14960    supportsTextTracks = false;
14961  }
14962  if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) {
14963    supportsTextTracks = false;
14964  }
14965
14966  return supportsTextTracks;
14967};
14968
14969/**
14970 * An array of events available on the Html5 tech.
14971 *
14972 * @private
14973 * @type {Array}
14974 */
14975Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
14976
14977/*
14978 * Set the tech's volume control support status
14979 *
14980 * @type {Boolean}
14981 */
14982Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume();
14983
14984/*
14985 * Set the tech's playbackRate support status
14986 *
14987 * @type {Boolean}
14988 */
14989Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();
14990
14991/*
14992 * Set the tech's status on moving the video element.
14993 * In iOS, if you move a video element in the DOM, it breaks video playback.
14994 *
14995 * @type {Boolean}
14996 */
14997Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS;
14998
14999/*
15000 * Set the the tech's fullscreen resize support status.
15001 * HTML video is able to automatically resize when going to fullscreen.
15002 * (No longer appears to be used. Can probably be removed.)
15003 */
15004Html5.prototype['featuresFullscreenResize'] = true;
15005
15006/*
15007 * Set the tech's progress event support status
15008 * (this disables the manual progress events of the Tech)
15009 */
15010Html5.prototype['featuresProgressEvents'] = true;
15011
15012/*
15013 * Sets the tech's status on native text track support
15014 *
15015 * @type {Boolean}
15016 */
15017Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();
15018
15019// HTML5 Feature detection and Device Fixes --------------------------------- //
15020var canPlayType = undefined;
15021var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15022var mp4RE = /^video\/mp4/i;
15023
15024Html5.patchCanPlayType = function () {
15025  // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15026  if (browser.ANDROID_VERSION >= 4.0) {
15027    if (!canPlayType) {
15028      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
15029    }
15030
15031    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15032      if (type && mpegurlRE.test(type)) {
15033        return 'maybe';
15034      }
15035      return canPlayType.call(this, type);
15036    };
15037  }
15038
15039  // Override Android 2.2 and less canPlayType method which is broken
15040  if (browser.IS_OLD_ANDROID) {
15041    if (!canPlayType) {
15042      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
15043    }
15044
15045    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15046      if (type && mp4RE.test(type)) {
15047        return 'maybe';
15048      }
15049      return canPlayType.call(this, type);
15050    };
15051  }
15052};
15053
15054Html5.unpatchCanPlayType = function () {
15055  var r = Html5.TEST_VID.constructor.prototype.canPlayType;
15056  Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
15057  canPlayType = null;
15058  return r;
15059};
15060
15061// by default, patch the video element
15062Html5.patchCanPlayType();
15063
15064Html5.disposeMediaElement = function (el) {
15065  if (!el) {
15066    return;
15067  }
15068
15069  if (el.parentNode) {
15070    el.parentNode.removeChild(el);
15071  }
15072
15073  // remove any child track or source nodes to prevent their loading
15074  while (el.hasChildNodes()) {
15075    el.removeChild(el.firstChild);
15076  }
15077
15078  // remove any src reference. not setting `src=''` because that causes a warning
15079  // in firefox
15080  el.removeAttribute('src');
15081
15082  // force the media element to update its loading state by calling load()
15083  // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
15084  if (typeof el.load === 'function') {
15085    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15086    (function () {
15087      try {
15088        el.load();
15089      } catch (e) {
15090        // not supported
15091      }
15092    })();
15093  }
15094};
15095
15096Html5.resetMediaElement = function (el) {
15097  if (!el) {
15098    return;
15099  }
15100
15101  var sources = el.querySelectorAll('source');
15102  var i = sources.length;
15103  while (i--) {
15104    el.removeChild(sources[i]);
15105  }
15106
15107  // remove any src reference.
15108  // not setting `src=''` because that throws an error
15109  el.removeAttribute('src');
15110
15111  if (typeof el.load === 'function') {
15112    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15113    (function () {
15114      try {
15115        el.load();
15116      } catch (e) {}
15117    })();
15118  }
15119};
15120
15121_component2['default'].registerComponent('Html5', Html5);
15122_techJs2['default'].registerTech('Html5', Html5);
15123exports['default'] = Html5;
15124module.exports = exports['default'];
15125
15126},{"../component":66,"../utils/browser.js":128,"../utils/dom.js":131,"../utils/fn.js":133,"../utils/log.js":136,"../utils/merge-options.js":137,"../utils/url.js":141,"./tech.js":118,"global/document":1,"global/window":2,"object.assign":45}
15126],117:[function(_dereq_,module,exports){
15127/**
15128 * @file loader.js
15129 */
15130'use strict';
15131
15132exports.__esModule = true;
15133
15134function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
15135
15136function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
15137
15138function _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; }
15139
15140var _componentJs = _dereq_('../component.js');
15141
15142var _componentJs2 = _interopRequireDefault(_componentJs);
15143
15144var _techJs = _dereq_('./tech.js');
15145
15146var _techJs2 = _interopRequireDefault(_techJs);
15147
15148var _globalWindow = _dereq_('global/window');
15149
15150var _globalWindow2 = _interopRequireDefault(_globalWindow);
15151
15152var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
15153
15154var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
15155
15156/**
15157 * The Media Loader is the component that decides which playback technology to load
15158 * when the player is initialized.
15159 *
15160 * @param {Object} player  Main Player
15161 * @param {Object=} options Object of option names and values
15162 * @param {Function=} ready    Ready callback function
15163 * @extends Component
15164 * @class MediaLoader
15165 */
15166
15167var MediaLoader = (function (_Component) {
15168  _inherits(MediaLoader, _Component);
15169
15170  function MediaLoader(player, options, ready) {
15171    _classCallCheck(this, MediaLoader);
15172
15173    _Component.call(this, player, options, ready);
15174
15175    // If there are no sources when the player is initialized,
15176    // load the first supported playback technology.
15177
15178    if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
15179      for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) {
15180        var techName = _utilsToTitleCaseJs2['default'](j[i]);
15181        var tech = _techJs2['default'].getTech(techName);
15182        // Support old behavior of techs being registered as components.
15183        // Remove once that deprecated behavior is removed.
15184        if (!techName) {
15185          tech = _componentJs2['default'].getComponent(techName);
15186        }
15187
15188        // Check if the browser supports this technology
15189        if (tech && tech.isSupported()) {
15190          player.loadTech_(techName);
15191          break;
15192        }
15193      }
15194    } else {
15195      // // Loop through playback technologies (HTML5, Flash) and check for support.
15196      // // Then load the best source.
15197      // // A few assumptions here:
15198      // //   All playback technologies respect preload false.
15199      player.src(options.playerOptions['sources']);
15200    }
15201  }
15202
15203  return MediaLoader;
15204})(_componentJs2['default']);
15205
15206_componentJs2['default'].registerComponent('MediaLoader', MediaLoader);
15207exports['default'] = MediaLoader;
15208module.exports = exports['default'];
15209
15210},{"../component.js":66,"../utils/to-title-case.js":140,"./tech.js":118,"global/window":2}],118:[function(_dereq_,module,exports){
15211/**
15212 * @file tech.js
15213 * Media Technology Controller - Base class for media playback
15214 * technology controllers like Flash and HTML5
15215 */
15216
15217'use strict';
15218
15219exports.__esModule = true;
15220
15221function _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; } }
15222
15223function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
15224
15225function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
15226
15227function _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
15227onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
15228
15229var _component = _dereq_('../component');
15230
15231var _component2 = _interopRequireDefault(_component);
15232
15233var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element');
15234
15235var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement);
15236
15237var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list');
15238
15239var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList);
15240
15241var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
15242
15243var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
15244
15245var _tracksTextTrack = _dereq_('../tracks/text-track');
15246
15247var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
15248
15249var _tracksTextTrackList = _dereq_('../tracks/text-track-list');
15250
15251var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList);
15252
15253var _utilsFnJs = _dereq_('../utils/fn.js');
15254
15255var Fn = _interopRequireWildcard(_utilsFnJs);
15256
15257var _utilsLogJs = _dereq_('../utils/log.js');
15258
15259var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
15260
15261var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
15262
15263var _utilsBufferJs = _dereq_('../utils/buffer.js');
15264
15265var _mediaErrorJs = _dereq_('../media-error.js');
15266
15267var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
15268
15269var _globalWindow = _dereq_('global/window');
15270
15271var _globalWindow2 = _interopRequireDefault(_globalWindow);
15272
15273var _globalDocument = _dereq_('global/document');
15274
15275var _globalDocument2 = _interopRequireDefault(_globalDocument);
15276
15277/**
15278 * Base class for media (HTML5 Video, Flash) controllers
15279 *
15280 * @param {Object=} options Options object
15281 * @param {Function=} ready Ready callback function
15282 * @extends Component
15283 * @class Tech
15284 */
15285
15286var Tech = (function (_Component) {
15287  _inherits(Tech, _Component);
15288
15289  function Tech() {
15290    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
15291    var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];
15292
15293    _classCallCheck(this, Tech);
15294
15295    // we don't want the tech to report user activity automatically.
15296    // This is done manually in addControlsListeners
15297    options.reportTouchActivity = false;
15298    _Component.call(this, null, options, ready);
15299
15300    // keep track of whether the current source has played at all to
15301    // implement a very limited played()
15302    this.hasStarted_ = false;
15303    this.on('playing', function () {
15304      this.hasStarted_ = true;
15305    });
15306    this.on('loadstart', function () {
15307      this.hasStarted_ = false;
15308    });
15309
15310    this.textTracks_ = options.textTracks;
15311
15312    // Manually track progress in cases where the browser/flash player doesn't report it.
15313    if (!this.featuresProgressEvents) {
15314      this.manualProgressOn();
15315    }
15316
15317    // Manually track timeupdates in cases where the browser/flash player doesn't report it.
15318    if (!this.featuresTimeupdateEvents) {
15319      this.manualTimeUpdatesOn();
15320    }
15321
15322    if (options.nativeCaptions === false || options.nativeTextTracks === false) {
15323      this.featuresNativeTextTracks = false;
15324    }
15325
15326    if (!this.featuresNativeTextTracks) {
15327      this.on('ready', this.emulateTextTracks);
15328    }
15329
15330    this.initTextTrackListeners();
15331
15332    // Turn on component tap events
15333    this.emitTapEvents();
15334  }
15335
15336  /*
15337   * List of associated text tracks
15338   *
15339   * @type {Array}
15340   * @private
15341   */
15342
15343  /* Fallbacks for unsupported event types
15344  ================================================================================ */
15345  // Manually trigger progress events based on changes to the buffered amount
15346  // Many flash players and older HTML5 browsers don't send progress or progress-like events
15347  /**
15348   * Turn on progress events
15349   *
15350   * @method manualProgressOn
15351   */
15352
15353  Tech.prototype.manualProgressOn = function manualProgressOn() {
15354    this.on('durationchange', this.onDurationChange);
15355
15356    this.manualProgress = true;
15357
15358    // Trigger progress watching when a source begins loading
15359    this.one('ready', this.trackProgress);
15360  };
15361
15362  /**
15363   * Turn off progress events
15364   *
15365   * @method manualProgressOff
15366   */
15367
15368  Tech.prototype.manualProgressOff = function manualProgressOff() {
15369    this.manualProgress = false;
15370    this.stopTrackingProgress();
15371
15372    this.off('durationchange', this.onDurationChange);
15373  };
15374
15375  /**
15376   * Track progress
15377   *
15378   * @method trackProgress
15379   */
15380
15381  Tech.prototype.trackProgress = function trackProgress() {
15382    this.stopTrackingProgress();
15383    this.progressInterval = this.setInterval(Fn.bind(this, function () {
15384      // Don't trigger unless buffered amount is greater than last time
15385
15386      var numBufferedPercent = this.bufferedPercent();
15387
15388      if (this.bufferedPercent_ !== numBufferedPercent) {
15389        this.trigger('progress');
15390      }
15391
15392      this.bufferedPercent_ = numBufferedPercent;
15393
15394      if (numBufferedPercent === 1) {
15395        this.stopTrackingProgress();
15396      }
15397    }), 500);
15398  };
15399
15400  /**
15401   * Update duration
15402   *
15403   * @method onDurationChange
15404   */
15405
15406  Tech.prototype.onDurationChange = function onDurationChange() {
15407    this.duration_ = this.duration();
15408  };
15409
15410  /**
15411   * Create and get TimeRange object for buffering
15412   *
15413   * @return {TimeRangeObject}
15414   * @method buffered
15415   */
15416
15417  Tech.prototype.buffered = function buffered() {
15418    return _utilsTimeRangesJs.createTimeRange(0, 0);
15419  };
15420
15421  /**
15422   * Get buffered percent
15423   *
15424   * @return {Number}
15425   * @method bufferedPercent
15426   */
15427
15428  Tech.prototype.bufferedPercent = function bufferedPercent() {
15429    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_);
15430  };
15431
15432  /**
15433   * Stops tracking progress by clearing progress interval
15434   *
15435   * @method stopTrackingProgress
15436   */
15437
15438  Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
15439    this.clearInterval(this.progressInterval);
15440  };
15441
15442  /*! Time Tracking -------------------------------------------------------------- */
15443  /**
15444   * Set event listeners for on play and pause and tracking current time
15445   *
15446   * @method manualTimeUpdatesOn
15447   */
15448
15449  Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
15450    this.manualTimeUpdates = true;
15451
15452    this.on('play', this.trackCurrentTime);
15453    this.on('pause', this.stopTrackingCurrentTime);
15454  };
15455
15456  /**
15457   * Remove event listeners for on play and pause and tracking current time
15458   *
15459   * @method manualTimeUpdatesOff
15460   */
15461
15462  Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
15463    this.manualTimeUpdates = false;
15464    this.stopTrackingCurrentTime();
15465    this.off('play', this.trackCurrentTime);
15466    this.off('pause', this.stopTrackingCurrentTime);
15467  };
15468
15469  /**
15470   * Tracks current time
15471   *
15472   * @method trackCurrentTime
15473   */
15474
15475  Tech.prototype.trackCurrentTime = function trackCurrentTime() {
15476    if (this.currentTimeInterval) {
15477      this.stopTrackingCurrentTime();
15478    }
15479    this.currentTimeInterval = this.setInterval(function () {
15480      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
15481    }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
15482  };
15483
15484  /**
15485   * Turn off play progress tracking (when paused or dragging)
15486   *
15487   * @method stopTrackingCurrentTime
15488   */
15489
15490  Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
15491    this.clearInterval(this.currentTimeInterval);
15492
15493    // #1002 - if the video ends right before the next timeupdate would happen,
15494    // the progress bar won't make it all the way to the end
15495    this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
15496  };
15497
15498  /**
15499   * Turn off any manual progress or timeupdate tracking
15500   *
15501   * @method dispose
15502   */
15503
15504  Tech.prototype.dispose = function dispose() {
15505    // clear out text tracks because we can't reuse them between techs
15506    var textTracks = this.textTracks();
15507
15508    if (textTracks) {
15509      var i = textTracks.length;
15510      while (i--) {
15511        this.removeRemoteTextTrack(textTracks[i]);
15512      }
15513    }
15514
15515    // Turn off any manual progress or timeupdate tracking
15516    if (this.manualProgress) {
15517      this.manualProgressOff();
15518    }
15519
15520    if (this.manualTimeUpdates) {
15521      this.manualTimeUpdatesOff();
15522    }
15523
15524    _Component.prototype.dispose.call(this);
15525  };
15526
15527  /**
15528   * Reset the tech. Removes all sources and resets readyState.
15529   *
15530   * @method reset
15531   */
15532
15533  Tech.prototype.reset = function reset() {};
15534
15535  /**
15536   * When invoked without an argument, returns a MediaError object
15537   * representing the current error state of the player or null if
15538   * there is no error. When invoked with an argument, set the current
15539   * error state of the player.
15540   * @param {MediaError=} err    Optional an error object
15541   * @return {MediaError}        the current error object or null
15542   * @method error
15543   */
15544
15545  Tech.prototype.error = function error(err) {
15546    if (err !== undefined) {
15547      if (err instanceof _mediaErrorJs2['default']) {
15548        this.error_ = err;
15549      } else {
15550        this.error_ = new _mediaErrorJs2['default'](err);
15551      }
15552      this.trigger('error');
15553    }
15554    return this.error_;
15555  };
15556
15557  /**
15558   * Return the time ranges that have been played through for the
15559   * current source. This implementation is incomplete. It does not
15560   * track the played time ranges, only whether the source has played
15561   * at all or not.
15562   * @return {TimeRangeObject} a single time range if this video has
15563   * played or an empty set of ranges if not.
15564   * @method played
15565   */
15566
15567  Tech.prototype.played = function played() {
15568    if (this.hasStarted_) {
15569      return _utilsTimeRangesJs.createTimeRange(0, 0);
15570    }
15571    return _utilsTimeRangesJs.createTimeRange();
15572  };
15573
15574  /**
15575   * Set current time
15576   *
15577   * @method setCurrentTime
15578   */
15579
15580  Tech.prototype.setCurrentTime = function setCurrentTime() {
15581    // improve the accuracy of manual timeupdates
15582    if (this.manualTimeUpdates) {
15583      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
15584    }
15585  };
15586
15587  /**
15588   * Initialize texttrack listeners
15589   *
15590   * @method initTextTrackListeners
15591   */
15592
15593  Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
15594    var textTrackListChanges = Fn.bind(this, function () {
15595      this.trigger('texttrackchange');
15596    });
15597
15598    var tracks = this.textTracks();
15599
15600    if (!tracks) return;
15601
15602    tracks.addEventListener('removetrack', textTrackListChanges);
15603    tracks.addEventListener('addtrack', textTrackListChanges);
15604
15605    this.on('dispose', Fn.bind(this, function () {
15606      tracks.removeEventListener('removetrack', textTrackListChanges);
15607      tracks.removeEventListener('addtrack', textTrackListChanges);
15608    }));
15609  };
15610
15611  /**
15612   * Emulate texttracks
15613   *
15614   * @method emulateTextTracks
15615   */
15616
15617  Tech.prototype.emulateTextTracks = function emulateTextTracks() {
15618    var _this = this;
15619
15620    var tracks = this.textTracks();
15621    if (!tracks) {
15622      return;
15623    }
15624
15625    if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) {
15626      var script = _globalDocument2['default'].createElement('script');
15627      script.src = this.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
15628      this.el().parentNode.appendChild(script);
15629      _globalWindow2['default']['WebVTT'] = true;
15630    }
15631
15632    var updateDisplay = function updateDisplay() {
15633      return _this.trigger('texttrackchange');
15634    };
15635    var textTracksChanges = function textTracksChanges() {
15636      updateDisplay();
15637
15638      for (var i = 0; i < tracks.length; i++) {
15639        var track = tracks[i];
15640        track.removeEventListener('cuechange', updateDisplay);
15641        if (track.mode === 'showing') {
15642          track.addEventListener('cuechange', updateDisplay);
15643        }
15644      }
15645    };
15646
15647    textTracksChanges();
15648    tracks.addEventListener('change', textTracksChanges);
15649
15650    this.on('dispose', function () {
15651      tracks.removeEventListener('change', textTracksChanges);
15652    });
15653  };
15654
15655  /*
15656   * Provide default methods for text tracks.
15657   *
15658   * Html5 tech overrides these.
15659   */
15660
15661  /**
15662   * Get texttracks
15663   *
15664   * @returns {TextTrackList}
15665   * @method textTracks
15666   */
15667
15668  Tech.prototype.textTracks = function textTracks() {
15669    this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default']();
15670    return this.textTracks_;
15671  };
15672
15673  /**
15674   * Get remote texttracks
15675   *
15676   * @returns {TextTrackList}
15677   * @method remoteTextTracks
15678   */
15679
15680  Tech.prototype.remoteTextTracks = function remoteTextTracks() {
15681    this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default']();
15682    return this.remoteTextTracks_;
15683  };
15684
15685  /**
15686   * Get remote htmltrackelements
15687   *
15688   * @returns {HTMLTrackElementList}
15689   * @method remoteTextTrackEls
15690   */
15691
15692  Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
15693    this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default']();
15694    return this.remoteTextTrackEls_;
15695  };
15696
15697  /**
15698   * Creates and returns a remote text track object
15699   *
15700   * @param {String} kind Text track kind (subtitles, captions, descriptions
15701   *                                       chapters and metadata)
15702   * @param {String=} label Label to identify the text track
15703   * @param {String=} language Two letter language abbreviation
15704   * @return {TextTrackObject}
15705   * @method addTextTrack
15706   */
15707
15708  Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15709    if (!kind) {
15710      throw new Error('TextTrack kind is required but was not provided');
15711    }
15712
15713    return createTrackHelper(this, kind, label, language);
15714  };
15715
15716  /**
15717   * Creates a remote text track object and returns a emulated html track element
15718   *
15719   * @param {Object} options The object should contain values for
15720   * kind, language, label and src (location of the WebVTT file)
15721   * @return {HTMLTrackElement}
15722   * @method addRemoteTextTrack
15723   */
15724
15725  Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
15726    var track = _utilsMergeOptionsJs2['default'](options, {
15727      tech: this
15728    });
15729
15730    var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track);
15731
15732    // store HTMLTrackElement and TextTrack to remote list
15733    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
15734    this.remoteTextTracks().addTrack_(htmlTrackElement.track);
15735
15736    // must come after remoteTextTracks()
15737    this.textTracks().addTrack_(htmlTrackElement.track);
15738
15739    return htmlTrackElement;
15740  };
15741
15742  /**
15743   * Remove remote texttrack
15744   *
15745   * @param {TextTrackObject} track Texttrack to remove
15746   * @method removeRemoteTextTrack
15747   */
15748
15749  Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15750    this.textTracks().removeTrack_(track);
15751
15752    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
15753
15754    // remove HTMLTrackElement and TextTrack from remote list
15755    this.remoteTextTrackEls().removeTrackElement_(trackElement);
15756    this.remoteTextTracks().removeTrack_(track);
15757  };
15758
15759  /**
15760   * Provide a default setPoster method for techs
15761   * Poster support for techs should be optional, so we don't want techs to
15762   * break if they don't have a way to set a poster.
15763   *
15764   * @method setPoster
15765   */
15766
15767  Tech.prototype.setPoster = function setPoster() {};
15768
15769  /*
15770   * Check if the tech can support the given type
15771   *
15772   * The base tech does not support any type, but source handlers might
15773   * overwrite this.
15774   *
15775   * @param  {String} type    The mimetype to check
15776   * @return {String}         'probably', 'maybe', or '' (empty string)
15777   */
15778
15779  Tech.prototype.canPlayType = function canPlayType() {
15780    return '';
15781  };
15782
15783  /*
15784   * Return whether the argument is a Tech or not.
15785   * Can be passed either a Class like `Html5` or a instance like `player.tech_`
15786   *
15787   * @param {Object} component An item to check
15788   * @return {Boolean}         Whether it is a tech or not
15789   */
15790
15791  Tech.isTech = function isTech(component) {
15792    return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
15793  };
15794
15795  /**
15796   * Registers a Tech
15797   *
15798   * @param {String} name Name of the Tech to register
15799   * @param {Object} tech The tech to register
15800   * @static
15801   * @method registerComponent
15802   */
15803
15804  Tech.registerTech = function registerTech(name, tech) {
15805    if (!Tech.techs_) {
15806      Tech.techs_ = {};
15807    }
15808
15809    if (!Tech.isTech(tech)) {
15810      throw new Error('Tech ' + name + ' must be a Tech');
15811    }
15812
15813    Tech.techs_[name] = tech;
15814    return tech;
15815  };
15816
15817  /**
15818   * Gets a component by name
15819   *
15820   * @param {String} name Name of the component to get
15821   * @return {Component}
15822   * @static
15823   * @method getComponent
15824   */
15825
15826  Tech.getTech = function getTech(name) {
15827    if (Tech.techs_ && Tech.techs_[name]) {
15828      return Tech.techs_[name];
15829    }
15830
15831    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
15832      _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
15833      return _globalWindow2['default'].videojs[name];
15834    }
15835  };
15836
15837  return Tech;
15838})(_component2['default']);
15839
15840Tech.prototype.textTracks_;
15841
15842var createTrackHelper = function createTrackHelper(self, kind, label, language) {
15843  var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
15844
15845  var tracks = self.textTracks();
15846
15847  options.kind = kind;
15848
15849  if (label) {
15850    options.label = label;
15851  }
15852  if (language) {
15853    options.language = language;
15854  }
15855  options.tech = self;
15856
15857  var track = new _tracksTextTrack2['default'](options);
15858  tracks.addTrack_(track);
15859
15860  return track;
15861};
15862
15863Tech.prototype.featuresVolumeControl = true;
15864
15865// Resizing plugins using request fullscreen reloads the plugin
15866Tech.prototype.featuresFullscreenResize = false;
15867Tech.prototype.featuresPlaybackRate = false;
15868
15869// Optional events that we can manually mimic with timers
15870// currently not triggered by video-js-swf
15871Tech.prototype.featuresProgressEvents = false;
15872Tech.prototype.featuresTimeupdateEvents = false;
15873
15874Tech.prototype.featuresNativeTextTracks = false;
15875
15876/*
15877 * A functional mixin for techs that want to use the Source Handler pattern.
15878 *
15879 * ##### EXAMPLE:
15880 *
15881 *   Tech.withSourceHandlers.call(MyTech);
15882 *
15883 */
15884Tech.withSourceHandlers = function (_Tech) {
15885  /*
15886   * Register a source handler
15887   * Source handlers are scripts for handling specific formats.
15888   * The source handler pattern is used for adaptive formats (HLS, DASH) that
15889   * manually load video data and feed it into a Source Buffer (Media Source Extensions)
15890   * @param  {Function} handler  The source handler
15891   * @param  {Boolean}  first    Register it before any existing handlers
15892   */
15893  _Tech.registerSourceHandler = function (handler, index) {
15894    var handlers = _Tech.sourceHandlers;
15895
15896    if (!handlers) {
15897      handlers = _Tech.sourceHandlers = [];
15898    }
15899
15900    if (index === undefined) {
15901      // add to the end of the list
15902      index = handlers.length;
15903    }
15904
15905    handlers.splice(index, 0, handler);
15906  };
15907
15908  /*
15909   * Check if the tech can support the given type
15910   * @param  {String} type    The mimetype to check
15911   * @return {String}         'probably', 'maybe', or '' (empty string)
15912   */
15913  _Tech.canPlayType = function (type) {
15914    var handlers = _Tech.sourceHandlers || [];
15915    var can = undefined;
15916
15917    for (var i = 0; i < handlers.length; i++) {
15918      can = handlers[i].canPlayType(type);
15919
15920      if (can) {
15921        return can;
15922      }
15923    }
15924
15925    return '';
15926  };
15927
15928  /*
15929   * Return the first source handler that supports the source
15930   * TODO: Answer question: should 'probably' be prioritized over 'maybe'
15931   * @param  {Object} source The source object
15932   * @returns {Object}       The first source handler that supports the source
15933   * @returns {null}         Null if no source handler is found
15934   */
15935  _Tech.selectSourceHandler = function (source) {
15936    var handlers = _Tech.sourceHandlers || [];
15937    var can = undefined;
15938
15939    for (var i = 0; i < handlers.length; i++) {
15940      can = handlers[i].canHandleSource(source);
15941
15942      if (can) {
15943        return handlers[i];
15944      }
15945    }
15946
15947    return null;
15948  };
15949
15950  /*
15951   * Check if the tech can support the given source
15952   * @param  {Object} srcObj  The source object
15953   * @return {String}         'probably', 'maybe', or '' (empty string)
15954   */
15955  _Tech.canPlaySource = function (srcObj) {
15956    var sh = _Tech.selectSourceHandler(srcObj);
15957
15958    if (sh) {
15959      return sh.canHandleSource(srcObj);
15960    }
15961
15962    return '';
15963  };
15964
15965  /*
15966   * When using a source handler, prefer its implementation of
15967   * any function normally provided by the tech.
15968   */
15969  var deferrable = ['seekable', 'duration'];
15970
15971  deferrable.forEach(function (fnName) {
15972    var originalFn = this[fnName];
15973
15974    if (typeof originalFn !== 'function') {
15975      return;
15976    }
15977
15978    this[fnName] = function () {
15979      if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
15980        return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
15981      }
15982      return originalFn.apply(this, arguments);
15983    };
15984  }, _Tech.prototype);
15985
15986  /*
15987   * Create a function for setting the source using a source object
15988   * and source handlers.
15989   * Should never be called unless a source handler was found.
15990   * @param {Object} source  A source object with src and type keys
15991   * @return {Tech} self
15992   */
15993  _Tech.prototype.setSource = function (source) {
15994    var sh = _Tech.selectSourceHandler(source);
15995
15996    if (!sh) {
15997      // Fall back to a native source hander when unsupported sources are
15998      // deliberately set
15999      if (_Tech.nativeSourceHandler) {
16000        sh = _Tech.nativeSourceHandler;
16001      } else {
16002        _utilsLogJs2['default'].error('No source hander found for the current source.');
16003      }
16004    }
16005
16006    // Dispose any existing source handler
16007    this.disposeSourceHandler();
16008    this.off('dispose', this.disposeSourceHandler);
16009
16010    this.currentSource_ = source;
16011    this.sourceHandler_ = sh.handleSource(source, this);
16012    this.on('dispose', this.disposeSourceHandler);
16013
16014    return this;
16015  };
16016
16017  /*
16018   * Clean up any existing source handler
16019   */
16020  _Tech.prototype.disposeSourceHandler = function () {
16021    if (this.sourceHandler_ && this.sourceHandler_.dispose) {
16022      this.sourceHandler_.dispose();
16023    }
16024  };
16025};
16026
16027_component2['default'].registerComponent('Tech', Tech);
16028// Old name for Tech
16029_component2['default'].registerComponent('MediaTechController', Tech);
16030Tech.registerTech('Tech', Tech);
16031exports['default'] = Tech;
16032module.exports = exports['default'];
16033
16034},{"../component":66,"../media-error.js":102,"../tracks/html-track-element":120,"../tracks/html-track-element-list":119,"../tracks/text-track":127,"../tracks/text-track-list":125,"../utils/buffer.js":129,"../utils/fn.js":133,"../utils/log.js":136,"../utils/merge-options.js":137,"../utils/time-ranges.js":139,"global/document":1,"global/window":2}],119:[function(_dereq_,module,exports){
16035/**
16036 * @file html-track-element-list.js
16037 */
16038
16039'use strict';
16040
16041exports.__esModule = true;
16042
16043function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16044
16045function _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; } }
16046
16047function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16048
16049var _utilsBrowserJs = _dereq_('../utils/browser.js');
16050
16051var browser = _interopRequireWildcard(_utilsBrowserJs);
16052
16053var _globalDocument = _dereq_('global/document');
16054
16055var _globalDocument2 = _interopRequireDefault(_globalDocument);
16056
16057var HtmlTrackElementList = (function () {
16058  function HtmlTrackElementList() {
16059    var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
16060
16061    _classCallCheck(this, HtmlTrackElementList);
16062
16063    var list = this;
16064
16065    if (browser.IS_IE8) {
16066      list = _globalDocument2['default'].createElement('custom');
16067
16068      for (var prop in HtmlTrackElementList.prototype) {
16069        if (prop !== 'constructor') {
16070          list[prop] = HtmlTrackElementList.prototype[prop];
16071        }
16072      }
16073    }
16074
16075    list.trackElements_ = [];
16076
16077    Object.defineProperty(list, 'length', {
16078      get: function get() {
16079        return this.trackElements_.length;
16080      }
16081    });
16082
16083    for (var i = 0, _length = trackElements.length; i < _length; i++) {
16084      list.addTrackElement_(trackElements[i]);
16085    }
16086
16087    if (browser.IS_IE8) {
16088      return list;
16089    }
16090  }
16091
16092  HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
16093    this.trackElements_.push(trackElement);
16094  };
16095
16096  HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
16097    var trackElement_ = undefined;
16098
16099    for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) {
16100      if (track === this.trackElements_[i].track) {
16101        trackElement_ = this.trackElements_[i];
16102
16103        break;
16104      }
16105    }
16106
16107    return trackElement_;
16108  };
16109
16110  HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
16111    for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) {
16112      if (trackElement === this.trackElements_[i]) {
16113        this.trackElements_.splice(i, 1);
16114
16115        break;
16116      }
16117    }
16118  };
16119
16120  return HtmlTrackElementList;
16121})();
16122
16123exports['default'] = HtmlTrackElementList;
16124module.exports = exports['default'];
16125
16126},{"../utils/browser.js":128,"global/document":1}],120:[function(_dereq_,module,exports){
16127/**
16128 * @file html-track-element.js
16129 */
16130
16131'use strict';
16132
16133exports.__esModule = true;
16134
16135function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16136
16137function _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; } }
16138
16139function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16140
16141function _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
16141onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
16142
16143var _utilsBrowserJs = _dereq_('../utils/browser.js');
16144
16145var browser = _interopRequireWildcard(_utilsBrowserJs);
16146
16147var _globalDocument = _dereq_('global/document');
16148
16149var _globalDocument2 = _interopRequireDefault(_globalDocument);
16150
16151var _eventTarget = _dereq_('../event-target');
16152
16153var _eventTarget2 = _interopRequireDefault(_eventTarget);
16154
16155var _tracksTextTrack = _dereq_('../tracks/text-track');
16156
16157var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
16158
16159var NONE = 0;
16160var LOADING = 1;
16161var LOADED = 2;
16162var ERROR = 3;
16163
16164/**
16165 * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement
16166 *
16167 * interface HTMLTrackElement : HTMLElement {
16168 *   attribute DOMString kind;
16169 *   attribute DOMString src;
16170 *   attribute DOMString srclang;
16171 *   attribute DOMString label;
16172 *   attribute boolean default;
16173 *
16174 *   const unsigned short NONE = 0;
16175 *   const unsigned short LOADING = 1;
16176 *   const unsigned short LOADED = 2;
16177 *   const unsigned short ERROR = 3;
16178 *   readonly attribute unsigned short readyState;
16179 *
16180 *   readonly attribute TextTrack track;
16181 * };
16182 *
16183 * @param {Object} options TextTrack configuration
16184 * @class HTMLTrackElement
16185 */
16186
16187var HTMLTrackElement = (function (_EventTarget) {
16188  _inherits(HTMLTrackElement, _EventTarget);
16189
16190  function HTMLTrackElement() {
16191    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
16192
16193    _classCallCheck(this, HTMLTrackElement);
16194
16195    _EventTarget.call(this);
16196
16197    var readyState = undefined,
16198        trackElement = this;
16199
16200    if (browser.IS_IE8) {
16201      trackElement = _globalDocument2['default'].createElement('custom');
16202
16203      for (var prop in HTMLTrackElement.prototype) {
16204        if (prop !== 'constructor') {
16205          trackElement[prop] = HTMLTrackElement.prototype[prop];
16206        }
16207      }
16208    }
16209
16210    var track = new _tracksTextTrack2['default'](options);
16211
16212    trackElement.kind = track.kind;
16213    trackElement.src = track.src;
16214    trackElement.srclang = track.language;
16215    trackElement.label = track.label;
16216    trackElement['default'] = track['default'];
16217
16218    Object.defineProperty(trackElement, 'readyState', {
16219      get: function get() {
16220        return readyState;
16221      }
16222    });
16223
16224    Object.defineProperty(trackElement, 'track', {
16225      get: function get() {
16226        return track;
16227      }
16228    });
16229
16230    readyState = NONE;
16231
16232    track.addEventListener('loadeddata', function () {
16233      readyState = LOADED;
16234
16235      trackElement.trigger({
16236        type: 'load',
16237        target: trackElement
16238      });
16239    });
16240
16241    if (browser.IS_IE8) {
16242      return trackElement;
16243    }
16244  }
16245
16246  return HTMLTrackElement;
16247})(_eventTarget2['default']);
16248
16249HTMLTrackElement.prototype.allowedEvents_ = {
16250  load: 'load'
16251};
16252
16253HTMLTrackElement.NONE = NONE;
16254HTMLTrackElement.LOADING = LOADING;
16255HTMLTrackElement.LOADED = LOADED;
16256HTMLTrackElement.ERROR = ERROR;
16257
16258exports['default'] = HTMLTrackElement;
16259module.exports = exports['default'];
16260
16261},{"../event-target":98,"../tracks/text-track":127,"../utils/browser.js":128,"global/document":1}],121:[function(_dereq_,module,exports){
16262/**
16263 * @file text-track-cue-list.js
16264 */
16265'use strict';
16266
16267exports.__esModule = true;
16268
16269function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16270
16271function _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; } }
16272
16273var _utilsBrowserJs = _dereq_('../utils/browser.js');
16274
16275var browser = _interopRequireWildcard(_utilsBrowserJs);
16276
16277var _globalDocument = _dereq_('global/document');
16278
16279var _globalDocument2 = _interopRequireDefault(_globalDocument);
16280
16281/*
16282 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist
16283 *
16284 * interface TextTrackCueList {
16285 *   readonly attribute unsigned long length;
16286 *   getter TextTrackCue (unsigned long index);
16287 *   TextTrackCue? getCueById(DOMString id);
16288 * };
16289 */
16290
16291var TextTrackCueList = function TextTrackCueList(cues) {
16292  var list = this;
16293
16294  if (browser.IS_IE8) {
16295    list = _globalDocument2['default'].createElement('custom');
16296
16297    for (var prop in TextTrackCueList.prototype) {
16298      if (prop !== 'constructor') {
16299        list[prop] = TextTrackCueList.prototype[prop];
16300      }
16301    }
16302  }
16303
16304  TextTrackCueList.prototype.setCues_.call(list, cues);
16305
16306  Object.defineProperty(list, 'length', {
16307    get: function get() {
16308      return this.length_;
16309    }
16310  });
16311
16312  if (browser.IS_IE8) {
16313    return list;
16314  }
16315};
16316
16317TextTrackCueList.prototype.setCues_ = function (cues) {
16318  var oldLength = this.length || 0;
16319  var i = 0;
16320  var l = cues.length;
16321
16322  this.cues_ = cues;
16323  this.length_ = cues.length;
16324
16325  var defineProp = function defineProp(i) {
16326    if (!('' + i in this)) {
16327      Object.defineProperty(this, '' + i, {
16328        get: function get() {
16329          return this.cues_[i];
16330        }
16331      });
16332    }
16333  };
16334
16335  if (oldLength < l) {
16336    i = oldLength;
16337
16338    for (; i < l; i++) {
16339      defineProp.call(this, i);
16340    }
16341  }
16342};
16343
16344TextTrackCueList.prototype.getCueById = function (id) {
16345  var result = null;
16346  for (var i = 0, l = this.length; i < l; i++) {
16347    var cue = this[i];
16348    if (cue.id === id) {
16349      result = cue;
16350      break;
16351    }
16352  }
16353
16354  return result;
16355};
16356
16357exports['default'] = TextTrackCueList;
16358module.exports = exports['default'];
16359
16360},{"../utils/browser.js":128,"global/document":1}],122:[function(_dereq_,module,exports){
16361/**
16362 * @file text-track-display.js
16363 */
16364'use strict';
16365
16366exports.__esModule = true;
16367
16368function _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; } }
16369
16370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16371
16372function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16373
16374function _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
16374onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
16375
16376var _component = _dereq_('../component');
16377
16378var _component2 = _interopRequireDefault(_component);
16379
16380var _menuMenuJs = _dereq_('../menu/menu.js');
16381
16382var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
16383
16384var _menuMenuItemJs = _dereq_('../menu/menu-item.js');
16385
16386var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
16387
16388var _menuMenuButtonJs = _dereq_('../menu/menu-button.js');
16389
16390var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
16391
16392var _utilsFnJs = _dereq_('../utils/fn.js');
16393
16394var Fn = _interopRequireWildcard(_utilsFnJs);
16395
16396var _globalDocument = _dereq_('global/document');
16397
16398var _globalDocument2 = _interopRequireDefault(_globalDocument);
16399
16400var _globalWindow = _dereq_('global/window');
16401
16402var _globalWindow2 = _interopRequireDefault(_globalWindow);
16403
16404var darkGray = '#222';
16405var lightGray = '#ccc';
16406var fontMap = {
16407  monospace: 'monospace',
16408  sansSerif: 'sans-serif',
16409  serif: 'serif',
16410  monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
16411  monospaceSerif: '"Courier New", monospace',
16412  proportionalSansSerif: 'sans-serif',
16413  proportionalSerif: 'serif',
16414  casual: '"Comic Sans MS", Impact, fantasy',
16415  script: '"Monotype Corsiva", cursive',
16416  smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
16417};
16418
16419/**
16420 * The component for displaying text track cues
16421 *
16422 * @param {Object} player  Main Player
16423 * @param {Object=} options Object of option names and values
16424 * @param {Function=} ready    Ready callback function
16425 * @extends Component
16426 * @class TextTrackDisplay
16427 */
16428
16429var TextTrackDisplay = (function (_Component) {
16430  _inherits(TextTrackDisplay, _Component);
16431
16432  function TextTrackDisplay(player, options, ready) {
16433    _classCallCheck(this, TextTrackDisplay);
16434
16435    _Component.call(this, player, options, ready);
16436
16437    player.on('loadstart', Fn.bind(this, this.toggleDisplay));
16438    player.on('texttrackchange', Fn.bind(this, this.updateDisplay));
16439
16440    // This used to be called during player init, but was causing an error
16441    // if a track should show by default and the display hadn't loaded yet.
16442    // Should probably be moved to an external track loader when we support
16443    // tracks that don't need a display.
16444    player.ready(Fn.bind(this, function () {
16445      if (player.tech_ && player.tech_['featuresNativeTextTracks']) {
16446        this.hide();
16447        return;
16448      }
16449
16450      player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
16451
16452      var tracks = this.options_.playerOptions['tracks'] || [];
16453      for (var i = 0; i < tracks.length; i++) {
16454        var track = tracks[i];
16455        this.player_.addRemoteTextTrack(track);
16456      }
16457    }));
16458  }
16459
16460  /**
16461  * Add cue HTML to display
16462  *
16463  * @param {Number} color Hex number for color, like #f0e
16464  * @param {Number} opacity Value for opacity,0.0 - 1.0
16465  * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
16466  * @method constructColor
16467  */
16468
16469  /**
16470   * Toggle display texttracks
16471   *
16472   * @method toggleDisplay
16473   */
16474
16475  TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
16476    if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) {
16477      this.hide();
16478    } else {
16479      this.show();
16480    }
16481  };
16482
16483  /**
16484   * Create the component's DOM element
16485   *
16486   * @return {Element}
16487   * @method createEl
16488   */
16489
16490  TextTrackDisplay.prototype.createEl = function createEl() {
16491    return _Component.prototype.createEl.call(this, 'div', {
16492      className: 'vjs-text-track-display'
16493    });
16494  };
16495
16496  /**
16497   * Clear display texttracks
16498   *
16499   * @method clearDisplay
16500   */
16501
16502  TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
16503    if (typeof _globalWindow2['default']['WebVTT'] === 'function') {
16504      _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_);
16505    }
16506  };
16507
16508  /**
16509   * Update display texttracks
16510   *
16511   * @method updateDisplay
16512   */
16513
16514  TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
16515    var tracks = this.player_.textTracks();
16516
16517    this.clearDisplay();
16518
16519    if (!tracks) {
16520      return;
16521    }
16522
16523    for (var i = 0; i < tracks.length; i++) {
16524      var track = tracks[i];
16525      if (track['mode'] === 'showing') {
16526        this.updateForTrack(track);
16527      }
16528    }
16529  };
16530
16531  /**
16532   * Add texttrack to texttrack list
16533   *
16534   * @param {TextTrackObject} track Texttrack object to be added to list
16535   * @method updateForTrack
16536   */
16537
16538  TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
16539    if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) {
16540      return;
16541    }
16542
16543    var overrides = this.player_['textTrackSettings'].getValues();
16544
16545    var cues = [];
16546    for (var _i = 0; _i < track['activeCues'].length; _i++) {
16547      cues.push(track['activeCues'][_i]);
16548    }
16549
16550    _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], track['activeCues'], this.el_);
16551
16552    var i = cues.length;
16553    while (i--) {
16554      var cue = cues[i];
16555      if (!cue) {
16556        continue;
16557      }
16558
16559      var cueDiv = cue.displayState;
16560      if (overrides.color) {
16561        cueDiv.firstChild.style.color = overrides.color;
16562      }
16563      if (overrides.textOpacity) {
16564        tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
16565      }
16566      if (overrides.backgroundColor) {
16567        cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
16568      }
16569      if (overrides.backgroundOpacity) {
16570        tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
16571      }
16572      if (overrides.windowColor) {
16573        if (overrides.windowOpacity) {
16574          tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
16575        } else {
16576          cueDiv.style.backgroundColor = overrides.windowColor;
16577        }
16578      }
16579      if (overrides.edgeStyle) {
16580        if (overrides.edgeStyle === 'dropshadow') {
16581          cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
16582        } else if (overrides.edgeStyle === 'raised') {
16583          cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
16584        } else if (overrides.edgeStyle === 'depressed') {
16585          cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
16586        } else if (overrides.edgeStyle === 'uniform') {
16587          cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
16588        }
16589      }
16590      if (overrides.fontPercent && overrides.fontPercent !== 1) {
16591        var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize);
16592        cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
16593        cueDiv.style.height = 'auto';
16594        cueDiv.style.top = 'auto';
16595        cueDiv.style.bottom = '2px';
16596      }
16597      if (overrides.fontFamily && overrides.fontFamily !== 'default') {
16598        if (overrides.fontFamily === 'small-caps') {
16599          cueDiv.firstChild.style.fontVariant = 'small-caps';
16600        } else {
16601          cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
16602        }
16603      }
16604    }
16605  };
16606
16607  return TextTrackDisplay;
16608})(_component2['default']);
16609
16610function constructColor(color, opacity) {
16611  return 'rgba(' +
16612  // color looks like "#f0e"
16613  parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
16614}
16615
16616/**
16617 * Try to update style
16618 * Some style changes will throw an error, particularly in IE8. Those should be noops.
16619 *
16620 * @param {Element} el The element to be styles
16621 * @param {CSSProperty} style The CSS property to be styled
16622 * @param {CSSStyle} rule The actual style to be applied to the property
16623 * @method tryUpdateStyle
16624 */
16625function tryUpdateStyle(el, style, rule) {
16626  //
16627  try {
16628    el.style[style] = rule;
16629  } catch (e) {}
16630}
16631
16632_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
16633exports['default'] = TextTrackDisplay;
16634module.exports = exports['default'];
16635
16636},{"../component":66,"../menu/menu-button.js":103,"../menu/menu-item.js":104,"../menu/menu.js":105,"../utils/fn.js":133,"global/document":1,"global/window":2}],123:[function(_dereq_,module,exports){
16637/**
16638 * @file text-track-enums.js
16639 *
16640 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
16641 *
16642 * enum TextTrackMode { "disabled",  "hidden",  "showing" };
16643 */
16644'use strict';
16645
16646exports.__esModule = true;
16647var TextTrackMode = {
16648  'disabled': 'disabled',
16649  'hidden': 'hidden',
16650  'showing': 'showing'
16651};
16652
16653/*
16654 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind
16655 *
16656 * enum TextTrackKind { "subtitles",  "captions",  "descriptions",  "chapters",  "metadata" };
16657 */
16658var TextTrackKind = {
16659  'subtitles': 'subtitles',
16660  'captions': 'captions',
16661  'descriptions': 'descriptions',
16662  'chapters': 'chapters',
16663  'metadata': 'metadata'
16664};
16665
16666exports.TextTrackMode = TextTrackMode;
16667exports.TextTrackKind = TextTrackKind;
16668
16669},{}],124:[function(_dereq_,module,exports){
16670/**
16671 * Utilities for capturing text track state and re-creating tracks
16672 * based on a capture.
16673 *
16674 * @file text-track-list-converter.js
16675 */
16676
16677/**
16678 * Examine a single text track and return a JSON-compatible javascript
16679 * object that represents the text track's state.
16680 * @param track {TextTrackObject} the text track to query
16681 * @return {Object} a serializable javascript representation of the
16682 * @private
16683 */
16684'use strict';
16685
16686exports.__esModule = true;
16687var trackToJson_ = function trackToJson_(track) {
16688  var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
16689    if (track[prop]) {
16690      acc[prop] = track[prop];
16691    }
16692
16693    return acc;
16694  }, {
16695    cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
16696      return {
16697        startTime: cue.startTime,
16698        endTime: cue.endTime,
16699        text: cue.text,
16700        id: cue.id
16701      };
16702    })
16703  });
16704
16705  return ret;
16706};
16707
16708/**
16709 * Examine a tech and return a JSON-compatible javascript array that
16710 * represents the state of all text tracks currently configured. The
16711 * return array is compatible with `jsonToTextTracks`.
16712 * @param tech {tech} the tech object to query
16713 * @return {Array} a serializable javascript representation of the
16714 * @function textTracksToJson
16715 */
16716var textTracksToJson = function textTracksToJson(tech) {
16717
16718  var trackEls = tech.$$('track');
16719
16720  var trackObjs = Array.prototype.map.call(trackEls, function (t) {
16721    return t.track;
16722  });
16723  var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
16724    var json = trackToJson_(trackEl.track);
16725    if (trackEl.src) {
16726      json.src = trackEl.src;
16727    }
16728    return json;
16729  });
16730
16731  return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
16732    return trackObjs.indexOf(track) === -1;
16733  }).map(trackToJson_));
16734};
16735
16736/**
16737 * Creates a set of remote text tracks on a tech based on an array of
16738 * javascript text track representations.
16739 * @param json {Array} an array of text track representation objects,
16740 * like those that would be produced by `textTracksToJson`
16741 * @param tech {tech} the tech to create text tracks on
16742 * @function jsonToTextTracks
16743 */
16744var jsonToTextTracks = function jsonToTextTracks(json, tech) {
16745  json.forEach(function (track) {
16746    var addedTrack = tech.addRemoteTextTrack(track).track;
16747    if (!track.src && track.cues) {
16748      track.cues.forEach(function (cue) {
16749        return addedTrack.addCue(cue);
16750      });
16751    }
16752  });
16753
16754  return tech.textTracks();
16755};
16756
16757exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
16758module.exports = exports['default'];
16759
16760},{}],125:[function(_dereq_,module,exports){
16761/**
16762 * @file text-track-list.js
16763 */
16764'use strict';
16765
16766exports.__esModule = true;
16767
16768function _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; } }
16769
16770function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16771
16772var _eventTarget = _dereq_('../event-target');
16773
16774var _eventTarget2 = _interopRequireDefault(_eventTarget);
16775
16776var _utilsFnJs = _dereq_('../utils/fn.js');
16777
16778var Fn = _interopRequireWildcard(_utilsFnJs);
16779
16780var _utilsBrowserJs = _dereq_('../utils/browser.js');
16781
16782var browser = _interopRequireWildcard(_utilsBrowserJs);
16783
16784var _globalDocument = _dereq_('global/document');
16785
16786var _globalDocument2 = _interopRequireDefault(_globalDocument);
16787
16788/*
16789 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist
16790 *
16791 * interface TextTrackList : EventTarget {
16792 *   readonly attribute unsigned long length;
16793 *   getter TextTrack (unsigned long index);
16794 *   TextTrack? getTrackById(DOMString id);
16795 *
16796 *   attribute EventHandler onchange;
16797 *   attribute EventHandler onaddtrack;
16798 *   attribute EventHandler onremovetrack;
16799 * };
16800 */
16801var TextTrackList = function TextTrackList(tracks) {
16802  var list = this;
16803
16804  if (browser.IS_IE8) {
16805    list = _globalDocument2['default'].createElement('custom');
16806
16807    for (var prop in TextTrackList.prototype) {
16808      if (prop !== 'constructor') {
16809        list[prop] = TextTrackList.prototype[prop];
16810      }
16811    }
16812  }
16813
16814  tracks = tracks || [];
16815  list.tracks_ = [];
16816
16817  Object.defineProperty(list, 'length', {
16818    get: function get() {
16819      return this.tracks_.length;
16820    }
16821  });
16822
16823  for (var i = 0; i < tracks.length; i++) {
16824    list.addTrack_(tracks[i]);
16825  }
16826
16827  if (browser.IS_IE8) {
16828    return list;
16829  }
16830};
16831
16832TextTrackList.prototype = Object.create(_eventTarget2['default'].prototype);
16833TextTrackList.prototype.constructor = TextTrackList;
16834
16835/*
16836 * change - One or more tracks in the track list have been enabled or disabled.
16837 * addtrack - A track has been added to the track list.
16838 * removetrack - A track has been removed from the track list.
16839 */
16840TextTrackList.prototype.allowedEvents_ = {
16841  'change': 'change',
16842  'addtrack': 'addtrack',
16843  'removetrack': 'removetrack'
16844};
16845
16846// emulate attribute EventHandler support to allow for feature detection
16847for (var _event in TextTrackList.prototype.allowedEvents_) {
16848  TextTrackList.prototype['on' + _event] = null;
16849}
16850
16851/**
16852 * Add TextTrack from TextTrackList
16853 *
16854 * @param {TextTrack} track
16855 * @method addTrack_
16856 * @private
16857 */
16858TextTrackList.prototype.addTrack_ = function (track) {
16859  var index = this.tracks_.length;
16860  if (!('' + index in this)) {
16861    Object.defineProperty(this, index, {
16862      get: function get() {
16863        return this.tracks_[index];
16864      }
16865    });
16866  }
16867
16868  track.addEventListener('modechange', Fn.bind(this, function () {
16869    this.trigger('change');
16870  }));
16871  this.tracks_.push(track);
16872
16873  this.trigger({
16874    type: 'addtrack',
16875    track: track
16876  });
16877};
16878
16879/**
16880 * Remove TextTrack from TextTrackList
16881 * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
16882 *
16883 * @param {TextTrack} rtrack
16884 * @method removeTrack_
16885 * @private
16886 */
16887TextTrackList.prototype.removeTrack_ = function (rtrack) {
16888  var track = undefined;
16889
16890  for (var i = 0, l = this.length; i < l; i++) {
16891    if (this[i] === rtrack) {
16892      track = this[i];
16893      if (track.off) {
16894        track.off();
16895      }
16896
16897      this.tracks_.splice(i, 1);
16898
16899      break;
16900    }
16901  }
16902
16903  if (!track) {
16904    return;
16905  }
16906
16907  this.trigger({
16908    type: 'removetrack',
16909    track: track
16910  });
16911};
16912
16913TextTrackList.prototype.getTrackById = function (id) {
16914  var result = null;
16915
16916  for (var i = 0, l = this.length; i < l; i++) {
16917    var track = this[i];
16918    if (track.id === id) {
16919      result = track;
16920      break;
16921    }
16922  }
16923
16924  return result;
16925};
16926
16927exports['default'] = TextTrackList;
16928module.exports = exports['default'];
16929
16930},{"../event-target":98,"../utils/browser.js":128,"../utils/fn.js":133,"global/document":1}],126:[function(_dereq_,module,exports){
16931/**
16932 * @file text-track-settings.js
16933 */
16934'use strict';
16935
16936exports.__esModule = true;
16937
16938function _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; } }
16939
16940function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16941
16942function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
16943
16944function _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
16944onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
16945
16946var _component = _dereq_('../component');
16947
16948var _component2 = _interopRequireDefault(_component);
16949
16950var _utilsEventsJs = _dereq_('../utils/events.js');
16951
16952var Events = _interopRequireWildcard(_utilsEventsJs);
16953
16954var _utilsFnJs = _dereq_('../utils/fn.js');
16955
16956var Fn = _interopRequireWildcard(_utilsFnJs);
16957
16958var _utilsLogJs = _dereq_('../utils/log.js');
16959
16960var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
16961
16962var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
16963
16964var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
16965
16966var _globalWindow = _dereq_('global/window');
16967
16968var _globalWindow2 = _interopRequireDefault(_globalWindow);
16969
16970/**
16971 * Manipulate settings of texttracks
16972 *
16973 * @param {Object} player  Main Player
16974 * @param {Object=} options Object of option names and values
16975 * @extends Component
16976 * @class TextTrackSettings
16977 */
16978
16979var TextTrackSettings = (function (_Component) {
16980  _inherits(TextTrackSettings, _Component);
16981
16982  function TextTrackSettings(player, options) {
16983    _classCallCheck(this, TextTrackSettings);
16984
16985    _Component.call(this, player, options);
16986    this.hide();
16987
16988    // Grab `persistTextTrackSettings` from the player options if not passed in child options
16989    if (options.persistTextTrackSettings === undefined) {
16990      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
16991    }
16992
16993    Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () {
16994      this.saveSettings();
16995      this.hide();
16996    }));
16997
16998    Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () {
16999      this.$('.vjs-fg-color > select').selectedIndex = 0;
17000      this.$('.vjs-bg-color > select').selectedIndex = 0;
17001      this.$('.window-color > select').selectedIndex = 0;
17002      this.$('.vjs-text-opacity > select').selectedIndex = 0;
17003      this.$('.vjs-bg-opacity > select').selectedIndex = 0;
17004      this.$('.vjs-window-opacity > select').selectedIndex = 0;
17005      this.$('.vjs-edge-style select').selectedIndex = 0;
17006      this.$('.vjs-font-family select').selectedIndex = 0;
17007      this.$('.vjs-font-percent select').selectedIndex = 2;
17008      this.updateDisplay();
17009    }));
17010
17011    Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
17012    Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
17013    Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
17014    Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
17015    Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
17016    Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
17017    Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
17018    Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
17019    Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
17020
17021    if (this.options_.persistTextTrackSettings) {
17022      this.restoreSettings();
17023    }
17024  }
17025
17026  /**
17027   * Create the component's DOM element
17028   *
17029   * @return {Element}
17030   * @method createEl
17031   */
17032
17033  TextTrackSettings.prototype.createEl = function createEl() {
17034    return _Component.prototype.createEl.call(this, 'div', {
17035      className: 'vjs-caption-settings vjs-modal-overlay',
17036      innerHTML: captionOptionsMenuTemplate()
17037    });
17038  };
17039
17040  /**
17041   * Get texttrack settings
17042   * Settings are
17043   * .vjs-edge-style
17044   * .vjs-font-family
17045   * .vjs-fg-color
17046   * .vjs-text-opacity
17047   * .vjs-bg-color
17048   * .vjs-bg-opacity
17049   * .window-color
17050   * .vjs-window-opacity
17051   *
17052   * @return {Object}
17053   * @method getValues
17054   */
17055
17056  TextTrackSettings.prototype.getValues = function getValues() {
17057    var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
17058    var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
17059    var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
17060    var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
17061    var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
17062    var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
17063    var windowColor = getSelectedOptionValue(this.$('.window-color > select'));
17064    var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
17065    var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));
17066
17067    var result = {
17068      'backgroundOpacity': bgOpacity,
17069      'textOpacity': textOpacity,
17070      'windowOpacity': windowOpacity,
17071      'edgeStyle': textEdge,
17072      'fontFamily': fontFamily,
17073      'color': fgColor,
17074      'backgroundColor': bgColor,
17075      'windowColor': windowColor,
17076      'fontPercent': fontPercent
17077    };
17078    for (var _name in result) {
17079      if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) {
17080        delete result[_name];
17081      }
17082    }
17083    return result;
17084  };
17085
17086  /**
17087   * Set texttrack settings
17088   * Settings are
17089   * .vjs-edge-style
17090   * .vjs-font-family
17091   * .vjs-fg-color
17092   * .vjs-text-opacity
17093   * .vjs-bg-color
17094   * .vjs-bg-opacity
17095   * .window-color
17096   * .vjs-window-opacity
17097   *
17098   * @param {Object} values Object with texttrack setting values
17099   * @method setValues
17100   */
17101
17102  TextTrackSettings.prototype.setValues = function setValues(values) {
17103    setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
17104    setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
17105    setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
17106    setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
17107    setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
17108    setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
17109    setSelectedOption(this.$('.window-color > select'), values.windowColor);
17110    setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);
17111
17112    var fontPercent = values.fontPercent;
17113
17114    if (fontPercent) {
17115      fontPercent = fontPercent.toFixed(2);
17116    }
17117
17118    setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
17119  };
17120
17121  /**
17122   * Restore texttrack settings
17123   *
17124   * @method restoreSettings
17125   */
17126
17127  TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
17128    var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings'));
17129
17130    var err = _safeParseTuple[0];
17131    var values = _safeParseTuple[1];
17132
17133    if (err) {
17134      _utilsLogJs2['default'].error(err);
17135    }
17136
17137    if (values) {
17138      this.setValues(values);
17139    }
17140  };
17141
17142  /**
17143   * Save texttrack settings to local storage
17144   *
17145   * @method saveSettings
17146   */
17147
17148  TextTrackSettings.prototype.saveSettings = function saveSettings() {
17149    if (!this.options_.persistTextTrackSettings) {
17150      return;
17151    }
17152
17153    var values = this.getValues();
17154    try {
17155      if (Object.getOwnPropertyNames(values).length > 0) {
17156        _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
17157      } else {
17158        _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings');
17159      }
17160    } catch (e) {}
17161  };
17162
17163  /**
17164   * Update display of texttrack settings
17165   *
17166   * @method updateDisplay
17167   */
17168
17169  TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
17170    var ttDisplay = this.player_.getChild('textTrackDisplay');
17171    if (ttDisplay) {
17172      ttDisplay.updateDisplay();
17173    }
17174  };
17175
17176  return TextTrackSettings;
17177})(_component2['default']);
17178
17179_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
17180
17181function getSelectedOptionValue(target) {
17182  var selectedOption = undefined;
17183  // not all browsers support selectedOptions, so, fallback to options
17184  if (target.selectedOptions) {
17185    selectedOption = target.selectedOptions[0];
17186  } else if (target.options) {
17187    selectedOption = target.options[target.options.selectedIndex];
17188  }
17189
17190  return selectedOption.value;
17191}
17192
17193function setSelectedOption(target, value) {
17194  if (!value) {
17195    return;
17196  }
17197
17198  var i = undefined;
17199  for (i = 0; i < target.options.length; i++) {
17200    var option = target.options[i];
17201    if (option.value === value) {
17202      break;
17203    }
17204  }
17205
17206  target.selectedIndex = i;
17207}
17208
17209function captionOptionsMenuTemplate() {
17210  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>
17210\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>';
17211
17212  return template;
17213}
17214
17215exports['default'] = TextTrackSettings;
17216module.exports = exports['default'];
17217
17218},{"../component":66,"../utils/events.js":132,"../utils/fn.js":133,"../utils/log.js":136,"global/window":2,"safe-json-parse/tuple":53}],127:[function(_dereq_,module,exports){
17219/**
17220 * @file text-track.js
17221 */
17222'use strict';
17223
17224exports.__esModule = true;
17225
17226function _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; } }
17227
17228function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17229
17230var _textTrackCueList = _dereq_('./text-track-cue-list');
17231
17232var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
17233
17234var _utilsFnJs = _dereq_('../utils/fn.js');
17235
17236var Fn = _interopRequireWildcard(_utilsFnJs);
17237
17238var _utilsGuidJs = _dereq_('../utils/guid.js');
17239
17240var Guid = _interopRequireWildcard(_utilsGuidJs);
17241
17242var _utilsBrowserJs = _dereq_('../utils/browser.js');
17243
17244var browser = _interopRequireWildcard(_utilsBrowserJs);
17245
17246var _textTrackEnums = _dereq_('./text-track-enums');
17247
17248var TextTrackEnum = _interopRequireWildcard(_textTrackEnums);
17249
17250var _utilsLogJs = _dereq_('../utils/log.js');
17251
17252var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
17253
17254var _eventTarget = _dereq_('../event-target');
17255
17256var _eventTarget2 = _interopRequireDefault(_eventTarget);
17257
17258var _globalDocument = _dereq_('global/document');
17259
17260var _globalDocument2 = _interopRequireDefault(_globalDocument);
17261
17262var _globalWindow = _dereq_('global/window');
17263
17264var _globalWindow2 = _interopRequireDefault(_globalWindow);
17265
17266var _utilsUrlJs = _dereq_('../utils/url.js');
17267
17268var _xhr = _dereq_('xhr');
17269
17270var _xhr2 = _interopRequireDefault(_xhr);
17271
17272/*
17273 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
17274 *
17275 * interface TextTrack : EventTarget {
17276 *   readonly attribute TextTrackKind kind;
17277 *   readonly attribute DOMString label;
17278 *   readonly attribute DOMString language;
17279 *
17280 *   readonly attribute DOMString id;
17281 *   readonly attribute DOMString inBandMetadataTrackDispatchType;
17282 *
17283 *   attribute TextTrackMode mode;
17284 *
17285 *   readonly attribute TextTrackCueList? cues;
17286 *   readonly attribute TextTrackCueList? activeCues;
17287 *
17288 *   void addCue(TextTrackCue cue);
17289 *   void removeCue(TextTrackCue cue);
17290 *
17291 *   attribute EventHandler oncuechange;
17292 * };
17293 */
17294var TextTrack = function TextTrack() {
17295  var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
17296
17297  if (!options.tech) {
17298    throw new Error('A tech was not provided.');
17299  }
17300
17301  var tt = this;
17302  if (browser.IS_IE8) {
17303    tt = _globalDocument2['default'].createElement('custom');
17304
17305    for (var prop in TextTrack.prototype) {
17306      if (prop !== 'constructor') {
17307        tt[prop] = TextTrack.prototype[prop];
17308      }
17309    }
17310  }
17311
17312  tt.tech_ = options.tech;
17313
17314  var mode = TextTrackEnum.TextTrackMode[options['mode']] || 'disabled';
17315  var kind = TextTrackEnum.TextTrackKind[options['kind']] || 'subtitles';
17316  var label = options['label'] || '';
17317  var language = options['language'] || options['srclang'] || '';
17318  var id = options['id'] || 'vjs_text_track_' + Guid.newGUID();
17319
17320  if (kind === 'metadata' || kind === 'chapters') {
17321    mode = 'hidden';
17322  }
17323
17324  tt.cues_ = [];
17325  tt.activeCues_ = [];
17326
17327  var cues = new _textTrackCueList2['default'](tt.cues_);
17328  var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
17329
17330  var changed = false;
17331  var timeupdateHandler = Fn.bind(tt, function () {
17332    this['activeCues'];
17333    if (changed) {
17334      this['trigger']('cuechange');
17335      changed = false;
17336    }
17337  });
17338  if (mode !== 'disabled') {
17339    tt.tech_.on('timeupdate', timeupdateHandler);
17340  }
17341
17342  Object.defineProperty(tt, 'kind', {
17343    get: function get() {
17344      return kind;
17345    },
17346    set: Function.prototype
17347  });
17348
17349  Object.defineProperty(tt, 'label', {
17350    get: function get() {
17351      return label;
17352    },
17353    set: Function.prototype
17354  });
17355
17356  Object.defineProperty(tt, 'language', {
17357    get: function get() {
17358      return language;
17359    },
17360    set: Function.prototype
17361  });
17362
17363  Object.defineProperty(tt, 'id', {
17364    get: function get() {
17365      return id;
17366    },
17367    set: Function.prototype
17368  });
17369
17370  Object.defineProperty(tt, 'mode', {
17371    get: function get() {
17372      return mode;
17373    },
17374    set: function set(newMode) {
17375      if (!TextTrackEnum.TextTrackMode[newMode]) {
17376        return;
17377      }
17378      mode = newMode;
17379      if (mode === 'showing') {
17380        this.tech_.on('timeupdate', timeupdateHandler);
17381      }
17382      this.trigger('modechange');
17383    }
17384  });
17385
17386  Object.defineProperty(tt, 'cues', {
17387    get: function get() {
17388      if (!this.loaded_) {
17389        return null;
17390      }
17391
17392      return cues;
17393    },
17394    set: Function.prototype
17395  });
17396
17397  Object.defineProperty(tt, 'activeCues', {
17398    get: function get() {
17399      if (!this.loaded_) {
17400        return null;
17401      }
17402
17403      if (this['cues'].length === 0) {
17404        return activeCues; // nothing to do
17405      }
17406
17407      var ct = this.tech_.currentTime();
17408      var active = [];
17409
17410      for (var i = 0, l = this['cues'].length; i < l; i++) {
17411        var cue = this['cues'][i];
17412        if (cue['startTime'] <= ct && cue['endTime'] >= ct) {
17413          active.push(cue);
17414        } else if (cue['startTime'] === cue['endTime'] && cue['startTime'] <= ct && cue['startTime'] + 0.5 >= ct) {
17415          active.push(cue);
17416        }
17417      }
17418
17419      changed = false;
17420
17421      if (active.length !== this.activeCues_.length) {
17422        changed = true;
17423      } else {
17424        for (var i = 0; i < active.length; i++) {
17425          if (indexOf.call(this.activeCues_, active[i]) === -1) {
17426            changed = true;
17427          }
17428        }
17429      }
17430
17431      this.activeCues_ = active;
17432      activeCues.setCues_(this.activeCues_);
17433
17434      return activeCues;
17435    },
17436    set: Function.prototype
17437  });
17438
17439  if (options.src) {
17440    tt.src = options.src;
17441    loadTrack(options.src, tt);
17442  } else {
17443    tt.loaded_ = true;
17444  }
17445
17446  if (browser.IS_IE8) {
17447    return tt;
17448  }
17449};
17450
17451TextTrack.prototype = Object.create(_eventTarget2['default'].prototype);
17452TextTrack.prototype.constructor = TextTrack;
17453
17454/*
17455 * cuechange - One or more cues in the track have become active or stopped being active.
17456 */
17457TextTrack.prototype.allowedEvents_ = {
17458  'cuechange': 'cuechange'
17459};
17460
17461TextTrack.prototype.addCue = function (cue) {
17462  var tracks = this.tech_.textTracks();
17463
17464  if (tracks) {
17465    for (var i = 0; i < tracks.length; i++) {
17466      if (tracks[i] !== this) {
17467        tracks[i].removeCue(cue);
17468      }
17469    }
17470  }
17471
17472  this.cues_.push(cue);
17473  this['cues'].setCues_(this.cues_);
17474};
17475
17476TextTrack.prototype.removeCue = function (removeCue) {
17477  var removed = false;
17478
17479  for (var i = 0, l = this.cues_.length; i < l; i++) {
17480    var cue = this.cues_[i];
17481    if (cue === removeCue) {
17482      this.cues_.splice(i, 1);
17483      removed = true;
17484    }
17485  }
17486
17487  if (removed) {
17488    this.cues.setCues_(this.cues_);
17489  }
17490};
17491
17492/*
17493* Downloading stuff happens below this point
17494*/
17495var parseCues = function parseCues(srcContent, track) {
17496  var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder());
17497
17498  parser.oncue = function (cue) {
17499    track.addCue(cue);
17500  };
17501
17502  parser.onparsingerror = function (error) {
17503    _utilsLogJs2['default'].error(error);
17504  };
17505
17506  parser.onflush = function () {
17507    track.trigger({
17508      type: 'loadeddata',
17509      target: track
17510    });
17511  };
17512
17513  parser.parse(srcContent);
17514  parser.flush();
17515};
17516
17517var loadTrack = function loadTrack(src, track) {
17518  var opts = {
17519    uri: src
17520  };
17521
17522  var crossOrigin = _utilsUrlJs.isCrossOrigin(src);
17523  if (crossOrigin) {
17524    opts.cors = crossOrigin;
17525  }
17526
17527  _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) {
17528    if (err) {
17529      return _utilsLogJs2['default'].error(err, response);
17530    }
17531
17532    track.loaded_ = true;
17533
17534    // NOTE: this is only used for the alt/video.novtt.js build
17535    if (typeof _globalWindow2['default'].WebVTT !== 'function') {
17536      _globalWindow2['default'].setTimeout(function () {
17537        parseCues(responseBody, track);
17538      }, 100);
17539    } else {
17540      parseCues(responseBody, track);
17541    }
17542  }));
17543};
17544
17545var indexOf = function indexOf(searchElement, fromIndex) {
17546  if (this == null) {
17547    throw new TypeError('"this" is null or not defined');
17548  }
17549
17550  var O = Object(this);
17551
17552  var len = O.length >>> 0;
17553
17554  if (len === 0) {
17555    return -1;
17556  }
17557
17558  var n = +fromIndex || 0;
17559
17560  if (Math.abs(n) === Infinity) {
17561    n = 0;
17562  }
17563
17564  if (n >= len) {
17565    return -1;
17566  }
17567
17568  var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
17569
17570  while (k < len) {
17571    if (k in O && O[k] === searchElement) {
17572      return k;
17573    }
17574    k++;
17575  }
17576  return -1;
17577};
17578
17579exports['default'] = TextTrack;
17580module.exports = exports['default'];
17581
17582},{"../event-target":98,"../utils/browser.js":128,"../utils/fn.js":133,"../utils/guid.js":135,"../utils/log.js":136,"../utils/url.js":141,"./text-track-cue-list":121,"./text-track-enums":123,"global/document":1,"global/window":2,"xhr":55}],128:[function(_dereq_,module,exports){
17583/**
17584 * @file browser.js
17585 */
17586'use strict';
17587
17588exports.__esModule = true;
17589
17590function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17591
17592var _globalDocument = _dereq_('global/document');
17593
17594var _globalDocument2 = _interopRequireDefault(_globalDocument);
17595
17596var _globalWindow = _dereq_('global/window');
17597
17598var _globalWindow2 = _interopRequireDefault(_globalWindow);
17599
17600var USER_AGENT = _globalWindow2['default'].navigator.userAgent;
17601var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
17602var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
17603
17604/*
17605 * Device is an iPhone
17606 *
17607 * @type {Boolean}
17608 * @constant
17609 * @private
17610 */
17611var IS_IPAD = /iPad/i.test(USER_AGENT);
17612
17613exports.IS_IPAD = IS_IPAD;
17614// The Facebook app's UIWebView identifies as both an iPhone and iPad, so
17615// to identify iPhones, we need to exclude iPads.
17616// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
17617var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
17618exports.IS_IPHONE = IS_IPHONE;
17619var IS_IPOD = /iPod/i.test(USER_AGENT);
17620exports.IS_IPOD = IS_IPOD;
17621var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
17622
17623exports.IS_IOS = IS_IOS;
17624var IOS_VERSION = (function () {
17625  var match = USER_AGENT.match(/OS (\d+)_/i);
17626  if (match && match[1]) {
17627    return match[1];
17628  }
17629})();
17630
17631exports.IOS_VERSION = IOS_VERSION;
17632var IS_ANDROID = /Android/i.test(USER_AGENT);
17633exports.IS_ANDROID = IS_ANDROID;
17634var ANDROID_VERSION = (function () {
17635  // This matches Android Major.Minor.Patch versions
17636  // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
17637  var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
17638      major,
17639      minor;
17640
17641  if (!match) {
17642    return null;
17643  }
17644
17645  major = match[1] && parseFloat(match[1]);
17646  minor = match[2] && parseFloat(match[2]);
17647
17648  if (major && minor) {
17649    return parseFloat(match[1] + '.' + match[2]);
17650  } else if (major) {
17651    return major;
17652  } else {
17653    return null;
17654  }
17655})();
17656exports.ANDROID_VERSION = ANDROID_VERSION;
17657// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
17658var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
17659exports.IS_OLD_ANDROID = IS_OLD_ANDROID;
17660var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
17661
17662exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID;
17663var IS_FIREFOX = /Firefox/i.test(USER_AGENT);
17664exports.IS_FIREFOX = IS_FIREFOX;
17665var IS_CHROME = /Chrome/i.test(USER_AGENT);
17666exports.IS_CHROME = IS_CHROME;
17667var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
17668
17669exports.IS_IE8 = IS_IE8;
17670var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch);
17671exports.TOUCH_ENABLED = TOUCH_ENABLED;
17672var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style);
17673exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED;
17674
17675},{"global/document":1,"global/window":2}],129:[function(_dereq_,module,exports){
17676/**
17677 * @file buffer.js
17678 */
17679'use strict';
17680
17681exports.__esModule = true;
17682exports.bufferedPercent = bufferedPercent;
17683
17684var _timeRangesJs = _dereq_('./time-ranges.js');
17685
17686/**
17687 * Compute how much your video has been buffered
17688 *
17689 * @param  {Object} Buffered object
17690 * @param  {Number} Total duration
17691 * @return {Number} Percent buffered of the total duration
17692 * @private
17693 * @function bufferedPercent
17694 */
17695
17696function bufferedPercent(buffered, duration) {
17697  var bufferedDuration = 0,
17698      start,
17699      end;
17700
17701  if (!duration) {
17702    return 0;
17703  }
17704
17705  if (!buffered || !buffered.length) {
17706    buffered = _timeRangesJs.createTimeRange(0, 0);
17707  }
17708
17709  for (var i = 0; i < buffered.length; i++) {
17710    start = buffered.start(i);
17711    end = buffered.end(i);
17712
17713    // buffered end can be bigger than duration by a very small fraction
17714    if (end > duration) {
17715      end = duration;
17716    }
17717
17718    bufferedDuration += end - start;
17719  }
17720
17721  return bufferedDuration / duration;
17722}
17723
17724},{"./time-ranges.js":139}],130:[function(_dereq_,module,exports){
17725'use strict';
17726
17727exports.__esModule = true;
17728
17729function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17730
17731var _logJs = _dereq_('./log.js');
17732
17733var _logJs2 = _interopRequireDefault(_logJs);
17734
17735/**
17736 * Object containing the default behaviors for available handler methods.
17737 *
17738 * @private
17739 * @type {Object}
17740 */
17741var defaultBehaviors = {
17742  get: function get(obj, key) {
17743    return obj[key];
17744  },
17745  set: function set(obj, key, value) {
17746    obj[key] = value;
17747    return true;
17748  }
17749};
17750
17751/**
17752 * Expose private objects publicly using a Proxy to log deprecation warnings.
17753 *
17754 * Browsers that do not support Proxy objects will simply return the `target`
17755 * object, so it can be directly exposed.
17756 *
17757 * @param {Object} target The target object.
17758 * @param {Object} messages Messages to display from a Proxy. Only operations
17759 *                          with an associated message will be proxied.
17760 * @param {String} [messages.get]
17761 * @param {String} [messages.set]
17762 * @return {Object} A Proxy if supported or the `target` argument.
17763 */
17764
17765exports['default'] = function (target) {
17766  var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
17767
17768  if (typeof Proxy === 'function') {
17769    var _ret = (function () {
17770      var handler = {};
17771
17772      // Build a handler object based on those keys that have both messages
17773      // and default behaviors.
17774      Object.keys(messages).forEach(function (key) {
17775        if (defaultBehaviors.hasOwnProperty(key)) {
17776          handler[key] = function () {
17777            _logJs2['default'].warn(messages[key]);
17778            return defaultBehaviors[key].apply(this, arguments);
17779          };
17780        }
17781      });
17782
17783      return {
17784        v: new Proxy(target, handler)
17785      };
17786    })();
17787
17788    if (typeof _ret === 'object') return _ret.v;
17789  }
17790  return target;
17791};
17792
17793module.exports = exports['default'];
17794
17795},{"./log.js":136}],131:[function(_dereq_,module,exports){
17796/**
17797 * @file dom.js
17798 */
17799'use strict';
17800
17801exports.__esModule = true;
17802exports.getEl = getEl;
17803exports.createEl = createEl;
17804exports.textContent = textContent;
17805exports.insertElFirst = insertElFirst;
17806exports.getElData = getElData;
17807exports.hasElData = hasElData;
17808exports.removeElData = removeElData;
17809exports.hasElClass = hasElClass;
17810exports.addElClass = addElClass;
17811exports.removeElClass = removeElClass;
17812exports.toggleElClass = toggleElClass;
17813exports.setElAttributes = setElAttributes;
17814exports.getElAttributes = getElAttributes;
17815exports.blockTextSelection = blockTextSelection;
17816exports.unblockTextSelection = unblockTextSelection;
17817exports.findElPosition = findElPosition;
17818exports.getPointerPosition = getPointerPosition;
17819exports.isEl = isEl;
17820exports.isTextNode = isTextNode;
17821exports.emptyEl = emptyEl;
17822exports.normalizeContent = normalizeContent;
17823exports.appendContent = appendContent;
17824exports.insertContent = insertContent;
17825
17826var _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 ', '.']);
17827
17828function _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; } }
17829
17830function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17831
17832function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
17833
17834var _globalDocument = _dereq_('global/document');
17835
17836var _globalDocument2 = _interopRequireDefault(_globalDocument);
17837
17838var _globalWindow = _dereq_('global/window');
17839
17840var _globalWindow2 = _interopRequireDefault(_globalWindow);
17841
17842var _guidJs = _dereq_('./guid.js');
17843
17844var Guid = _interopRequireWildcard(_guidJs);
17845
17846var _logJs = _dereq_('./log.js');
17847
17848var _logJs2 = _interopRequireDefault(_logJs);
17849
17850var _tsml = _dereq_('tsml');
17851
17852var _tsml2 = _interopRequireDefault(_tsml);
17853
17854/**
17855 * Detect if a value is a string with any non-whitespace characters.
17856 *
17857 * @param  {String} str
17858 * @return {Boolean}
17859 */
17860function isNonBlankString(str) {
17861  return typeof str === 'string' && /\S/.test(str);
17862}
17863
17864/**
17865 * Throws an error if the passed string has whitespace. This is used by
17866 * class methods to be relatively consistent with the classList API.
17867 *
17868 * @param  {String} str
17869 * @return {Boolean}
17870 */
17871function throwIfWhitespace(str) {
17872  if (/\s/.test(str)) {
17873    throw new Error('class has illegal whitespace characters');
17874  }
17875}
17876
17877/**
17878 * Produce a regular expression for matching a class name.
17879 *
17880 * @param  {String} className
17881 * @return {RegExp}
17882 */
17883function classRegExp(className) {
17884  return new RegExp('(^|\\s)' + className + '($|\\s)');
17885}
17886
17887/**
17888 * Creates functions to query the DOM using a given method.
17889 *
17890 * @function createQuerier
17891 * @private
17892 * @param  {String} method
17893 * @return {Function}
17894 */
17895function createQuerier(method) {
17896  return function (selector, context) {
17897    if (!isNonBlankString(selector)) {
17898      return _globalDocument2['default'][method](null);
17899    }
17900    if (isNonBlankString(context)) {
17901      context = _globalDocument2['default'].querySelector(context);
17902    }
17903    return (isEl(context) ? context : _globalDocument2['default'])[method](selector);
17904  };
17905}
17906
17907/**
17908 * Shorthand for document.getElementById()
17909 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
17910 *
17911 * @param  {String} id  Element ID
17912 * @return {Element}    Element with supplied ID
17913 * @function getEl
17914 */
17915
17916function getEl(id) {
17917  if (id.indexOf('#') === 0) {
17918    id = id.slice(1);
17919  }
17920
17921  return _globalDocument2['default'].getElementById(id);
17922}
17923
17924/**
17925 * Creates an element and applies properties.
17926 *
17927 * @param  {String} [tagName='div'] Name of tag to be created.
17928 * @param  {Object} [properties={}] Element properties to be applied.
17929 * @param  {Object} [attributes={}] Element attributes to be applied.
17930 * @return {Element}
17931 * @function createEl
17932 */
17933
17934function createEl() {
17935  var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
17936  var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
17937  var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
17938
17939  var el = _globalDocument2['default'].createElement(tagName);
17940
vendor: 4,103 bytes, lines 17941-18125
17941  Object.getOwnPropertyNames(properties).forEach(function (propName) {
17942    var val = properties[propName];
17943
17944    // See #2176
17945    // We originally were accepting both properties and attributes in the
17946    // same object, but that doesn't work so well.
17947    if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
17948      _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val));
17949      el.setAttribute(propName, val);
17950    } else {
17951      el[propName] = val;
17952    }
17953  });
17954
17955  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
17956    var val = attributes[attrName];
17957    el.setAttribute(attrName, attributes[attrName]);
17958  });
17959
17960  return el;
17961}
17962
17963/**
17964 * Injects text into an element, replacing any existing contents entirely.
17965 *
17966 * @param  {Element} el
17967 * @param  {String} text
17968 * @return {Element}
17969 * @function textContent
17970 */
17971
17972function textContent(el, text) {
17973  if (typeof el.textContent === 'undefined') {
17974    el.innerText = text;
17975  } else {
17976    el.textContent = text;
17977  }
17978}
17979
17980/**
17981 * Insert an element as the first child node of another
17982 *
17983 * @param  {Element} child   Element to insert
17984 * @param  {Element} parent Element to insert child into
17985 * @private
17986 * @function insertElFirst
17987 */
17988
17989function insertElFirst(child, parent) {
17990  if (parent.firstChild) {
17991    parent.insertBefore(child, parent.firstChild);
17992  } else {
17993    parent.appendChild(child);
17994  }
17995}
17996
17997/**
17998 * Element Data Store. Allows for binding data to an element without putting it directly on the element.
17999 * Ex. Event listeners are stored here.
18000 * (also from jsninja.com, slightly modified and updated for closure compiler)
18001 *
18002 * @type {Object}
18003 * @private
18004 */
18005var elData = {};
18006
18007/*
18008 * Unique attribute name to store an element's guid in
18009 *
18010 * @type {String}
18011 * @constant
18012 * @private
18013 */
18014var elIdAttr = 'vdata' + new Date().getTime();
18015
18016/**
18017 * Returns the cache object where data for an element is stored
18018 *
18019 * @param  {Element} el Element to store data for.
18020 * @return {Object}
18021 * @function getElData
18022 */
18023
18024function getElData(el) {
18025  var id = el[elIdAttr];
18026
18027  if (!id) {
18028    id = el[elIdAttr] = Guid.newGUID();
18029  }
18030
18031  if (!elData[id]) {
18032    elData[id] = {};
18033  }
18034
18035  return elData[id];
18036}
18037
18038/**
18039 * Returns whether or not an element has cached data
18040 *
18041 * @param  {Element} el A dom element
18042 * @return {Boolean}
18043 * @private
18044 * @function hasElData
18045 */
18046
18047function hasElData(el) {
18048  var id = el[elIdAttr];
18049
18050  if (!id) {
18051    return false;
18052  }
18053
18054  return !!Object.getOwnPropertyNames(elData[id]).length;
18055}
18056
18057/**
18058 * Delete data for the element from the cache and the guid attr from getElementById
18059 *
18060 * @param  {Element} el Remove data for an element
18061 * @private
18062 * @function removeElData
18063 */
18064
18065function removeElData(el) {
18066  var id = el[elIdAttr];
18067
18068  if (!id) {
18069    return;
18070  }
18071
18072  // Remove all stored data
18073  delete elData[id];
18074
18075  // Remove the elIdAttr property from the DOM node
18076  try {
18077    delete el[elIdAttr];
18078  } catch (e) {
18079    if (el.removeAttribute) {
18080      el.removeAttribute(elIdAttr);
18081    } else {
18082      // IE doesn't appear to support removeAttribute on the document element
18083      el[elIdAttr] = null;
18084    }
18085  }
18086}
18087
18088/**
18089 * Check if an element has a CSS class
18090 *
18091 * @function hasElClass
18092 * @param {Element} element Element to check
18093 * @param {String} classToCheck Classname to check
18094 */
18095
18096function hasElClass(element, classToCheck) {
18097  if (element.classList) {
18098    return element.classList.contains(classToCheck);
18099  } else {
18100    throwIfWhitespace(classToCheck);
18101    return classRegExp(classToCheck).test(element.className);
18102  }
18103}
18104
18105/**
18106 * Add a CSS class name to an element
18107 *
18108 * @function addElClass
18109 * @param {Element} element    Element to add class name to
18110 * @param {String} classToAdd Classname to add
18111 */
18112
18113function addElClass(element, classToAdd) {
18114  if (element.classList) {
18115    element.classList.add(classToAdd);
18116
18117    // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
18118    // in the case of classList not being supported.
18119  } else if (!hasElClass(element, classToAdd)) {
18120      element.className = (element.className + ' ' + classToAdd).trim();
18121    }
18122
18123  return element;
18124}
18125
18126/**
18127 * Remove a CSS class name from an element
18128 *
18129 * @function removeElClass
18130 * @param {Element} element    Element to remove from class name
18131 * @param {String} classToRemove Classname to remove
18132 */
18133
18134function removeElClass(element, classToRemove) {
18135  if (element.classList) {
18136    element.classList.remove(classToRemove);
18137  } else {
18138    throwIfWhitespace(classToRemove);
18139    element.className = element.className.split(/\s+/).filter(function (c) {
18140      return c !== classToRemove;
18141    }).join(' ');
18142  }
18143
18144  return element;
18145}
18146
18147/**
18148 * Adds or removes a CSS class name on an element depending on an optional
18149 * condition or the presence/absence of the class name.
18150 *
18151 * @function toggleElClass
18152 * @param    {Element} element
18153 * @param    {String} classToToggle
18154 * @param    {Boolean|Function} [predicate]
18155 *           Can be a function that returns a Boolean. If `true`, the class
18156 *           will be added; if `false`, the class will be removed. If not
18157 *           given, the class will be added if not present and vice versa.
18158 */
18159
18160function toggleElClass(element, classToToggle, predicate) {
18161
18162  // This CANNOT use `classList` internally because IE does not support the
18163  // second parameter to the `classList.toggle()` method! Which is fine because
18164  // `classList` will be used by the add/remove functions.
18165  var has = hasElClass(element, classToToggle);
18166
18167  if (typeof predicate === 'function') {
18168    predicate = predicate(element, classToToggle);
18169  }
18170
18171  if (typeof predicate !== 'boolean') {
18172    predicate = !has;
18173  }
18174
18175  // If the necessary class operation matches the current state of the
18176  // element, no action is required.
18177  if (predicate === has) {
18178    return;
18179  }
18180
18181  if (predicate) {
18182    addElClass(element, classToToggle);
18183  } else {
18184    removeElClass(element, classToToggle);
18185  }
18186
18187  return element;
18188}
18189
18190/**
18191 * Apply attributes to an HTML element.
18192 *
18193 * @param  {Element} el         Target element.
18194 * @param  {Object=} attributes Element attributes to be applied.
18195 * @private
18196 * @function setElAttributes
18197 */
18198
18199function setElAttributes(el, attributes) {
18200  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
18201    var attrValue = attributes[attrName];
18202
18203    if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
18204      el.removeAttribute(attrName);
18205    } else {
18206      el.setAttribute(attrName, attrValue === true ? '' : attrValue);
18207    }
18208  });
18209}
18210
18211/**
18212 * Get an element's attribute values, as defined on the HTML tag
18213 * Attributes are not the same as properties. They're defined on the tag
18214 * or with setAttribute (which shouldn't be used with HTML)
18215 * This will return true or false for boolean attributes.
18216 *
18217 * @param  {Element} tag Element from which to get tag attributes
18218 * @return {Object}
18219 * @private
18220 * @function getElAttributes
18221 */
18222
18223function getElAttributes(tag) {
18224  var obj, knownBooleans, attrs, attrName, attrVal;
18225
18226  obj = {};
18227
18228  // known boolean attributes
18229  // we can check for matching boolean properties, but older browsers
18230  // won't know about HTML5 boolean attributes that we still read from
18231  knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
18232
18233  if (tag && tag.attributes && tag.attributes.length > 0) {
18234    attrs = tag.attributes;
18235
18236    for (var i = attrs.length - 1; i >= 0; i--) {
18237      attrName = attrs[i].name;
18238      attrVal = attrs[i].value;
18239
18240      // check for known booleans
18241      // the matching element property will return a value for typeof
18242      if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
18243        // the value of an included boolean attribute is typically an empty
18244        // string ('') which would equal false if we just check for a false value.
18245        // we also don't want support bad code like autoplay='false'
18246        attrVal = attrVal !== null ? true : false;
18247      }
18248
18249      obj[attrName] = attrVal;
18250    }
18251  }
18252
18253  return obj;
18254}
18255
18256/**
18257 * Attempt to block the ability to select text while dragging controls
18258 *
18259 * @return {Boolean}
18260 * @function blockTextSelection
18261 */
18262
18263function blockTextSelection() {
18264  _globalDocument2['default'].body.focus();
18265  _globalDocument2['default'].onselectstart = function () {
18266    return false;
18267  };
18268}
18269
18270/**
18271 * Turn off text selection blocking
18272 *
18273 * @return {Boolean}
18274 * @function unblockTextSelection
18275 */
18276
18277function unblockTextSelection() {
18278  _globalDocument2['default'].onselectstart = function () {
18279    return true;
18280  };
18281}
18282
18283/**
18284 * Offset Left
18285 * getBoundingClientRect technique from
18286 * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
18287 *
18288 * @function findElPosition
18289 * @param {Element} el Element from which to get offset
18290 * @return {Object}
18291 */
18292
18293function findElPosition(el) {
18294  var box = undefined;
18295
18296  if (el.getBoundingClientRect && el.parentNode) {
18297    box = el.getBoundingClientRect();
18298  }
18299
18300  if (!box) {
18301    return {
18302      left: 0,
18303      top: 0
18304    };
18305  }
18306
18307  var docEl = _globalDocument2['default'].documentElement;
18308  var body = _globalDocument2['default'].body;
18309
18310  var clientLeft = docEl.clientLeft || body.clientLeft || 0;
18311  var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft;
18312  var left = box.left + scrollLeft - clientLeft;
18313
18314  var clientTop = docEl.clientTop || body.clientTop || 0;
18315  var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop;
18316  var top = box.top + scrollTop - clientTop;
18317
18318  // Android sometimes returns slightly off decimal values, so need to round
18319  return {
18320    left: Math.round(left),
18321    top: Math.round(top)
18322  };
18323}
18324
18325/**
18326 * Get pointer position in element
18327 * Returns an object with x and y coordinates.
18328 * The base on the coordinates are the bottom left of the element.
18329 *
18330 * @function getPointerPosition
18331 * @param {Element} el Element on which to get the pointer position on
18332 * @param {Event} event Event object
18333 * @return {Object} This object will have x and y coordinates corresponding to the mouse position
18334 */
18335
18336function getPointerPosition(el, event) {
18337  var position = {};
18338  var box = findElPosition(el);
18339  var boxW = el.offsetWidth;
18340  var boxH = el.offsetHeight;
18341
18342  var boxY = box.top;
18343  var boxX = box.left;
18344  var pageY = event.pageY;
18345  var pageX = event.pageX;
18346
18347  if (event.changedTouches) {
18348    pageX = event.changedTouches[0].pageX;
18349    pageY = event.changedTouches[0].pageY;
18350  }
18351
18352  position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
18353  position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
18354
18355  return position;
18356}
18357
18358/**
18359 * Determines, via duck typing, whether or not a value is a DOM element.
18360 *
18361 * @function isEl
18362 * @param    {Mixed} value
18363 * @return   {Boolean}
18364 */
18365
18366function isEl(value) {
18367  return !!value && typeof value === 'object' && value.nodeType === 1;
18368}
18369
18370/**
18371 * Determines, via duck typing, whether or not a value is a text node.
18372 *
18373 * @param  {Mixed} value
18374 * @return {Boolean}
18375 */
18376
18377function isTextNode(value) {
18378  return !!value && typeof value === 'object' && value.nodeType === 3;
18379}
18380
18381/**
18382 * Empties the contents of an element.
18383 *
18384 * @function emptyEl
18385 * @param    {Element} el
18386 * @return   {Element}
18387 */
18388
18389function emptyEl(el) {
18390  while (el.firstChild) {
18391    el.removeChild(el.firstChild);
18392  }
18393  return el;
18394}
18395
18396/**
18397 * Normalizes content for eventual insertion into the DOM.
18398 *
18399 * This allows a wide range of content definition methods, but protects
18400 * from falling into the trap of simply writing to `innerHTML`, which is
18401 * an XSS concern.
18402 *
18403 * The content for an element can be passed in multiple types and
18404 * combinations, whose behavior is as follows:
18405 *
18406 * - String
18407 *   Normalized into a text node.
18408 *
18409 * - Element, TextNode
18410 *   Passed through.
18411 *
18412 * - Array
18413 *   A one-dimensional array of strings, elements, nodes, or functions (which
18414 *   return single strings, elements, or nodes).
18415 *
18416 * - Function
18417 *   If the sole argument, is expected to produce a string, element,
18418 *   node, or array.
18419 *
18420 * @function normalizeContent
18421 * @param    {String|Element|TextNode|Array|Function} content
18422 * @return   {Array}
18423 */
18424
18425function normalizeContent(content) {
18426
18427  // First, invoke content if it is a function. If it produces an array,
18428  // that needs to happen before normalization.
18429  if (typeof content === 'function') {
18430    content = content();
18431  }
18432
18433  // Next up, normalize to an array, so one or many items can be normalized,
18434  // filtered, and returned.
18435  return (Array.isArray(content) ? content : [content]).map(function (value) {
18436
18437    // First, invoke value if it is a function to produce a new value,
18438    // which will be subsequently normalized to a Node of some kind.
18439    if (typeof value === 'function') {
18440      value = value();
18441    }
18442
18443    if (isEl(value) || isTextNode(value)) {
18444      return value;
18445    }
18446
18447    if (typeof value === 'string' && /\S/.test(value)) {
18448      return _globalDocument2['default'].createTextNode(value);
18449    }
18450  }).filter(function (value) {
18451    return value;
18452  });
18453}
18454
18455/**
18456 * Normalizes and appends content to an element.
18457 *
18458 * @function appendContent
18459 * @param    {Element} el
18460 * @param    {String|Element|TextNode|Array|Function} content
18461 *           See: `normalizeContent`
18462 * @return   {Element}
18463 */
18464
18465function appendContent(el, content) {
18466  normalizeContent(content).forEach(function (node) {
18467    return el.appendChild(node);
18468  });
18469  return el;
18470}
18471
18472/**
18473 * Normalizes and inserts content into an element; this is identical to
18474 * `appendContent()`, except it empties the element first.
18475 *
18476 * @function insertContent
18477 * @param    {Element} el
18478 * @param    {String|Element|TextNode|Array|Function} content
18479 *           See: `normalizeContent`
18480 * @return   {Element}
18481 */
18482
18483function insertContent(el, content) {
18484  return appendContent(emptyEl(el), content);
18485}
18486
18487/**
18488 * Finds a single DOM element matching `selector` within the optional
18489 * `context` of another DOM element (defaulting to `document`).
18490 *
18491 * @function $
18492 * @param    {String} selector
18493 *           A valid CSS selector, which will be passed to `querySelector`.
18494 *
18495 * @param    {Element|String} [context=document]
18496 *           A DOM element within which to query. Can also be a selector
18497 *           string in which case the first matching element will be used
18498 *           as context. If missing (or no element matches selector), falls
18499 *           back to `document`.
18500 *
18501 * @return   {Element|null}
18502 */
18503var $ = createQuerier('querySelector');
18504
18505exports.$ = $;
18506/**
18507 * Finds a all DOM elements matching `selector` within the optional
18508 * `context` of another DOM element (defaulting to `document`).
18509 *
18510 * @function $$
18511 * @param    {String} selector
18512 *           A valid CSS selector, which will be passed to `querySelectorAll`.
18513 *
18514 * @param    {Element|String} [context=document]
18515 *           A DOM element within which to query. Can also be a selector
18516 *           string in which case the first matching element will be used
18517 *           as context. If missing (or no element matches selector), falls
18518 *           back to `document`.
18519 *
18520 * @return   {NodeList}
18521 */
18522var $$ = createQuerier('querySelectorAll');
18523exports.$$ = $$;
18524
18525},{"./guid.js":135,"./log.js":136,"global/document":1,"global/window":2,"tsml":54}],132:[function(_dereq_,module,exports){
18526/**
18527 * @file events.js
18528 *
18529 * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
18530 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
18531 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
18532 * robust as jquery's, so there's probably some differences.
18533 */
18534
18535'use strict';
18536
18537exports.__esModule = true;
18538exports.on = on;
18539exports.off = off;
18540exports.trigger = trigger;
18541exports.one = one;
18542exports.fixEvent = fixEvent;
18543
18544function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18545
18546function _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; } }
18547
18548var _domJs = _dereq_('./dom.js');
18549
18550var Dom = _interopRequireWildcard(_domJs);
18551
18552var _guidJs = _dereq_('./guid.js');
18553
18554var Guid = _interopRequireWildcard(_guidJs);
18555
18556var _globalWindow = _dereq_('global/window');
18557
18558var _globalWindow2 = _interopRequireDefault(_globalWindow);
18559
18560var _globalDocument = _dereq_('global/document');
18561
18562var _globalDocument2 = _interopRequireDefault(_globalDocument);
18563
18564/**
18565 * Add an event listener to element
18566 * It stores the handler function in a separate cache object
18567 * and adds a generic handler to the element's event,
18568 * along with a unique id (guid) to the element.
18569 *
18570 * @param  {Element|Object}   elem Element or object to bind listeners to
18571 * @param  {String|Array}   type Type of event to bind to.
18572 * @param  {Function} fn   Event listener.
18573 * @method on
18574 */
18575
18576function on(elem, type, fn) {
18577  if (Array.isArray(type)) {
18578    return _handleMultipleEvents(on, elem, type, fn);
18579  }
18580
18581  var data = Dom.getElData(elem);
18582
18583  // We need a place to store all our handler data
18584  if (!data.handlers) data.handlers = {};
18585
18586  if (!data.handlers[type]) data.handlers[type] = [];
18587
18588  if (!fn.guid) fn.guid = Guid.newGUID();
18589
18590  data.handlers[type].push(fn);
18591
18592  if (!data.dispatcher) {
18593    data.disabled = false;
18594
18595    data.dispatcher = function (event, hash) {
18596
18597      if (data.disabled) return;
18598      event = fixEvent(event);
18599
18600      var handlers = data.handlers[event.type];
18601
18602      if (handlers) {
18603        // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
18604        var handlersCopy = handlers.slice(0);
18605
18606        for (var m = 0, n = handlersCopy.length; m < n; m++) {
18607          if (event.isImmediatePropagationStopped()) {
18608            break;
18609          } else {
18610            handlersCopy[m].call(elem, event, hash);
18611          }
18612        }
18613      }
18614    };
18615  }
18616
18617  if (data.handlers[type].length === 1) {
18618    if (elem.addEventListener) {
18619      elem.addEventListener(type, data.dispatcher, false);
18620    } else if (elem.attachEvent) {
18621      elem.attachEvent('on' + type, data.dispatcher);
18622    }
18623  }
18624}
18625
18626/**
18627 * Removes event listeners from an element
18628 *
18629 * @param  {Element|Object}   elem Object to remove listeners from
18630 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
18631 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
18632 * @method off
18633 */
18634
18635function off(elem, type, fn) {
18636  // Don't want to add a cache object through getElData if not needed
18637  if (!Dom.hasElData(elem)) return;
18638
18639  var data = Dom.getElData(elem);
18640
18641  // If no events exist, nothing to unbind
18642  if (!data.handlers) {
18643    return;
18644  }
18645
18646  if (Array.isArray(type)) {
18647    return _handleMultipleEvents(off, elem, type, fn);
18648  }
18649
18650  // Utility function
18651  var removeType = function removeType(t) {
18652    data.handlers[t] = [];
18653    _cleanUpEvents(elem, t);
18654  };
18655
18656  // Are we removing all bound events?
18657  if (!type) {
18658    for (var t in data.handlers) {
18659      removeType(t);
18660    }return;
18661  }
18662
18663  var handlers = data.handlers[type];
18664
18665  // If no handlers exist, nothing to unbind
18666  if (!handlers) return;
18667
18668  // If no listener was provided, remove all listeners for type
18669  if (!fn) {
18670    removeType(type);
18671    return;
18672  }
18673
18674  // We're only removing a single handler
18675  if (fn.guid) {
18676    for (var n = 0; n < handlers.length; n++) {
18677      if (handlers[n].guid === fn.guid) {
18678        handlers.splice(n--, 1);
18679      }
18680    }
18681  }
18682
18683  _cleanUpEvents(elem, type);
18684}
18685
18686/**
18687 * Trigger an event for an element
18688 *
18689 * @param  {Element|Object}      elem  Element to trigger an event on
18690 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
18691 * @param  {Object} [hash] data hash to pass along with the event
18692 * @return {Boolean=} Returned only if default was prevented
18693 * @method trigger
18694 */
18695
18696function trigger(elem, event, hash) {
18697  // Fetches element data and a reference to the parent (for bubbling).
18698  // Don't want to add a data object to cache for every parent,
18699  // so checking hasElData first.
18700  var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
18701  var parent = elem.parentNode || elem.ownerDocument;
18702  // type = event.type || event,
18703  // handler;
18704
18705  // If an event name was passed as a string, creates an event out of it
18706  if (typeof event === 'string') {
18707    event = { type: event, target: elem };
18708  }
18709  // Normalizes the event properties.
18710  event = fixEvent(event);
18711
18712  // If the passed element has a dispatcher, executes the established handlers.
18713  if (elemData.dispatcher) {
18714    elemData.dispatcher.call(elem, event, hash);
18715  }
18716
18717  // Unless explicitly stopped or the event does not bubble (e.g. media events)
18718  // recursively calls this function to bubble the event up the DOM.
18719  if (parent && !event.isPropagationStopped() && event.bubbles === true) {
18720    trigger.call(null, parent, event, hash);
18721
18722    // If at the top of the DOM, triggers the default action unless disabled.
18723  } else if (!parent && !event.defaultPrevented) {
18724      var targetData = Dom.getElData(event.target);
18725
18726      // Checks if the target has a default action for this event.
18727      if (event.target[event.type]) {
18728        // Temporarily disables event dispatching on the target as we have already executed the handler.
18729        targetData.disabled = true;
18730        // Executes the default action.
18731        if (typeof event.target[event.type] === 'function') {
18732          event.target[event.type]();
18733        }
18734        // Re-enables event dispatching.
18735        targetData.disabled = false;
vendor: 4,549 bytes, lines 18736-18877
18736      }
18737    }
18738
18739  // Inform the triggerer if the default was prevented by returning false
18740  return !event.defaultPrevented;
18741}
18742
18743/**
18744 * Trigger a listener only once for an event
18745 *
18746 * @param  {Element|Object}   elem Element or object to
18747 * @param  {String|Array}   type Name/type of event
18748 * @param  {Function} fn Event handler function
18749 * @method one
18750 */
18751
18752function one(elem, type, fn) {
18753  if (Array.isArray(type)) {
18754    return _handleMultipleEvents(one, elem, type, fn);
18755  }
18756  var func = function func() {
18757    off(elem, type, func);
18758    fn.apply(this, arguments);
18759  };
18760  // copy the guid to the new function so it can removed using the original function's ID
18761  func.guid = fn.guid = fn.guid || Guid.newGUID();
18762  on(elem, type, func);
18763}
18764
18765/**
18766 * Fix a native event to have standard property values
18767 *
18768 * @param  {Object} event Event object to fix
18769 * @return {Object}
18770 * @private
18771 * @method fixEvent
18772 */
18773
18774function fixEvent(event) {
18775
18776  function returnTrue() {
18777    return true;
18778  }
18779  function returnFalse() {
18780    return false;
18781  }
18782
18783  // Test if fixing up is needed
18784  // Used to check if !event.stopPropagation instead of isPropagationStopped
18785  // But native events return true for stopPropagation, but don't have
18786  // other expected methods like isPropagationStopped. Seems to be a problem
18787  // with the Javascript Ninja code. So we're just overriding all events now.
18788  if (!event || !event.isPropagationStopped) {
18789    var old = event || _globalWindow2['default'].event;
18790
18791    event = {};
18792    // Clone the old object so that we can modify the values event = {};
18793    // IE8 Doesn't like when you mess with native event properties
18794    // Firefox returns false for event.hasOwnProperty('type') and other props
18795    //  which makes copying more difficult.
18796    // TODO: Probably best to create a whitelist of event props
18797    for (var key in old) {
18798      // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
18799      // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
18800      // and webkitMovementX/Y
18801      if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
18802        // Chrome 32+ warns if you try to copy deprecated returnValue, but
18803        // we still want to if preventDefault isn't supported (IE8).
18804        if (!(key === 'returnValue' && old.preventDefault)) {
18805          event[key] = old[key];
18806        }
18807      }
18808    }
18809
18810    // The event occurred on this element
18811    if (!event.target) {
18812      event.target = event.srcElement || _globalDocument2['default'];
18813    }
18814
18815    // Handle which other element the event is related to
18816    if (!event.relatedTarget) {
18817      event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
18818    }
18819
18820    // Stop the default browser action
18821    event.preventDefault = function () {
18822      if (old.preventDefault) {
18823        old.preventDefault();
18824      }
18825      event.returnValue = false;
18826      old.returnValue = false;
18827      event.defaultPrevented = true;
18828    };
18829
18830    event.defaultPrevented = false;
18831
18832    // Stop the event from bubbling
18833    event.stopPropagation = function () {
18834      if (old.stopPropagation) {
18835        old.stopPropagation();
18836      }
18837      event.cancelBubble = true;
18838      old.cancelBubble = true;
18839      event.isPropagationStopped = returnTrue;
18840    };
18841
18842    event.isPropagationStopped = returnFalse;
18843
18844    // Stop the event from bubbling and executing other handlers
18845    event.stopImmediatePropagation = function () {
18846      if (old.stopImmediatePropagation) {
18847        old.stopImmediatePropagation();
18848      }
18849      event.isImmediatePropagationStopped = returnTrue;
18850      event.stopPropagation();
18851    };
18852
18853    event.isImmediatePropagationStopped = returnFalse;
18854
18855    // Handle mouse position
18856    if (event.clientX != null) {
18857      var doc = _globalDocument2['default'].documentElement,
18858          body = _globalDocument2['default'].body;
18859
18860      event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
18861      event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
18862    }
18863
18864    // Handle key presses
18865    event.which = event.charCode || event.keyCode;
18866
18867    // Fix button for mouse clicks:
18868    // 0 == left; 1 == middle; 2 == right
18869    if (event.button != null) {
18870      event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
18871    }
18872  }
18873
18874  // Returns fixed-up instance
18875  return event;
18876}
18877
18878/**
18879 * Clean up the listener cache and dispatchers
18880*
18881 * @param  {Element|Object} elem Element to clean up
18882 * @param  {String} type Type of event to clean up
18883 * @private
18884 * @method _cleanUpEvents
18885 */
18886function _cleanUpEvents(elem, type) {
18887  var data = Dom.getElData(elem);
18888
18889  // Remove the events of a particular type if there are none left
18890  if (data.handlers[type].length === 0) {
18891    delete data.handlers[type];
18892    // data.handlers[type] = null;
18893    // Setting to null was causing an error with data.handlers
18894
18895    // Remove the meta-handler from the element
18896    if (elem.removeEventListener) {
18897      elem.removeEventListener(type, data.dispatcher, false);
18898    } else if (elem.detachEvent) {
18899      elem.detachEvent('on' + type, data.dispatcher);
18900    }
18901  }
18902
18903  // Remove the events object if there are no types left
18904  if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
18905    delete data.handlers;
18906    delete data.dispatcher;
18907    delete data.disabled;
18908  }
18909
18910  // Finally remove the element data if there is no data left
18911  if (Object.getOwnPropertyNames(data).length === 0) {
18912    Dom.removeElData(elem);
18913  }
18914}
18915
18916/**
18917 * Loops through an array of event types and calls the requested method for each type.
18918 *
18919 * @param  {Function} fn   The event method we want to use.
18920 * @param  {Element|Object} elem Element or object to bind listeners to
18921 * @param  {String}   type Type of event to bind to.
18922 * @param  {Function} callback   Event listener.
18923 * @private
18924 * @function _handleMultipleEvents
18925 */
18926function _handleMultipleEvents(fn, elem, types, callback) {
18927  types.forEach(function (type) {
18928    //Call the event method for each one of the types
18929    fn(elem, type, callback);
18930  });
18931}
18932
18933},{"./dom.js":131,"./guid.js":135,"global/document":1,"global/window":2}],133:[function(_dereq_,module,exports){
18934/**
18935 * @file fn.js
18936 */
18937'use strict';
18938
18939exports.__esModule = true;
18940
18941var _guidJs = _dereq_('./guid.js');
18942
18943/**
18944 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
18945 * It also stores a unique id on the function so it can be easily removed from events
18946 *
18947 * @param  {*}   context The object to bind as scope
18948 * @param  {Function} fn      The function to be bound to a scope
18949 * @param  {Number=}   uid     An optional unique ID for the function to be set
18950 * @return {Function}
18951 * @private
18952 * @method bind
18953 */
18954var bind = function bind(context, fn, uid) {
18955  // Make sure the function has a unique ID
18956  if (!fn.guid) {
18957    fn.guid = _guidJs.newGUID();
18958  }
18959
18960  // Create the new function that changes the context
18961  var ret = function ret() {
18962    return fn.apply(context, arguments);
18963  };
18964
18965  // Allow for the ability to individualize this function
18966  // Needed in the case where multiple objects might share the same prototype
18967  // IF both items add an event listener with the same function, then you try to remove just one
18968  // it will remove both because they both have the same guid.
18969  // when using this, you need to use the bind method when you remove the listener as well.
18970  // currently used in text tracks
18971  ret.guid = uid ? uid + '_' + fn.guid : fn.guid;
18972
18973  return ret;
18974};
18975exports.bind = bind;
18976
18977},{"./guid.js":135}],134:[function(_dereq_,module,exports){
18978/**
18979 * @file format-time.js
18980 *
18981 * Format seconds as a time string, H:MM:SS or M:SS
18982 * Supplying a guide (in seconds) will force a number of leading zeros
18983 * to cover the length of the guide
18984 *
18985 * @param  {Number} seconds Number of seconds to be turned into a string
18986 * @param  {Number} guide   Number (in seconds) to model the string after
18987 * @return {String}         Time formatted as H:MM:SS or M:SS
18988 * @private
18989 * @function formatTime
18990 */
18991'use strict';
18992
18993exports.__esModule = true;
18994function formatTime(seconds) {
18995  var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1];
18996  return (function () {
18997    seconds = seconds < 0 ? 0 : seconds;
18998    var s = Math.floor(seconds % 60);
18999    var m = Math.floor(seconds / 60 % 60);
19000    var h = Math.floor(seconds / 3600);
19001    var gm = Math.floor(guide / 60 % 60);
19002    var gh = Math.floor(guide / 3600);
19003
19004    // handle invalid times
19005    if (isNaN(seconds) || seconds === Infinity) {
19006      // '-' is false for all relational operators (e.g. <, >
19006=) so this setting
19007      // will add the minimum number of fields specified by the guide
19008      h = m = s = '-';
19009    }
19010
19011    // Check if we need to show hours
19012    h = h > 0 || gh > 0 ? h + ':' : '';
19013
19014    // If hours are showing, we may need to add a leading zero.
19015    // Always show at least one digit of minutes.
19016    m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
19017
19018    // Check if leading zero is need for seconds
19019    s = s < 10 ? '0' + s : s;
19020
19021    return h + m + s;
19022  })();
19023}
19024
19025exports['default'] = formatTime;
19026module.exports = exports['default'];
19027
19028},{}],135:[function(_dereq_,module,exports){
19029/**
19030 * @file guid.js
19031 *
19032 * Unique ID for an element or function
19033 * @type {Number}
19034 * @private
19035 */
19036"use strict";
19037
19038exports.__esModule = true;
19039exports.newGUID = newGUID;
19040var _guid = 1;
19041
19042/**
19043 * Get the next unique ID
19044 *
19045 * @return {String} 
19046 * @function newGUID
19047 */
19048
19049function newGUID() {
19050  return _guid++;
19051}
19052
19053},{}],136:[function(_dereq_,module,exports){
19054/**
19055 * @file log.js
19056 */
19057'use strict';
19058
19059exports.__esModule = true;
19060
19061function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19062
19063var _globalWindow = _dereq_('global/window');
19064
19065var _globalWindow2 = _interopRequireDefault(_globalWindow);
19066
19067/**
19068 * Log plain debug messages
19069 */
19070var log = function log() {
19071  _logType(null, arguments);
19072};
19073
19074/**
19075 * Keep a history of log messages
19076 * @type {Array}
19077 */
19078log.history = [];
19079
19080/**
19081 * Log error messages
19082 */
19083log.error = function () {
19084  _logType('error', arguments);
19085};
19086
19087/**
19088 * Log warning messages
19089 */
19090log.warn = function () {
19091  _logType('warn', arguments);
19092};
19093
19094/**
19095 * Log messages to the console and history based on the type of message
19096 *
19097 * @param  {String} type The type of message, or `null` for `log`
19098 * @param  {Object} args The args to be passed to the log
19099 * @private
19100 * @method _logType
19101 */
19102function _logType(type, args) {
19103  // convert args to an array to get array functions
19104  var argsArray = Array.prototype.slice.call(args);
19105  // if there's no console then don't try to output messages
19106  // they will still be stored in log.history
19107  // Was setting these once outside of this function, but containing them
19108  // in the function makes it easier to test cases where console doesn't exist
19109  var noop = function noop() {};
19110
19111  var console = _globalWindow2['default']['console'] || {
19112    'log': noop,
19113    'warn': noop,
19114    'error': noop
19115  };
19116
19117  if (type) {
19118    // add the type to the front of the message
19119    argsArray.unshift(type.toUpperCase() + ':');
19120  } else {
19121    // default to log with no prefix
19122    type = 'log';
19123  }
19124
19125  // add to history
19126  log.history.push(argsArray);
19127
19128  // add console prefix after adding to history
19129  argsArray.unshift('VIDEOJS:');
19130
19131  // call appropriate log function
19132  if (console[type].apply) {
19133    console[type].apply(console, argsArray);
19134  } else {
19135    // ie8 doesn't allow error.apply, but it will just join() the array anyway
19136    console[type](argsArray.join(' '));
19137  }
19138}
19139
19140exports['default'] = log;
19141module.exports = exports['default'];
19142
19143},{"global/window":2}],137:[function(_dereq_,module,exports){
19144/**
19145 * @file merge-options.js
19146 */
19147'use strict';
19148
19149exports.__esModule = true;
19150exports['default'] = mergeOptions;
19151
19152function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19153
19154var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
19155
19156var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
19157
19158function isPlain(obj) {
19159  return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object;
19160}
19161
19162/**
19163 * Merge customizer. video.js simply overwrites non-simple objects
19164 * (like arrays) instead of attempting to overlay them.
19165 * @see https://lodash.com/docs#merge
19166 */
19167var customizer = function customizer(destination, source) {
19168  // If we're not working with a plain object, copy the value as is
19169  // If source is an array, for instance, it will replace destination
19170  if (!isPlain(source)) {
19171    return source;
19172  }
19173
19174  // If the new value is a plain object but the first object value is not
19175  // we need to create a new object for the first object to merge with.
19176  // This makes it consistent with how merge() works by default
19177  // and also protects from later changes the to first object affecting
19178  // the second object's values.
19179  if (!isPlain(destination)) {
19180    return mergeOptions(source);
19181  }
19182};
19183
19184/**
19185 * Merge one or more options objects, recursively merging **only**
19186 * plain object properties.  Previously `deepMerge`.
19187 *
19188 * @param  {...Object} source One or more objects to merge
19189 * @returns {Object}          a new object that is the union of all
19190 * provided objects
19191 * @function mergeOptions
19192 */
19193
19194function mergeOptions() {
19195  // contruct the call dynamically to handle the variable number of
19196  // objects to merge
19197  var args = Array.prototype.slice.call(arguments);
19198
19199  // unshift an empty object into the front of the call as the target
19200  // of the merge
19201  args.unshift({});
19202
19203  // customize conflict resolution to match our historical merge behavior
19204  args.push(customizer);
19205
19206  _lodashCompatObjectMerge2['default'].apply(null, args);
19207
19208  // return the mutated result object
19209  return args[0];
19210}
19211
19212module.exports = exports['default'];
19213
19214},{"lodash-compat/object/merge":40}],138:[function(_dereq_,module,exports){
19215'use strict';
19216
19217exports.__esModule = true;
19218
19219function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19220
19221var _globalDocument = _dereq_('global/document');
19222
19223var _globalDocument2 = _interopRequireDefault(_globalDocument);
19224
19225var createStyleElement = function createStyleElement(className) {
19226  var style = _globalDocument2['default'].createElement('style');
19227  style.className = className;
19228
19229  return style;
19230};
19231
19232exports.createStyleElement = createStyleElement;
19233var setTextContent = function setTextContent(el, content) {
19234  if (el.styleSheet) {
19235    el.styleSheet.cssText = content;
19236  } else {
19237    el.textContent = content;
19238  }
19239};
19240exports.setTextContent = setTextContent;
19241
19242},{"global/document":1}],139:[function(_dereq_,module,exports){
19243'use strict';
19244
19245exports.__esModule = true;
19246exports.createTimeRanges = createTimeRanges;
19247
19248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19249
19250var _logJs = _dereq_('./log.js');
19251
19252var _logJs2 = _interopRequireDefault(_logJs);
19253
19254/**
19255 * @file time-ranges.js
19256 *
19257 * Should create a fake TimeRange object
19258 * Mimics an HTML5 time range instance, which has functions that
19259 * return the start and end times for a range
19260 * TimeRanges are returned by the buffered() method
19261 *
19262 * @param  {(Number|Array)} Start of a single range or an array of ranges
19263 * @param  {Number} End of a single range
19264 * @private
19265 * @method createTimeRanges
19266 */
19267
19268function createTimeRanges(start, end) {
19269  if (Array.isArray(start)) {
19270    return createTimeRangesObj(start);
19271  } else if (start === undefined || end === undefined) {
19272    return createTimeRangesObj();
19273  }
19274  return createTimeRangesObj([[start, end]]);
19275}
19276
19277exports.createTimeRange = createTimeRanges;
19278
19279function createTimeRangesObj(ranges) {
19280  if (ranges === undefined || ranges.length === 0) {
19281    return {
19282      length: 0,
19283      start: function start() {
19284        throw new Error('This TimeRanges object is empty');
19285      },
19286      end: function end() {
19287        throw new Error('This TimeRanges object is empty');
19288      }
19289    };
19290  }
19291  return {
19292    length: ranges.length,
19293    start: getRange.bind(null, 'start', 0, ranges),
19294    end: getRange.bind(null, 'end', 1, ranges)
19295  };
19296}
19297
19298function getRange(fnName, valueIndex, ranges, rangeIndex) {
19299  if (rangeIndex === undefined) {
19300    _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
19301    rangeIndex = 0;
19302  }
19303  rangeCheck(fnName, rangeIndex, ranges.length - 1);
19304  return ranges[rangeIndex][valueIndex];
19305}
19306
19307function rangeCheck(fnName, index, maxIndex) {
19308  if (index < 0 || index > maxIndex) {
19309    throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
19310  }
19311}
19312
19313},{"./log.js":136}],140:[function(_dereq_,module,exports){
19314/**
19315 * @file to-title-case.js
19316 *
19317 * Uppercase the first letter of a string
19318 *
19319 * @param  {String} string String to be uppercased
19320 * @return {String}
19321 * @private
19322 * @method toTitleCase
19323 */
19324"use strict";
19325
19326exports.__esModule = true;
19327function toTitleCase(string) {
19328  return string.charAt(0).toUpperCase() + string.slice(1);
19329}
19330
19331exports["default"] = toTitleCase;
19332module.exports = exports["default"];
19333
19334},{}],141:[function(_dereq_,module,exports){
19335/**
19336 * @file url.js
19337 */
19338'use strict';
19339
19340exports.__esModule = true;
19341
19342function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19343
19344var _globalDocument = _dereq_('global/document');
19345
19346var _globalDocument2 = _interopRequireDefault(_globalDocument);
19347
19348var _globalWindow = _dereq_('global/window');
19349
19350var _globalWindow2 = _interopRequireDefault(_globalWindow);
19351
19352/**
19353 * Resolve and parse the elements of a URL
19354 *
19355 * @param  {String} url The url to parse
19356 * @return {Object}     An object of url details
19357 * @method parseUrl
19358 */
19359var parseUrl = function parseUrl(url) {
19360  var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
19361
19362  // add the url to an anchor and let the browser parse the URL
19363  var a = _globalDocument2['default'].createElement('a');
19364  a.href = url;
19365
19366  // IE8 (and 9?) Fix
19367  // ie8 doesn't parse the URL correctly until the anchor is actually
19368  // added to the body, and an innerHTML is needed to trigger the parsing
19369  var addToBody = a.host === '' && a.protocol !== 'file:';
19370  var div = undefined;
19371  if (addToBody) {
19372    div = _globalDocument2['default'].createElement('div');
19373    div.innerHTML = '<a href="' + url + '"></a>';
19374    a = div.firstChild;
19375    // prevent the div from affecting layout
19376    div.setAttribute('style', 'display:none; position:absolute;');
19377    _globalDocument2['default'].body.appendChild(div);
19378  }
19379
19380  // Copy the specific URL properties to a new object
19381  // This is also needed for IE8 because the anchor loses its
19382  // properties when it's removed from the dom
19383  var details = {};
19384  for (var i = 0; i < props.length; i++) {
19385    details[props[i]] = a[props[i]];
19386  }
19387
19388  // IE9 adds the port to the host property unlike everyone else. If
19389  // a port identifier is added for standard ports, strip it.
19390  if (details.protocol === 'http:') {
19391    details.host = details.host.replace(/:80$/, '');
19392  }
19393  if (details.protocol === 'https:') {
19394    details.host = details.host.replace(/:443$/, '');
19395  }
19396
19397  if (addToBody) {
19398    _globalDocument2['default'].body.removeChild(div);
19399  }
19400
19401  return details;
19402};
19403
19404exports.parseUrl = parseUrl;
19405/**
19406 * Get absolute version of relative URL. Used to tell flash correct URL.
19407 * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
19408 *
19409 * @param  {String} url URL to make absolute
19410 * @return {String}     Absolute URL
19411 * @private
19412 * @method getAbsoluteURL
19413 */
19414var getAbsoluteURL = function getAbsoluteURL(url) {
19415  // Check if absolute URL
19416  if (!url.match(/^https?:\/\//)) {
19417    // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
19418    var div = _globalDocument2['default'].createElement('div');
19419    div.innerHTML = '<a href="' + url + '">x</a>';
19420    url = div.firstChild.href;
19421  }
19422
19423  return url;
19424};
19425
19426exports.getAbsoluteURL = getAbsoluteURL;
19427/**
19428 * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path
19429 *
19430 * @param {String}    path    The fileName path like '/path/to/file.mp4'
19431 * @returns {String}          The extension in lower case or an empty string if no extension could be found.
19432 * @method getFileExtension
19433 */
19434var getFileExtension = function getFileExtension(path) {
19435  if (typeof path === 'string') {
19436    var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
19437    var pathParts = splitPathRe.exec(path);
19438
19439    if (pathParts) {
19440      return pathParts.pop().toLowerCase();
19441    }
19442  }
19443
19444  return '';
19445};
19446
19447exports.getFileExtension = getFileExtension;
19448/**
19449 * Returns whether the url passed is a cross domain request or not.
19450 *
19451 * @param {String} url The url to check
19452 * @return {Boolean}   Whether it is a cross domain request or not
19453 * @method isCrossOrigin
19454 */
19455var isCrossOrigin = function isCrossOrigin(url) {
19456  var winLoc = _globalWindow2['default'].location;
19457  var urlInfo = parseUrl(url);
19458
19459  // IE8 protocol relative urls will return ':' for protocol
19460  var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
19461
19462  // Check if url is for another domain/origin
19463  // IE8 doesn't know location.origin, so we won't rely on it here
19464  var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
19465
19466  return crossOrigin;
19467};
19468exports.isCrossOrigin = isCrossOrigin;
19469
19470},{"global/document":1,"global/window":2}],142:[function(_dereq_,module,exports){
19471/**
19472 * @file video.js
19473 */
19474'use strict';
19475
19476exports.__esModule = true;
19477
19478function _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; } }
19479
19480function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19481
19482var _globalDocument = _dereq_('global/document');
19483
19484var _globalDocument2 = _interopRequireDefault(_globalDocument);
19485
19486var _setup = _dereq_('./setup');
19487
19488var setup = _interopRequireWildcard(_setup);
19489
19490var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
19491
19492var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
19493
19494var _component = _dereq_('./component');
19495
19496var _component2 = _interopRequireDefault(_component);
19497
19498var _eventTarget = _dereq_('./event-target');
19499
19500var _eventTarget2 = _interopRequireDefault(_eventTarget);
19501
19502var _utilsEventsJs = _dereq_('./utils/events.js');
19503
19504var Events = _interopRequireWildcard(_utilsEventsJs);
19505
19506var _player = _dereq_('./player');
19507
19508var _player2 = _interopRequireDefault(_player);
19509
19510var _pluginsJs = _dereq_('./plugins.js');
19511
19512var _pluginsJs2 = _interopRequireDefault(_pluginsJs);
19513
19514var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js');
19515
19516var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs);
19517
19518var _utilsFnJs = _dereq_('./utils/fn.js');
19519
19520var Fn = _interopRequireWildcard(_utilsFnJs);
19521
19522var _tracksTextTrackJs = _dereq_('./tracks/text-track.js');
19523
19524var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs);
19525
19526var _objectAssign = _dereq_('object.assign');
19527
19528var _objectAssign2 = _interopRequireDefault(_objectAssign);
19529
19530var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
19531
19532var _utilsFormatTimeJs = _dereq_('./utils/format-time.js');
19533
19534var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
19535
19536var _utilsLogJs = _dereq_('./utils/log.js');
19537
19538var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
19539
19540var _utilsDomJs = _dereq_('./utils/dom.js');
19541
19542var Dom = _interopRequireWildcard(_utilsDomJs);
19543
19544var _utilsBrowserJs = _dereq_('./utils/browser.js');
19545
19546var browser = _interopRequireWildcard(_utilsBrowserJs);
19547
19548var _utilsUrlJs = _dereq_('./utils/url.js');
19549
19550var Url = _interopRequireWildcard(_utilsUrlJs);
19551
19552var _extendJs = _dereq_('./extend.js');
19553
19554var _extendJs2 = _interopRequireDefault(_extendJs);
19555
19556var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
19557
19558var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
19559
19560var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js');
19561
19562var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs);
19563
19564var _xhr = _dereq_('xhr');
19565
19566var _xhr2 = _interopRequireDefault(_xhr);
19567
19568// Include the built-in techs
19569
19570var _techTechJs = _dereq_('./tech/tech.js');
19571
19572var _techTechJs2 = _interopRequireDefault(_techTechJs);
19573
19574var _techHtml5Js = _dereq_('./tech/html5.js');
19575
19576var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
19577
19578var _techFlashJs = _dereq_('./tech/flash.js');
19579
19580var _techFlashJs2 = _interopRequireDefault(_techFlashJs);
19581
19582// HTML5 Element Shim for IE8
19583if (typeof HTMLVideoElement === 'undefined') {
19584  _globalDocument2['default'].createElement('video');
19585  _globalDocument2['default'].createElement('audio');
19586  _globalDocument2['default'].createElement('track');
19587}
19588
19589/**
19590 * Doubles as the main function for users to create a player instance and also
19591 * the main library object.
19592 * The `videojs` function can be used to initialize or retrieve a player.
19593 * ```js
19594 *     var myPlayer = videojs('my_video_id');
19595 * ```
19596 *
19597 * @param  {String|Element} id      Video element or video element ID
19598 * @param  {Object=} options        Optional options object for config/settings
19599 * @param  {Function=} ready        Optional ready callback
19600 * @return {Player}                 A player instance
19601 * @mixes videojs
19602 * @method videojs
19603 */
19604var videojs = function videojs(id, options, ready) {
19605  var tag = undefined; // Element of ID
19606
19607  // Allow for element or ID to be passed in
19608  // String ID
19609  if (typeof id === 'string') {
19610
19611    // Adjust for jQuery ID syntax
19612    if (id.indexOf('#') === 0) {
19613      id = id.slice(1);
19614    }
19615
19616    // If a player instance has already been created for this ID return it.
19617    if (videojs.getPlayers()[id]) {
19618
19619      // If options or ready funtion are passed, warn
19620      if (options) {
19621        _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
19622      }
19623
19624      if (ready) {
19625        videojs.getPlayers()[id].ready(ready);
19626      }
19627
19628      return videojs.getPlayers()[id];
19629
19630      // Otherwise get element for ID
19631    } else {
19632        tag = Dom.getEl(id);
19633      }
19634
19635    // ID is a media element
19636  } else {
19637      tag = id;
19638    }
19639
19640  // Check for a useable element
19641  if (!tag || !tag.nodeName) {
19642    // re: nodeName, could be a box div also
19643    throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns
19644  }
19645
19646  // Element may have a player attr referring to an already created player instance.
19647  // If not, set up a new player and return the instance.
19648  return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready);
19649};
19650
19651// Add default styles
19652var style = Dom.$('.vjs-styles-defaults');
19653if (!style) {
19654  style = stylesheet.createStyleElement('vjs-styles-defaults');
19655  var head = Dom.$('head');
19656  head.insertBefore(style, head.firstChild);
19657  stylesheet.setTextContent(style, '\n    .video-js {\n      width: 300px;\n      height: 150px;\n    }\n\n    .vjs-fluid {\n      padding-top: 56.25%\n    }\n  ');
19658}
19659
19660// Run Auto-load players
19661// 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)
19662setup.autoSetupTimeout(1, videojs);
19663
19664/*
19665 * Current software version (semver)
19666 *
19667 * @type {String}
19668 */
19669videojs.VERSION = '5.7.0';
19670
19671/**
19672 * The global options object. These are the settings that take effect
19673 * if no overrides are specified when the player is created.
19674 *
19675 * ```js
19676 *     videojs.options.autoplay = true
19677 *     // -> all players will autoplay by default
19678 * ```
19679 *
19680 * @type {Object}
19681 */
19682videojs.options = _player2['default'].prototype.options_;
19683
19684/**
19685 * Get an object with the currently created players, keyed by player ID
19686 *
19687 * @return {Object} The created players
19688 * @mixes videojs
19689 * @method getPlayers
19690 */
19691videojs.getPlayers = function () {
19692  return _player2['default'].players;
19693};
19694
19695/**
19696 * For backward compatibility, expose players object.
19697 *
19698 * @deprecated
19699 * @memberOf videojs
19700 * @property {Object|Proxy} players
19701 */
19702videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, {
19703  get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead',
19704  set: 'Modification of videojs.players is deprecated'
19705});
19706
19707/**
19708 * Get a component class object by name
19709 * ```js
19710 *     var VjsButton = videojs.getComponent('Button');
19711 *     // Create a new instance of the component
19712 *     var myButton = new VjsButton(myPlayer);
19713 * ```
19714 *
19715 * @return {Component} Component identified by name
19716 * @mixes videojs
19717 * @method getComponent
19718 */
19719videojs.getComponent = _component2['default'].getComponent;
19720
19721/**
19722 * Register a component so it can referred to by name
19723 * Used when adding to other
19724 * components, either through addChild
19725 * `component.addChild('myComponent')`
19726 * or through default children options
19727 * `{ children: ['myComponent'] }`.
19728 * ```js
19729 *     // Get a component to subclass
19730 *     var VjsButton = videojs.getComponent('Button');
19731 *     // Subclass the component (see 'extend' doc for more info)
19732 *     var MySpecialButton = videojs.extend(VjsButton, {});
19733 *     // Register the new component
19734 *     VjsButton.registerComponent('MySepcialButton', MySepcialButton);
19735 *     // (optionally) add the new component as a default player child
19736 *     myPlayer.addChild('MySepcialButton');
19737 * ```
19738 * NOTE: You could also just initialize the component before adding.
19739 * `component.addChild(new MyComponent());`
19740 *
19741 * @param {String} The class name of the component
19742 * @param {Component} The component class
19743 * @return {Component} The newly registered component
19744 * @mixes videojs
19745 * @method registerComponent
19746 */
19747videojs.registerComponent = function (name, comp) {
19748  if (_techTechJs2['default'].isTech(comp)) {
19749    _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
19750  }
19751
19752  _component2['default'].registerComponent.call(_component2['default'], name, comp);
19753};
19754
19755/**
19756 * Get a Tech class object by name
19757 * ```js
19758 *     var Html5 = videojs.getTech('Html5');
19759 *     // Create a new instance of the component
19760 *     var html5 = new Html5(options);
19761 * ```
19762 *
19763 * @return {Tech} Tech identified by name
19764 * @mixes videojs
19765 * @method getComponent
19766 */
19767videojs.getTech = _techTechJs2['default'].getTech;
19768
19769/**
19770 * Register a Tech so it can referred to by name.
19771 * This is used in the tech order for the player.
19772 *
19773 * ```js
19774 *     // get the Html5 Tech
19775 *     var Html5 = videojs.getTech('Html5');
19776 *     var MyTech = videojs.extend(Html5, {});
19777 *     // Register the new Tech
19778 *     VjsButton.registerTech('Tech', MyTech);
19779 *     var player = videojs('myplayer', {
19780 *       techOrder: ['myTech', 'html5']
19781 *     });
19782 * ```
19783 *
19784 * @param {String} The class name of the tech
19785 * @param {Tech} The tech class
19786 * @return {Tech} The newly registered Tech
19787 * @mixes videojs
19788 * @method registerTech
19789 */
19790videojs.registerTech = _techTechJs2['default'].registerTech;
19791
19792/**
19793 * A suite of browser and device tests
19794 *
19795 * @type {Object}
19796 * @private
19797 */
19798videojs.browser = browser;
19799
19800/**
19801 * Whether or not the browser supports touch events. Included for backward
19802 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
19803 * instead going forward.
19804 *
19805 * @deprecated
19806 * @type {Boolean}
19807 */
19808videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
19809
19810/**
19811 * Subclass an existing class
19812 * Mimics ES6 subclassing with the `extend` keyword
19813 * ```js
19814 *     // Create a basic javascript 'class'
19815 *     function MyClass(name){
19816 *       // Set a property at initialization
19817 *       this.myName = name;
19818 *     }
19819 *     // Create an instance method
19820 *     MyClass.prototype.sayMyName = function(){
19821 *       alert(this.myName);
19822 *     };
19823 *     // Subclass the exisitng class and change the name
19824 *     // when initializing
19825 *     var MySubClass = videojs.extend(MyClass, {
19826 *       constructor: function(name) {
19827 *         // Call the super class constructor for the subclass
19828 *         MyClass.call(this, name)
19829 *       }
19830 *     });
19831 *     // Create an instance of the new sub class
19832 *     var myInstance = new MySubClass('John');
19833 *     myInstance.sayMyName(); // -> should alert "John"
19834 * ```
19835 *
19836 * @param {Function} The Class to subclass
19837 * @param {Object} An object including instace methods for the new class
19838 *                   Optionally including a `constructor` function
19839 * @return {Function} The newly created subclass
19840 * @mixes videojs
19841 * @method extend
19842 */
19843videojs.extend = _extendJs2['default'];
19844
19845/**
19846 * Merge two options objects recursively
19847 * Performs a deep merge like lodash.merge but **only merges plain objects**
19848 * (not arrays, elements, anything else)
19849 * Other values will be copied directly from the second object.
19850 * ```js
19851 *     var defaultOptions = {
19852 *       foo: true,
19853 *       bar: {
19854 *         a: true,
19855 *         b: [1,2,3]
19856 *       }
19857 *     };
19858 *     var newOptions = {
19859 *       foo: false,
19860 *       bar: {
19861 *         b: [4,5,6]
19862 *       }
19863 *     };
19864 *     var result = videojs.mergeOptions(defaultOptions, newOptions);
19865 *     // result.foo = false;
19866 *     // result.bar.a = true;
19867 *     // result.bar.b = [4,5,6];
19868 * ```
19869 *
19870 * @param {Object} defaults  The options object whose values will be overriden
19871 * @param {Object} overrides The options object with values to override the first
19872 * @param {Object} etc       Any number of additional options objects
19873 *
19874 * @return {Object} a new object with the merged values
19875 * @mixes videojs
19876 * @method mergeOptions
19877 */
19878videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default'];
19879
19880/**
19881 * Change the context (this) of a function
19882 *
19883 *     videojs.bind(newContext, function(){
19884 *       this === newContext
19885 *     });
19886 *
19887 * NOTE: as of v5.0 we require an ES5 shim, so you should use the native
19888 * `function(){}.bind(newContext);` instead of this.
19889 *
19890 * @param  {*}        context The object to bind as scope
19891 * @param  {Function} fn      The function to be bound to a scope
19892 * @param  {Number=}  uid     An optional unique ID for the function to be set
19893 * @return {Function}
19894 */
19895videojs.bind = Fn.bind;
19896
19897/**
19898 * Create a Video.js player plugin
19899 * Plugins are only initialized when options for the plugin are included
19900 * in the player options, or the plugin function on the player instance is
19901 * called.
19902 * **See the plugin guide in the docs for a more detailed example**
19903 * ```js
19904 *     // Make a plugin that alerts when the player plays
19905 *     videojs.plugin('myPlugin', function(myPluginOptions) {
19906 *       myPluginOptions = myPluginOptions || {};
19907 *
19908 *       var player = this;
19909 *       var alertText = myPluginOptions.text || 'Player is playing!'
19910 *
19911 *       player.on('play', function(){
19912 *         alert(alertText);
19913 *       });
19914 *     });
19915 *     // USAGE EXAMPLES
19916 *     // EXAMPLE 1: New player with plugin options, call plugin immediately
19917 *     var player1 = videojs('idOne', {
19918 *       myPlugin: {
19919 *         text: 'Custom text!'
19920 *       }
19921 *     });
19922 *     // Click play
19923 *     // --> Should alert 'Custom text!'
19924 *     // EXAMPLE 3: New player, initialize plugin later
19925 *     var player3 = videojs('idThree');
19926 *     // Click play
19927 *     // --> NO ALERT
19928 *     // Click pause
19929 *     // Initialize plugin using the plugin function on the player instance
19930 *     player3.myPlugin({
19931 *       text: 'Plugin added later!'
19932 *     });
19933 *     // Click play
19934 *     // --> Should alert 'Plugin added later!'
19935 * ```
19936 *
19937 * @param {String} name The plugin name
19938 * @param {Function} fn The plugin function that will be called with options
19939 * @mixes videojs
19940 * @method plugin
19941 */
19942videojs.plugin = _pluginsJs2['default'];
19943
19944/**
19945 * Adding languages so that they're available to all players.
19946 * ```js
19947 *     videojs.addLanguage('es', { 'Hello': 'Hola' });
19948 * ```
19949 *
19950 * @param  {String} code The language code or dictionary property
19951 * @param  {Object} data The data values to be translated
19952 * @return {Object} The resulting language dictionary object
19953 * @mixes videojs
19954 * @method addLanguage
19955 */
19956videojs.addLanguage = function (code, data) {
19957  var _merge;
19958
19959  code = ('' + code).toLowerCase();
19960  return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code];
19961};
19962
19963/**
19964 * Log debug messages.
19965 *
19966 * @param {...Object} messages One or more messages to log
19967 */
19968videojs.log = _utilsLogJs2['default'];
19969
19970/**
19971 * Creates an emulated TimeRange object.
19972 *
19973 * @param  {Number|Array} start Start time in seconds or an array of ranges
19974 * @param  {Number} end   End time in seconds
19975 * @return {Object}       Fake TimeRange object
19976 * @method createTimeRange
19977 */
19978videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges;
19979
19980/**
19981 * Format seconds as a time string, H:MM:SS or M:SS
19982 * Supplying a guide (in seconds) will force a number of leading zeros
19983 * to cover the length of the guide
19984 *
19985 * @param  {Number} seconds Number of seconds to be turned into a string
19986 * @param  {Number} guide   Number (in seconds) to model the string after
19987 * @return {String}         Time formatted as H:MM:SS or M:SS
19988 * @method formatTime
19989 */
19990videojs.formatTime = _utilsFormatTimeJs2['default'];
19991
19992/**
19993 * Resolve and parse the elements of a URL
19994 *
19995 * @param  {String} url The url to parse
19996 * @return {Object}     An object of url details
19997 * @method parseUrl
19998 */
19999videojs.parseUrl = Url.parseUrl;
20000
20001/**
20002 * Returns whether the url passed is a cross domain request or not.
20003 *
20004 * @param {String} url The url to check
20005 * @return {Boolean}   Whether it is a cross domain request or not
20006 * @method isCrossOrigin
20007 */
20008videojs.isCrossOrigin = Url.isCrossOrigin;
20009
20010/**
20011 * Event target class.
20012 *
20013 * @type {Function}
20014 */
20015videojs.EventTarget = _eventTarget2['default'];
20016
20017/**
20018 * Add an event listener to element
20019 * It stores the handler function in a separate cache object
20020 * and adds a generic handler to the element's event,
20021 * along with a unique id (guid) to the element.
20022 *
20023 * @param  {Element|Object}   elem Element or object to bind listeners to
20024 * @param  {String|Array}   type Type of event to bind to.
20025 * @param  {Function} fn   Event listener.
20026 * @method on
20027 */
20028videojs.on = Events.on;
20029
20030/**
20031 * Trigger a listener only once for an event
20032 *
20033 * @param  {Element|Object}   elem Element or object to
20034 * @param  {String|Array}   type Name/type of event
20035 * @param  {Function} fn Event handler function
20036 * @method one
20037 */
20038videojs.one = Events.one;
20039
20040/**
20041 * Removes event listeners from an element
20042 *
20043 * @param  {Element|Object}   elem Object to remove listeners from
20044 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
20045 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
20046 * @method off
20047 */
20048videojs.off = Events.off;
20049
20050/**
20051 * Trigger an event for an element
20052 *
20053 * @param  {Element|Object}      elem  Element to trigger an event on
20054 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
20055 * @param  {Object} [hash] data hash to pass along with the event
20056 * @return {Boolean=} Returned only if default was prevented
20057 * @method trigger
20058 */
20059videojs.trigger = Events.trigger;
20060
20061/**
20062 * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
20063 *
20064 *     videojs.xhr({
20065 *       body: someJSONString,
20066 *       uri: "/foo",
20067 *       headers: {
20068 *         "Content-Type": "application/json"
20069 *       }
20070 *     }, function (err, resp, body) {
20071 *       // check resp.statusCode
20072 *     });
20073 *
20074 * Check out the [full
20075 * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md)
20076 * for more options.
20077 *
20078 * @param {Object} options settings for the request.
20079 * @return {XMLHttpRequest|XDomainRequest} the request object.
20080 * @see https://github.com/Raynos/xhr
20081 */
20082videojs.xhr = _xhr2['default'];
20083
20084/**
20085 * TextTrack class
20086 *
20087 * @type {Function}
20088 */
20089videojs.TextTrack = _tracksTextTrackJs2['default'];
20090
20091/**
20092 * Determines, via duck typing, whether or not a value is a DOM element.
20093 *
20094 * @method isEl
20095 * @param  {Mixed} value
20096 * @return {Boolean}
20097 */
20098videojs.isEl = Dom.isEl;
20099
20100/**
20101 * Determines, via duck typing, whether or not a value is a text node.
20102 *
20103 * @method isTextNode
20104 * @param  {Mixed} value
20105 * @return {Boolean}
20106 */
20107videojs.isTextNode = Dom.isTextNode;
20108
20109/**
20110 * Creates an element and applies properties.
20111 *
20112 * @method createEl
20113 * @param  {String} [tagName='div'] Name of tag to be created.
20114 * @param  {Object} [properties={}] Element properties to be applied.
20115 * @param  {Object} [attributes={}] Element attributes to be applied.
20116 * @return {Element}
20117 */
20118videojs.createEl = Dom.createEl;
20119
20120/**
20121 * Check if an element has a CSS class
20122 *
20123 * @method hasClass
20124 * @param {Element} element Element to check
20125 * @param {String} classToCheck Classname to check
20126 */
20127videojs.hasClass = Dom.hasElClass;
20128
20129/**
20130 * Add a CSS class name to an element
20131 *
20132 * @method addClass
20133 * @param {Element} element    Element to add class name to
20134 * @param {String} classToAdd Classname to add
20135 */
20136videojs.addClass = Dom.addElClass;
20137
20138/**
20139 * Remove a CSS class name from an element
20140 *
20141 * @method removeClass
20142 * @param {Element} element    Element to remove from class name
20143 * @param {String} classToRemove Classname to remove
20144 */
20145videojs.removeClass = Dom.removeElClass;
20146
20147/**
20148 * Adds or removes a CSS class name on an element depending on an optional
20149 * condition or the presence/absence of the class name.
20150 *
20151 * @method toggleElClass
20152 * @param  {Element} element
20153 * @param  {String} classToToggle
20154 * @param  {Boolean|Function} [predicate]
20155 *         Can be a function that returns a Boolean. If `true`, the class
20156 *         will be added; if `false`, the class will be removed. If not
20157 *         given, the class will be added if not present and vice versa.
20158 */
20159videojs.toggleClass = Dom.toggleElClass;
20160
20161/**
20162 * Apply attributes to an HTML element.
20163 *
20164 * @method setAttributes
20165 * @param  {Element} el         Target element.
20166 * @param  {Object=} attributes Element attributes to be applied.
20167 */
20168videojs.setAttributes = Dom.setElAttributes;
20169
20170/**
20171 * Get an element's attribute values, as defined on the HTML tag
20172 * Attributes are not the same as properties. They're defined on the tag
20173 * or with setAttribute (which shouldn't be used with HTML)
20174 * This will return true or false for boolean attributes.
20175 *
20176 * @method getAttributes
20177 * @param  {Element} tag Element from which to get tag attributes
20178 * @return {Object}
20179 */
20180videojs.getAttributes = Dom.getElAttributes;
20181
20182/**
20183 * Empties the contents of an element.
20184 *
20185 * @method emptyEl
20186 * @param  {Element} el
20187 * @return {Element}
20188 */
20189videojs.emptyEl = Dom.emptyEl;
20190
20191/**
20192 * Normalizes and appends content to an element.
20193 *
20194 * The content for an element can be passed in multiple types and
20195 * combinations, whose behavior is as follows:
20196 *
20197 * - String
20198 *   Normalized into a text node.
20199 *
20200 * - Element, TextNode
20201 *   Passed through.
20202 *
20203 * - Array
20204 *   A one-dimensional array of strings, elements, nodes, or functions (which
20205 *   return single strings, elements, or nodes).
20206 *
20207 * - Function
20208 *   If the sole argument, is expected to produce a string, element,
20209 *   node, or array.
20210 *
20211 * @method appendContent
20212 * @param  {Element} el
20213 * @param  {String|Element|TextNode|Array|Function} content
20214 * @return {Element}
20215 */
20216videojs.appendContent = Dom.appendContent;
20217
20218/**
20219 * Normalizes and inserts content into an element; this is identical to
20220 * `appendContent()`, except it empties the element first.
20221 *
20222 * The content for an element can be passed in multiple types and
20223 * combinations, whose behavior is as follows:
20224 *
20225 * - String
20226 *   Normalized into a text node.
20227 *
20228 * - Element, TextNode
20229 *   Passed through.
20230 *
20231 * - Array
20232 *   A one-dimensional array of strings, elements, nodes, or functions (which
20233 *   return single strings, elements, or nodes).
20234 *
20235 * - Function
20236 *   If the sole argument, is expected to produce a string, element,
20237 *   node, or array.
20238 *
20239 * @method insertContent
20240 * @param  {Element} el
20241 * @param  {String|Element|TextNode|Array|Function} content
20242 * @return {Element}
20243 */
20244videojs.insertContent = Dom.insertContent;
20245
20246/*
20247 * Custom Universal Module Definition (UMD)
20248 *
20249 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
20250 * still support requirejs and browserify. This also needs to be closure
20251 * compiler compatible, so string keys are used.
20252 */
20253if (typeof define === 'function' && define['amd']) {
20254  define('videojs', [], function () {
20255    return videojs;
20256  });
20257
20258  // checking that module is an object too because of umdjs/umd#35
20259} else if (typeof exports === 'object' && typeof module === 'object') {
20260    module['exports'] = videojs;
20261  }
20262
20263exports['default'] = videojs;
20264module.exports = exports['default'];
20265
20266},{"../../src/js/utils/merge-options.js":137,"./component":66,"./event-target":98,"./extend.js":99,"./player":107,"./plugins.js":108,"./setup":112,"./tech/flash.js":115,"./tech/html5.js":116,"./tech/tech.js":118,"./tracks/text-track.js":127,"./utils/browser.js":128,"./utils/create-deprecation-proxy.js":130,"./utils/dom.js":131,"./utils/events.js":132,"./utils/fn.js":133,"./utils/format-time.js":134,"./utils/log.js":136,"./utils/stylesheet.js":138,"./utils/time-ranges.js":139,"./utils/url.js":141,"global/document":1,"lodash-compat/object/merge":40,"object.assign":45,"xhr":55}]},{},[142])(142)
20267});
20268
20269
20270//# sourceMappingURL=video.js.map
20271/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */
20272
20273(function(root) {
20274  var vttjs = root.vttjs = {};
20275  var cueShim = vttjs.VTTCue;
20276  var regionShim = vttjs.VTTRegion;
20277  var oldVTTCue = root.VTTCue;
20278  var oldVTTRegion = root.VTTRegion;
20279
20280  vttjs.shim = function() {
20281    vttjs.VTTCue = cueShim;
20282    vttjs.VTTRegion = regionShim;
20283  };
20284
20285  vttjs.restore = function() {
20286    vttjs.VTTCue = oldVTTCue;
20287    vttjs.VTTRegion = oldVTTRegion;
20288  };
20289}(this));
20290
20291/**
20292 * Copyright 2013 vtt.js Contributors
20293 *
20294 * Licensed under the Apache License, Version 2.0 (the "License");
20295 * you may not use this file except in compliance with the License.
20296 * You may obtain a copy of the License at
20297 *
20298 *   http://www.apache.org/licenses/LICENSE-2.0
20299 *
20300 * Unless required by applicable law or agreed to in writing, software
20301 * distributed under the License is distributed on an "AS IS" BASIS,
20302 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20303 * See the License for the specific language governing permissions and
20304 * limitations under the License.
20305 */
20306
20307(function(root, vttjs) {
20308
20309  var autoKeyword = "auto";
20310  var directionSetting = {
20311    "": true,
20312    "lr": true,
20313    "rl": true
20314  };
20315  var alignSetting = {
20316    "start": true,
20317    "middle": true,
20318    "end": true,
20319    "left": true,
20320    "right": true
20321  };
20322
20323  function findDirectionSetting(value) {
20324    if (typeof value !== "string") {
20325      return false;
20326    }
20327    var dir = directionSetting[value.toLowerCase()];
20328    return dir ? value.toLowerCase() : false;
20329  }
20330
20331  function findAlignSetting(value) {
20332    if (typeof value !== "string") {
20333      return false;
20334    }
20335    var align = alignSetting[value.toLowerCase()];
20336    return align ? value.toLowerCase() : false;
20337  }
20338
20339  function extend(obj) {
20340    var i = 1;
20341    for (; i < arguments.length; i++) {
20342      var cobj = arguments[i];
20343      for (var p in cobj) {
20344        obj[p] = cobj[p];
20345      }
20346    }
20347
20348    return obj;
20349  }
20350
20351  function VTTCue(startTime, endTime, text) {
20352    var cue = this;
20353    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
20354    var baseObj = {};
20355
20356    if (isIE8) {
20357      cue = document.createElement('custom');
20358    } else {
20359      baseObj.enumerable = true;
20360    }
20361
20362    /**
20363     * Shim implementation specific properties. These properties are not in
20364     * the spec.
20365     */
20366
20367    // Lets us know when the VTTCue's data has changed in such a way that we need
20368    // to recompute its display state. This lets us compute its display state
20369    // lazily.
20370    cue.hasBeenReset = false;
20371
20372    /**
20373     * VTTCue and TextTrackCue properties
20374     * http://dev.w3.org/html5/webvtt/#vttcue-interface
20375     */
20376
20377    var _id = "";
20378    var _pauseOnExit = false;
20379    var _startTime = startTime;
20380    var _endTime = endTime;
20381    var _text = text;
20382    var _region = null;
20383    var _vertical = "";
20384    var _snapToLines = true;
20385    var _line = "auto";
20386    var _lineAlign = "start";
20387    var _position = 50;
20388    var _positionAlign = "middle";
20389    var _size = 50;
20390    var _align = "middle";
20391
20392    Object.defineProperty(cue,
20393      "id", extend({}, baseObj, {
20394        get: function() {
20395          return _id;
20396        },
20397        set: function(value) {
20398          _id = "" + value;
20399        }
20400      }));
20401
20402    Object.defineProperty(cue,
20403      "pauseOnExit", extend({}, baseObj, {
20404        get: function() {
20405          return _pauseOnExit;
20406        },
20407        set: function(value) {
20408          _pauseOnExit = !!value;
20409        }
20410      }));
20411
20412    Object.defineProperty(cue,
20413      "startTime", extend({}, baseObj, {
20414        get: function() {
20415          return _startTime;
20416        },
20417        set: function(value) {
20418          if (typeof value !== "number") {
20419            throw new TypeError("Start time must be set to a number.");
20420          }
20421          _startTime = value;
20422          this.hasBeenReset = true;
20423        }
20424      }));
20425
20426    Object.defineProperty(cue,
20427      "endTime", extend({}, baseObj, {
20428        get: function() {
20429          return _endTime;
20430        },
20431        set: function(value) {
20432          if (typeof value !== "number") {
20433            throw new TypeError("End time must be set to a number.");
20434          }
20435          _endTime = value;
20436          this.hasBeenReset = true;
20437        }
20438      }));
20439
20440    Object.defineProperty(cue,
20441      "text", extend({}, baseObj, {
20442        get: function() {
20443          return _text;
20444        },
20445        set: function(value) {
20446          _text = "" + value;
20447          this.hasBeenReset = true;
20448        }
20449      }));
20450
20451    Object.defineProperty(cue,
20452      "region", extend({}, baseObj, {
20453        get: function() {
20454          return _region;
20455        },
20456        set: function(value) {
20457          _region = value;
20458          this.hasBeenReset = true;
20459        }
20460      }));
20461
20462    Object.defineProperty(cue,
20463      "vertical", extend({}, baseObj, {
20464        get: function() {
20465          return _vertical;
20466        },
20467        set: function(value) {
20468          var setting = findDirectionSetting(value);
20469          // Have to check for false because the setting an be an empty string.
20470          if (setting === false) {
20471            throw new SyntaxError("An invalid or illegal string was specified.");
20472          }
20473          _vertical = setting;
20474          this.hasBeenReset = true;
20475        }
20476      }));
20477
20478    Object.defineProperty(cue,
20479      "snapToLines", extend({}, baseObj, {
20480        get: function() {
20481          return _snapToLines;
20482        },
20483        set: function(value) {
20484          _snapToLines = !!value;
20485          this.hasBeenReset = true;
20486        }
20487      }));
20488
20489    Object.defineProperty(cue,
20490      "line", extend({}, baseObj, {
20491        get: function() {
20492          return _line;
20493        },
20494        set: function(value) {
20495          if (typeof value !== "number" && value !== autoKeyword) {
20496            throw new SyntaxError("An invalid number or illegal string was specified.");
20497          }
20498          _line = value;
20499          this.hasBeenReset = true;
20500        }
20501      }));
20502
20503    Object.defineProperty(cue,
20504      "lineAlign", extend({}, baseObj, {
20505        get: function() {
20506          return _lineAlign;
20507        },
20508        set: function(value) {
20509          var setting = findAlignSetting(value);
20510          if (!setting) {
20511            throw new SyntaxError("An invalid or illegal string was specified.");
20512          }
20513          _lineAlign = setting;
20514          this.hasBeenReset = true;
20515        }
20516      }));
20517
20518    Object.defineProperty(cue,
20519      "position", extend({}, baseObj, {
20520        get: function() {
20521          return _position;
20522        },
20523        set: function(value) {
20524          if (value < 0 || value > 100) {
20525            throw new Error("Position must be between 0 and 100.");
20526          }
20527          _position = value;
20528          this.hasBeenReset = true;
20529        }
20530      }));
20531
20532    Object.defineProperty(cue,
20533      "positionAlign", extend({}, baseObj, {
20534        get: function() {
20535          return _positionAlign;
20536        },
20537        set: function(value) {
20538          var setting = findAlignSetting(value);
20539          if (!setting) {
20540            throw new SyntaxError("An invalid or illegal string was specified.");
20541          }
20542          _positionAlign = setting;
20543          this.hasBeenReset = true;
20544        }
20545      }));
20546
20547    Object.defineProperty(cue,
20548      "size", extend({}, baseObj, {
20549        get: function() {
20550          return _size;
20551        },
20552        set: function(value) {
20553          if (value < 0 || value > 100) {
20554            throw new Error("Size must be between 0 and 100.");
20555          }
20556          _size = value;
20557          this.hasBeenReset = true;
20558        }
20559      }));
20560
20561    Object.defineProperty(cue,
20562      "align", extend({}, baseObj, {
20563        get: function() {
20564          return _align;
20565        },
20566        set: function(value) {
20567          var setting = findAlignSetting(value);
20568          if (!setting) {
20569            throw new SyntaxError("An invalid or illegal string was specified.");
20570          }
20571          _align = setting;
20572          this.hasBeenReset = true;
20573        }
20574      }));
20575
20576    /**
20577     * Other <track> spec defined properties
20578     */
20579
20580    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
20581    cue.displayState = undefined;
20582
20583    if (isIE8) {
20584      return cue;
20585    }
20586  }
20587
20588  /**
20589   * VTTCue methods
20590   */
20591
20592  VTTCue.prototype.getCueAsHTML = function() {
20593    // Assume WebVTT.convertCueToDOMTree is on the global.
20594    return WebVTT.convertCueToDOMTree(window, this.text);
20595  };
20596
20597  root.VTTCue = root.VTTCue || VTTCue;
20598  vttjs.VTTCue = VTTCue;
20599}(this, (this.vttjs || {})));
20600
20601/**
20602 * Copyright 2013 vtt.js Contributors
20603 *
20604 * Licensed under the Apache License, Version 2.0 (the "License");
20605 * you may not use this file except in compliance with the License.
20606 * You may obtain a copy of the License at
20607 *
20608 *   http://www.apache.org/licenses/LICENSE-2.0
20609 *
20610 * Unless required by applicable law or agreed to in writing, software
20611 * distributed under the License is distributed on an "AS IS" BASIS,
20612 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20613 * See the License for the specific language governing permissions and
20614 * limitations under the License.
20615 */
20616
20617(function(root, vttjs) {
20618
20619  var scrollSetting = {
20620    "": true,
20621    "up": true
20622  };
20623
20624  function findScrollSetting(value) {
20625    if (typeof value !== "string") {
20626      return false;
20627    }
20628    var scroll = scrollSetting[value.toLowerCase()];
20629    return scroll ? value.toLowerCase() : false;
20630  }
20631
20632  function isValidPercentValue(value) {
20633    return typeof value === "number" && (value >= 0 && value <= 100);
20634  }
20635
20636  // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
20637  function VTTRegion() {
20638    var _width = 100;
20639    var _lines = 3;
20640    var _regionAnchorX = 0;
20641    var _regionAnchorY = 100;
20642    var _viewportAnchorX = 0;
20643    var _viewportAnchorY = 100;
20644    var _scroll = "";
20645
20646    Object.defineProperties(this, {
20647      "width": {
20648        enumerable: true,
20649        get: function() {
20650          return _width;
20651        },
20652        set: function(value) {
20653          if (!isValidPercentValue(value)) {
20654            throw new Error("Width must be between 0 and 100.");
20655          }
20656          _width = value;
20657        }
20658      },
20659      "lines": {
20660        enumerable: true,
20661        get: function() {
20662          return _lines;
20663        },
20664        set: function(value) {
vendor: 16,471 bytes, lines 20665-21169
20665          if (typeof value !== "number") {
20666            throw new TypeError("Lines must be set to a number.");
20667          }
20668          _lines = value;
20669        }
20670      },
20671      "regionAnchorY": {
20672        enumerable: true,
20673        get: function() {
20674          return _regionAnchorY;
20675        },
20676        set: function(value) {
20677          if (!isValidPercentValue(value)) {
20678            throw new Error("RegionAnchorX must be between 0 and 100.");
20679          }
20680          _regionAnchorY = value;
20681        }
20682      },
20683      "regionAnchorX": {
20684        enumerable: true,
20685        get: function() {
20686          return _regionAnchorX;
20687        },
20688        set: function(value) {
20689          if(!isValidPercentValue(value)) {
20690            throw new Error("RegionAnchorY must be between 0 and 100.");
20691          }
20692          _regionAnchorX = value;
20693        }
20694      },
20695      "viewportAnchorY": {
20696        enumerable: true,
20697        get: function() {
20698          return _viewportAnchorY;
20699        },
20700        set: function(value) {
20701          if (!isValidPercentValue(value)) {
20702            throw new Error("ViewportAnchorY must be between 0 and 100.");
20703          }
20704          _viewportAnchorY = value;
20705        }
20706      },
20707      "viewportAnchorX": {
20708        enumerable: true,
20709        get: function() {
20710          return _viewportAnchorX;
20711        },
20712        set: function(value) {
20713          if (!isValidPercentValue(value)) {
20714            throw new Error("ViewportAnchorX must be between 0 and 100.");
20715          }
20716          _viewportAnchorX = value;
20717        }
20718      },
20719      "scroll": {
20720        enumerable: true,
20721        get: function() {
20722          return _scroll;
20723        },
20724        set: function(value) {
20725          var setting = findScrollSetting(value);
20726          // Have to check for false as an empty string is a legal value.
20727          if (setting === false) {
20728            throw new SyntaxError("An invalid or illegal string was specified.");
20729          }
20730          _scroll = setting;
20731        }
20732      }
20733    });
20734  }
20735
20736  root.VTTRegion = root.VTTRegion || VTTRegion;
20737  vttjs.VTTRegion = VTTRegion;
20738}(this, (this.vttjs || {})));
20739
20740/**
20741 * Copyright 2013 vtt.js Contributors
20742 *
20743 * Licensed under the Apache License, Version 2.0 (the "License");
20744 * you may not use this file except in compliance with the License.
20745 * You may obtain a copy of the License at
20746 *
20747 *   http://www.apache.org/licenses/LICENSE-2.0
20748 *
20749 * Unless required by applicable law or agreed to in writing, software
20750 * distributed under the License is distributed on an "AS IS" BASIS,
20751 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20752 * See the License for the specific language governing permissions and
20753 * limitations under the License.
20754 */
20755
20756/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
20757/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
20758
20759(function(global) {
20760
20761  var _objCreate = Object.create || (function() {
20762    function F() {}
20763    return function(o) {
20764      if (arguments.length !== 1) {
20765        throw new Error('Object.create shim only accepts one parameter.');
20766      }
20767      F.prototype = o;
20768      return new F();
20769    };
20770  })();
20771
20772  // Creates a new ParserError object from an errorData object. The errorData
20773  // object should have default code and message properties. The default message
20774  // property can be overriden by passing in a message parameter.
20775  // See ParsingError.Errors below for acceptable errors.
20776  function ParsingError(errorData, message) {
20777    this.name = "ParsingError";
20778    this.code = errorData.code;
20779    this.message = message || errorData.message;
20780  }
20781  ParsingError.prototype = _objCreate(Error.prototype);
20782  ParsingError.prototype.constructor = ParsingError;
20783
20784  // ParsingError metadata for acceptable ParsingErrors.
20785  ParsingError.Errors = {
20786    BadSignature: {
20787      code: 0,
20788      message: "Malformed WebVTT signature."
20789    },
20790    BadTimeStamp: {
20791      code: 1,
20792      message: "Malformed time stamp."
20793    }
20794  };
20795
20796  // Try to parse input as a time stamp.
20797  function parseTimeStamp(input) {
20798
20799    function computeSeconds(h, m, s, f) {
20800      return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
20801    }
20802
20803    var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
20804    if (!m) {
20805      return null;
20806    }
20807
20808    if (m[3]) {
20809      // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
20810      return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
20811    } else if (m[1] > 59) {
20812      // Timestamp takes the form of [hours]:[minutes].[milliseconds]
20813      // First position is hours as it's over 59.
20814      return computeSeconds(m[1], m[2], 0,  m[4]);
20815    } else {
20816      // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
20817      return computeSeconds(0, m[1], m[2], m[4]);
20818    }
20819  }
20820
20821  // A settings object holds key/value pairs and will ignore anything but the first
20822  // assignment to a specific key.
20823  function Settings() {
20824    this.values = _objCreate(null);
20825  }
20826
20827  Settings.prototype = {
20828    // Only accept the first assignment to any key.
20829    set: function(k, v) {
20830      if (!this.get(k) && v !== "") {
20831        this.values[k] = v;
20832      }
20833    },
20834    // Return the value for a key, or a default value.
20835    // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
20836    // a number of possible default values as properties where 'defaultKey' is
20837    // the key of the property that will be chosen; otherwise it's assumed to be
20838    // a single value.
20839    get: function(k, dflt, defaultKey) {
20840      if (defaultKey) {
20841        return this.has(k) ? this.values[k] : dflt[defaultKey];
20842      }
20843      return this.has(k) ? this.values[k] : dflt;
20844    },
20845    // Check whether we have a value for a key.
20846    has: function(k) {
20847      return k in this.values;
20848    },
20849    // Accept a setting if its one of the given alternatives.
20850    alt: function(k, v, a) {
20851      for (var n = 0; n < a.length; ++n) {
20852        if (v === a[n]) {
20853          this.set(k, v);
20854          break;
20855        }
20856      }
20857    },
20858    // Accept a setting if its a valid (signed) integer.
20859    integer: function(k, v) {
20860      if (/^-?\d+$/.test(v)) { // integer
20861        this.set(k, parseInt(v, 10));
20862      }
20863    },
20864    // Accept a setting if its a valid percentage.
20865    percent: function(k, v) {
20866      var m;
20867      if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
20868        v = parseFloat(v);
20869        if (v >= 0 && v <= 100) {
20870          this.set(k, v);
20871          return true;
20872        }
20873      }
20874      return false;
20875    }
20876  };
20877
20878  // Helper function to parse input into groups separated by 'groupDelim', and
20879  // interprete each group as a key/value pair separated by 'keyValueDelim'.
20880  function parseOptions(input, callback, keyValueDelim, groupDelim) {
20881    var groups = groupDelim ? input.split(groupDelim) : [input];
20882    for (var i in groups) {
20883      if (typeof groups[i] !== "string") {
20884        continue;
20885      }
20886      var kv = groups[i].split(keyValueDelim);
20887      if (kv.length !== 2) {
20888        continue;
20889      }
20890      var k = kv[0];
20891      var v = kv[1];
20892      callback(k, v);
20893    }
20894  }
20895
20896  function parseCue(input, cue, regionList) {
20897    // Remember the original input if we need to throw an error.
20898    var oInput = input;
20899    // 4.1 WebVTT timestamp
20900    function consumeTimeStamp() {
20901      var ts = parseTimeStamp(input);
20902      if (ts === null) {
20903        throw new ParsingError(ParsingError.Errors.BadTimeStamp,
20904                              "Malformed timestamp: " + oInput);
20905      }
20906      // Remove time stamp from input.
20907      input = input.replace(/^[^\sa-zA-Z-]+/, "");
20908      return ts;
20909    }
20910
20911    // 4.4.2 WebVTT cue settings
20912    function consumeCueSettings(input, cue) {
20913      var settings = new Settings();
20914
20915      parseOptions(input, function (k, v) {
20916        switch (k) {
20917        case "region":
20918          // Find the last region we parsed with the same region id.
20919          for (var i = regionList.length - 1; i >= 0; i--) {
20920            if (regionList[i].id === v) {
20921              settings.set(k, regionList[i].region);
20922              break;
20923            }
20924          }
20925          break;
20926        case "vertical":
20927          settings.alt(k, v, ["rl", "lr"]);
20928          break;
20929        case "line":
20930          var vals = v.split(","),
20931              vals0 = vals[0];
20932          settings.integer(k, vals0);
20933          settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
20934          settings.alt(k, vals0, ["auto"]);
20935          if (vals.length === 2) {
20936            settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
20937          }
20938          break;
20939        case "position":
20940          vals = v.split(",");
20941          settings.percent(k, vals[0]);
20942          if (vals.length === 2) {
20943            settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
20944          }
20945          break;
20946        case "size":
20947          settings.percent(k, v);
20948          break;
20949        case "align":
20950          settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
20951          break;
20952        }
20953      }, /:/, /\s/);
20954
20955      // Apply default values for any missing fields.
20956      cue.region = settings.get("region", null);
20957      cue.vertical = settings.get("vertical", "");
20958      cue.line = settings.get("line", "auto");
20959      cue.lineAlign = settings.get("lineAlign", "start");
20960      cue.snapToLines = settings.get("snapToLines", true);
20961      cue.size = settings.get("size", 100);
20962      cue.align = settings.get("align", "middle");
20963      cue.position = settings.get("position", {
20964        start: 0,
20965        left: 0,
20966        middle: 50,
20967        end: 100,
20968        right: 100
20969      }, cue.align);
20970      cue.positionAlign = settings.get("positionAlign", {
20971        start: "start",
20972        left: "start",
20973        middle: "middle",
20974        end: "end",
20975        right: "end"
20976      }, cue.align);
20977    }
20978
20979    function skipWhitespace() {
20980      input = input.replace(/^\s+/, "");
20981    }
20982
20983    // 4.1 WebVTT cue timings.
20984    skipWhitespace();
20985    cue.startTime = consumeTimeStamp();   // (1) collect cue start time
20986    skipWhitespace();
20987    if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
20988      throw new ParsingError(ParsingError.Errors.BadTimeStamp,
20989                             "Malformed time stamp (time stamps must be separated by '-->'): " +
20990                             oInput);
20991    }
20992    input = input.substr(3);
20993    skipWhitespace();
20994    cue.endTime = consumeTimeStamp();     // (5) collect cue end time
20995
20996    // 4.1 WebVTT cue settings list.
20997    skipWhitespace();
20998    consumeCueSettings(input, cue);
20999  }
21000
21001  var ESCAPE = {
21002    "&amp;": "&",
21003    "&lt;": "<",
21004    "&gt;": ">",
21005    "&lrm;": "\u200e",
21006    "&rlm;": "\u200f",
21007    "&nbsp;": "\u00a0"
21008  };
21009
21010  var TAG_NAME = {
21011    c: "span",
21012    i: "i",
21013    b: "b",
21014    u: "u",
21015    ruby: "ruby",
21016    rt: "rt",
21017    v: "span",
21018    lang: "span"
21019  };
21020
21021  var TAG_ANNOTATION = {
21022    v: "title",
21023    lang: "lang"
21024  };
21025
21026  var NEEDS_PARENT = {
21027    rt: "ruby"
21028  };
21029
21030  // Parse content into a document fragment.
21031  function parseContent(window, input) {
21032    function nextToken() {
21033      // Check for end-of-string.
21034      if (!input) {
21035        return null;
21036      }
21037
21038      // Consume 'n' characters from the input.
21039      function consume(result) {
21040        input = input.substr(result.length);
21041        return result;
21042      }
21043
21044      var m = input.match(/^([^<]*)(<[^>]+>?)?/);
21045      // If there is some text before the next tag, return it, otherwise return
21046      // the tag.
21047      return consume(m[1] ? m[1] : m[2]);
21048    }
21049
21050    // Unescape a string 's'.
21051    function unescape1(e) {
21052      return ESCAPE[e];
21053    }
21054    function unescape(s) {
21055      while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
21056        s = s.replace(m[0], unescape1);
21057      }
21058      return s;
21059    }
21060
21061    function shouldAdd(current, element) {
21062      return !NEEDS_PARENT[element.localName] ||
21063             NEEDS_PARENT[element.localName] === current.localName;
21064    }
21065
21066    // Create an element for this tag.
21067    function createElement(type, annotation) {
21068      var tagName = TAG_NAME[type];
21069      if (!tagName) {
21070        return null;
21071      }
21072      var element = window.document.createElement(tagName);
21073      element.localName = tagName;
21074      var name = TAG_ANNOTATION[type];
21075      if (name && annotation) {
21076        element[name] = annotation.trim();
21077      }
21078      return element;
21079    }
21080
21081    var rootDiv = window.document.createElement("div"),
21082        current = rootDiv,
21083        t,
21084        tagStack = [];
21085
21086    while ((t = nextToken()) !== null) {
21087      if (t[0] === '<') {
21088        if (t[1] === "/") {
21089          // If the closing tag matches, move back up to the parent node.
21090          if (tagStack.length &&
21091              tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
21092            tagStack.pop();
21093            current = current.parentNode;
21094          }
21095          // Otherwise just ignore the end tag.
21096          continue;
21097        }
21098        var ts = parseTimeStamp(t.substr(1, t.length - 2));
21099        var node;
21100        if (ts) {
21101          // Timestamps are lead nodes as well.
21102          node = window.document.createProcessingInstruction("timestamp", ts);
21103          current.appendChild(node);
21104          continue;
21105        }
21106        var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
21107        // If we can't parse the tag, skip to the next tag.
21108        if (!m) {
21109          continue;
21110        }
21111        // Try to construct an element, and ignore the tag if we couldn't.
21112        node = createElement(m[1], m[3]);
21113        if (!node) {
21114          continue;
21115        }
21116        // Determine if the tag should be added based on the context of where it
21117        // is placed in the cuetext.
21118        if (!shouldAdd(current, node)) {
21119          continue;
21120        }
21121        // Set the class list (as a list of classes, separated by space).
21122        if (m[2]) {
21123          node.className = m[2].substr(1).replace('.', ' ');
21124        }
21125        // Append the node to the current node, and enter the scope of the new
21126        // node.
21127        tagStack.push(m[1]);
21128        current.appendChild(node);
21129        current = node;
21130        continue;
21131      }
21132
21133      // Text nodes are leaf nodes.
21134      current.appendChild(window.document.createTextNode(unescape(t)));
21135    }
21136
21137    return rootDiv;
21138  }
21139
21140  // This is a list of all the Unicode characters that have a strong
21141  // right-to-left category. What this means is that these characters are
21142  // written right-to-left for sure. It was generated by pulling all the strong
21143  // right-to-left characters out of the Unicode data table. That table can
21144  // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
21145  var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
21146      0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
21147      0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
21148      0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
21149      0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
21150      0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
21151      0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
21152      0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
21153      0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
21154      0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
21155      0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
21156      0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
21157      0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
21158      0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
21159      0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
21160      0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
21161      0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
21162      0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
21163      0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
21164      0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
21165      0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
21166      0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
21167      0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
21168      0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
21169      0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
21170      0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
21171      0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
21172      0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
21173      0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
21174      0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
21175      0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
21176      0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
21177      0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
21178      0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
21179      0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
21180      0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
21181      0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
21182      0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
21183      0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
21184      0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
21185      0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
21186      0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
21187      0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
21188      0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
21189      0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
21190      0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
21191      0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
21192      0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
21193      0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
21194      0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
21195      0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
21196      0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
21197      0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
21198      0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
21199      0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
21200      0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
21201      0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
21202      0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
21203      0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
21204      0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
21205      0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
21206      0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
21207      0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
21208      0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
21209      0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
21210      0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
21211      0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
21212      0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
21213      0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
21214      0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
21215      0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
21216      0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
21217      0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
21218      0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
21219      0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
21220      0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
21221      0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
21222      0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
21223      0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
21224      0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
21225      0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
21226      0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
21227      0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
21228      0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
21229      0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
21230      0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
21231      0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
21232      0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
21233      0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
21234      0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
21235      0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
21236      0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
21237      0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
21238      0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
21239      0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
21240      0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
21241      0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
21242      0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
21243      0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
21244      0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
21245      0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
21246      0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
21247      0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
21248      0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
21249      0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
21250      0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
21251      0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
21252      0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
21253      0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
21254      0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
21255      0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
21256      0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
21257      0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
21258      0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
21259      0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
21260      0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
21261      0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
21262      0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
21263      0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
21264      0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
21265      0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
21266      0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
21267      0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
21268      0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
21269      0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
21270      0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
21271      0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
21272      0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
21273      0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
21274      0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
21275      0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
21276      0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
21277      0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
21278      0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
21279      0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
21280      0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
21281      0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
21282      0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
21283      0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
21284      0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
21285      0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
21286      0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
21287      0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
21288      0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
21289      0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
21290      0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
21291      0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
21292      0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
21293      0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
21294      0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
21295      0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
21296      0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
21297      0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
21298      0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
21299      0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
21300      0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
21301      0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
21302      0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
21303      0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
21304      0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
21305      0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
21306      0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
21307      0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
21308      0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
21309      0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
21310      0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
21311      0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
21312      0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
21313      0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
21314      0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
21315      0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
21316      0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
21317      0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
21318      0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
21319      0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
21320      0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
21321      0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
21322      0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
21323      0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
21324      0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
21325      0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
21326      0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
21327      0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
21328      0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
21329      0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
21330      0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
21331      0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
21332      0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
21333      0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
21334      0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
21335      0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
21336      0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
21337      0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
21338      0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
21339      0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
21340      0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
21341      0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
21342      0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
21343      0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
21344      0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
21345      0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
21346      0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
21347      0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
21348      0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
21349      0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
21350      0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
21351      0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
21352      0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
21353      0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
21354      0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
21355      0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
21356      0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
21357      0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
21358      0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
21359      0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
21360      0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];
21361
21362  function determineBidi(cueDiv) {
21363    var nodeStack = [],
21364        text = "",
vendor: 6,425 bytes, lines 21365-21568
21365        charCode;
21366
21367    if (!cueDiv || !cueDiv.childNodes) {
21368      return "ltr";
21369    }
21370
21371    function pushNodes(nodeStack, node) {
21372      for (var i = node.childNodes.length - 1; i >= 0; i--) {
21373        nodeStack.push(node.childNodes[i]);
21374      }
21375    }
21376
21377    function nextTextNode(nodeStack) {
21378      if (!nodeStack || !nodeStack.length) {
21379        return null;
21380      }
21381
21382      var node = nodeStack.pop(),
21383          text = node.textContent || node.innerText;
21384      if (text) {
21385        // TODO: This should match all unicode type B characters (paragraph
21386        // separator characters). See issue #115.
21387        var m = text.match(/^.*(\n|\r)/);
21388        if (m) {
21389          nodeStack.length = 0;
21390          return m[0];
21391        }
21392        return text;
21393      }
21394      if (node.tagName === "ruby") {
21395        return nextTextNode(nodeStack);
21396      }
21397      if (node.childNodes) {
21398        pushNodes(nodeStack, node);
21399        return nextTextNode(nodeStack);
21400      }
21401    }
21402
21403    pushNodes(nodeStack, cueDiv);
21404    while ((text = nextTextNode(nodeStack))) {
21405      for (var i = 0; i < text.length; i++) {
21406        charCode = text.charCodeAt(i);
21407        for (var j = 0; j < strongRTLChars.length; j++) {
21408          if (strongRTLChars[j] === charCode) {
21409            return "rtl";
21410          }
21411        }
21412      }
21413    }
21414    return "ltr";
21415  }
21416
21417  function computeLinePos(cue) {
21418    if (typeof cue.line === "number" &&
21419        (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
21420      return cue.line;
21421    }
21422    if (!cue.track || !cue.track.textTrackList ||
21423        !cue.track.textTrackList.mediaElement) {
21424      return -1;
21425    }
21426    var track = cue.track,
21427        trackList = track.textTrackList,
21428        count = 0;
21429    for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
21430      if (trackList[i].mode === "showing") {
21431        count++;
21432      }
21433    }
21434    return ++count * -1;
21435  }
21436
21437  function StyleBox() {
21438  }
21439
21440  // Apply styles to a div. If there is no div passed then it defaults to the
21441  // div on 'this'.
21442  StyleBox.prototype.applyStyles = function(styles, div) {
21443    div = div || this.div;
21444    for (var prop in styles) {
21445      if (styles.hasOwnProperty(prop)) {
21446        div.style[prop] = styles[prop];
21447      }
21448    }
21449  };
21450
21451  StyleBox.prototype.formatStyle = function(val, unit) {
21452    return val === 0 ? 0 : val + unit;
21453  };
21454
21455  // Constructs the computed display state of the cue (a div). Places the div
21456  // into the overlay which should be a block level element (usually a div).
21457  function CueStyleBox(window, cue, styleOptions) {
21458    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
21459    var color = "rgba(255, 255, 255, 1)";
21460    var backgroundColor = "rgba(0, 0, 0, 0.8)";
21461
21462    if (isIE8) {
21463      color = "rgb(255, 255, 255)";
21464      backgroundColor = "rgb(0, 0, 0)";
21465    }
21466
21467    StyleBox.call(this);
21468    this.cue = cue;
21469
21470    // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
21471    // have inline positioning and will function as the cue background box.
21472    this.cueDiv = parseContent(window, cue.text);
21473    var styles = {
21474      color: color,
21475      backgroundColor: backgroundColor,
21476      position: "relative",
21477      left: 0,
21478      right: 0,
21479      top: 0,
21480      bottom: 0,
21481      display: "inline"
21482    };
21483
21484    if (!isIE8) {
21485      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
21486                                               : cue.vertical === "lr" ? "vertical-lr"
21487                                                                       : "vertical-rl";
21488      styles.unicodeBidi = "plaintext";
21489    }
21490    this.applyStyles(styles, this.cueDiv);
21491
21492    // Create an absolutely positioned div that will be used to position the cue
21493    // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
21494    // mirrors of them except "middle" which is "center" in CSS.
21495    this.div = window.document.createElement("div");
21496    styles = {
21497      textAlign: cue.align === "middle" ? "center" : cue.align,
21498      font: styleOptions.font,
21499      whiteSpace: "pre-line",
21500      position: "absolute"
21501    };
21502
21503    if (!isIE8) {
21504      styles.direction = determineBidi(this.cueDiv);
21505      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
21506                                               : cue.vertical === "lr" ? "vertical-lr"
21507                                                                       : "vertical-rl".
21508      stylesunicodeBidi =  "plaintext";
21509    }
21510
21511    this.applyStyles(styles);
21512
21513    this.div.appendChild(this.cueDiv);
21514
21515    // Calculate the distance from the reference edge of the viewport to the text
21516    // position of the cue box. The reference edge will be resolved later when
21517    // the box orientation styles are applied.
21518    var textPos = 0;
21519    switch (cue.positionAlign) {
21520    case "start":
21521      textPos = cue.position;
21522      break;
21523    case "middle":
21524      textPos = cue.position - (cue.size / 2);
21525      break;
21526    case "end":
21527      textPos = cue.position - cue.size;
21528      break;
21529    }
21530
21531    // Horizontal box orientation; textPos is the distance from the left edge of the
21532    // area to the left edge of the box and cue.size is the distance extending to
21533    // the right from there.
21534    if (cue.vertical === "") {
21535      this.applyStyles({
21536        left:  this.formatStyle(textPos, "%"),
21537        width: this.formatStyle(cue.size, "%")
21538      });
21539    // Vertical box orientation; textPos is the distance from the top edge of the
21540    // area to the top edge of the box and cue.size is the height extending
21541    // downwards from there.
21542    } else {
21543      this.applyStyles({
21544        top: this.formatStyle(textPos, "%"),
21545        height: this.formatStyle(cue.size, "%")
21546      });
21547    }
21548
21549    this.move = function(box) {
21550      this.applyStyles({
21551        top: this.formatStyle(box.top, "px"),
21552        bottom: this.formatStyle(box.bottom, "px"),
21553        left: this.formatStyle(box.left, "px"),
21554        right: this.formatStyle(box.right, "px"),
21555        height: this.formatStyle(box.height, "px"),
21556        width: this.formatStyle(box.width, "px")
21557      });
21558    };
21559  }
21560  CueStyleBox.prototype = _objCreate(StyleBox.prototype);
21561  CueStyleBox.prototype.constructor = CueStyleBox;
21562
21563  // Represents the co-ordinates of an Element in a way that we can easily
21564  // compute things with such as if it overlaps or intersects with another Element.
21565  // Can initialize it with either a StyleBox or another BoxPosition.
21566  function BoxPosition(obj) {
21567    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
21568
vendor: 11,730 bytes, lines 21569-21906
21569    // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
21570    // was passed in and we need to copy the results of 'getBoundingClientRect'
21571    // as the object returned is readonly. All co-ordinate values are in reference
21572    // to the viewport origin (top left).
21573    var lh, height, width, top;
21574    if (obj.div) {
21575      height = obj.div.offsetHeight;
21576      width = obj.div.offsetWidth;
21577      top = obj.div.offsetTop;
21578
21579      var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
21580                  rects.getClientRects && rects.getClientRects();
21581      obj = obj.div.getBoundingClientRect();
21582      // In certain cases the outter div will be slightly larger then the sum of
21583      // the inner div's lines. This could be due to bold text, etc, on some platforms.
21584      // In this case we should get the average line height and use that. This will
21585      // result in the desired behaviour.
21586      lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
21587                 : 0;
21588
21589    }
21590    this.left = obj.left;
21591    this.right = obj.right;
21592    this.top = obj.top || top;
21593    this.height = obj.height || height;
21594    this.bottom = obj.bottom || (top + (obj.height || height));
21595    this.width = obj.width || width;
21596    this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
21597
21598    if (isIE8 && !this.lineHeight) {
21599      this.lineHeight = 13;
21600    }
21601  }
21602
21603  // Move the box along a particular axis. Optionally pass in an amount to move
21604  // the box. If no amount is passed then the default is the line height of the
21605  // box.
21606  BoxPosition.prototype.move = function(axis, toMove) {
21607    toMove = toMove !== undefined ? toMove : this.lineHeight;
21608    switch (axis) {
21609    case "+x":
21610      this.left += toMove;
21611      this.right += toMove;
21612      break;
21613    case "-x":
21614      this.left -= toMove;
21615      this.right -= toMove;
21616      break;
21617    case "+y":
21618      this.top += toMove;
21619      this.bottom += toMove;
21620      break;
21621    case "-y":
21622      this.top -= toMove;
21623      this.bottom -= toMove;
21624      break;
21625    }
21626  };
21627
21628  // Check if this box overlaps another box, b2.
21629  BoxPosition.prototype.overlaps = function(b2) {
21630    return this.left < b2.right &&
21631           this.right > b2.left &&
21632           this.top < b2.bottom &&
21633           this.bottom > b2.top;
21634  };
21635
21636  // Check if this box overlaps any other boxes in boxes.
21637  BoxPosition.prototype.overlapsAny = function(boxes) {
21638    for (var i = 0; i < boxes.length; i++) {
21639      if (this.overlaps(boxes[i])) {
21640        return true;
21641      }
21642    }
21643    return false;
21644  };
21645
21646  // Check if this box is within another box.
21647  BoxPosition.prototype.within = function(container) {
21648    return this.top >= container.top &&
21649           this.bottom <= container.bottom &&
21650           this.left >= container.left &&
21651           this.right <= container.right;
21652  };
21653
21654  // Check if this box is entirely within the container or it is overlapping
21655  // on the edge opposite of the axis direction passed. For example, if "+x" is
21656  // passed and the box is overlapping on the left edge of the container, then
21657  // return true.
21658  BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
21659    switch (axis) {
21660    case "+x":
21661      return this.left < container.left;
21662    case "-x":
21663      return this.right > container.right;
21664    case "+y":
21665      return this.top < container.top;
21666    case "-y":
21667      return this.bottom > container.bottom;
21668    }
21669  };
21670
21671  // Find the percentage of the area that this box is overlapping with another
21672  // box.
21673  BoxPosition.prototype.intersectPercentage = function(b2) {
21674    var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
21675        y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
21676        intersectArea = x * y;
21677    return intersectArea / (this.height * this.width);
21678  };
21679
21680  // Convert the positions from this box to CSS compatible positions using
21681  // the reference container's positions. This has to be done because this
21682  // box's positions are in reference to the viewport origin, whereas, CSS
21683  // values are in referecne to their respective edges.
21684  BoxPosition.prototype.toCSSCompatValues = function(reference) {
21685    return {
21686      top: this.top - reference.top,
21687      bottom: reference.bottom - this.bottom,
21688      left: this.left - reference.left,
21689      right: reference.right - this.right,
21690      height: this.height,
21691      width: this.width
21692    };
21693  };
21694
21695  // Get an object that represents the box's position without anything extra.
21696  // Can pass a StyleBox, HTMLElement, or another BoxPositon.
21697  BoxPosition.getSimpleBoxPosition = function(obj) {
21698    var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
21699    var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
21700    var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
21701
21702    obj = obj.div ? obj.div.getBoundingClientRect() :
21703                  obj.tagName ? obj.getBoundingClientRect() : obj;
21704    var ret = {
21705      left: obj.left,
21706      right: obj.right,
21707      top: obj.top || top,
21708      height: obj.height || height,
21709      bottom: obj.bottom || (top + (obj.height || height)),
21710      width: obj.width || width
21711    };
21712    return ret;
21713  };
21714
21715  // Move a StyleBox to its specified, or next best, position. The containerBox
21716  // is the box that contains the StyleBox, such as a div. boxPositions are
21717  // a list of other boxes that the styleBox can't overlap with.
21718  function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
21719
21720    // Find the best position for a cue box, b, on the video. The axis parameter
21721    // is a list of axis, the order of which, it will move the box along. For example:
21722    // Passing ["+x", "-x"] will move the box first along the x axis in the positive
21723    // direction. If it doesn't find a good position for it there it will then move
21724    // it along the x axis in the negative direction.
21725    function findBestPosition(b, axis) {
21726      var bestPosition,
21727          specifiedPosition = new BoxPosition(b),
21728          percentage = 1; // Highest possible so the first thing we get is better.
21729
21730      for (var i = 0; i < axis.length; i++) {
21731        while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
21732               (b.within(containerBox) && b.overlapsAny(boxPositions))) {
21733          b.move(axis[i]);
21734        }
21735        // We found a spot where we aren't overlapping anything. This is our
21736        // best position.
21737        if (b.within(containerBox)) {
21738          return b;
21739        }
21740        var p = b.intersectPercentage(containerBox);
21741        // If we're outside the container box less then we were on our last try
21742        // then remember this position as the best position.
21743        if (percentage > p) {
21744          bestPosition = new BoxPosition(b);
21745          percentage = p;
21746        }
21747        // Reset the box position to the specified position.
21748        b = new BoxPosition(specifiedPosition);
21749      }
21750      return bestPosition || specifiedPosition;
21751    }
21752
21753    var boxPosition = new BoxPosition(styleBox),
21754        cue = styleBox.cue,
21755        linePos = computeLinePos(cue),
21756        axis = [];
21757
21758    // If we have a line number to align the cue to.
21759    if (cue.snapToLines) {
21760      var size;
21761      switch (cue.vertical) {
21762      case "":
21763        axis = [ "+y", "-y" ];
21764        size = "height";
21765        break;
21766      case "rl":
21767        axis = [ "+x", "-x" ];
21768        size = "width";
21769        break;
21770      case "lr":
21771        axis = [ "-x", "+x" ];
21772        size = "width";
21773        break;
21774      }
21775
21776      var step = boxPosition.lineHeight,
21777          position = step * Math.round(linePos),
21778          maxPosition = containerBox[size] + step,
21779          initialAxis = axis[0];
21780
21781      // If the specified intial position is greater then the max position then
21782      // clamp the box to the amount of steps it would take for the box to
21783      // reach the max position.
21784      if (Math.abs(position) > maxPosition) {
21785        position = position < 0 ? -1 : 1;
21786        position *= Math.ceil(maxPosition / step) * step;
21787      }
21788
21789      // If computed line position returns negative then line numbers are
21790      // relative to the bottom of the video instead of the top. Therefore, we
21791      // need to increase our initial position by the length or width of the
21792      // video, depending on the writing direction, and reverse our axis directions.
21793      if (linePos < 0) {
21794        position += cue.vertical === "" ? containerBox.height : containerBox.width;
21795        axis = axis.reverse();
21796      }
21797
21798      // Move the box to the specified position. This may not be its best
21799      // position.
21800      boxPosition.move(initialAxis, position);
21801
21802    } else {
21803      // If we have a percentage line value for the cue.
21804      var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
21805
21806      switch (cue.lineAlign) {
21807      case "middle":
21808        linePos -= (calculatedPercentage / 2);
21809        break;
21810      case "end":
21811        linePos -= calculatedPercentage;
21812        break;
21813      }
21814
21815      // Apply initial line position to the cue box.
21816      switch (cue.vertical) {
21817      case "":
21818        styleBox.applyStyles({
21819          top: styleBox.formatStyle(linePos, "%")
21820        });
21821        break;
21822      case "rl":
21823        styleBox.applyStyles({
21824          left: styleBox.formatStyle(linePos, "%")
21825        });
21826        break;
21827      case "lr":
21828        styleBox.applyStyles({
21829          right: styleBox.formatStyle(linePos, "%")
21830        });
21831        break;
21832      }
21833
21834      axis = [ "+y", "-x", "+x", "-y" ];
21835
21836      // Get the box position again after we've applied the specified positioning
21837      // to it.
21838      boxPosition = new BoxPosition(styleBox);
21839    }
21840
21841    var bestPosition = findBestPosition(boxPosition, axis);
21842    styleBox.move(bestPosition.toCSSCompatValues(containerBox));
21843  }
21844
21845  function WebVTT() {
21846    // Nothing
21847  }
21848
21849  // Helper to allow strings to be decoded instead of the default binary utf8 data.
21850  WebVTT.StringDecoder = function() {
21851    return {
21852      decode: function(data) {
21853        if (!data) {
21854          return "";
21855        }
21856        if (typeof data !== "string") {
21857          throw new Error("Error - expected string data.");
21858        }
21859        return decodeURIComponent(encodeURIComponent(data));
21860      }
21861    };
21862  };
21863
21864  WebVTT.convertCueToDOMTree = function(window, cuetext) {
21865    if (!window || !cuetext) {
21866      return null;
21867    }
21868    return parseContent(window, cuetext);
21869  };
21870
21871  var FONT_SIZE_PERCENT = 0.05;
21872  var FONT_STYLE = "sans-serif";
21873  var CUE_BACKGROUND_PADDING = "1.5%";
21874
21875  // Runs the processing model over the cues and regions passed to it.
21876  // @param overlay A block level element (usually a div) that the computed cues
21877  //                and regions will be placed into.
21878  WebVTT.processCues = function(window, cues, overlay) {
21879    if (!window || !cues || !overlay) {
21880      return null;
21881    }
21882
21883    // Remove all previous children.
21884    while (overlay.firstChild) {
21885      overlay.removeChild(overlay.firstChild);
21886    }
21887
21888    var paddedOverlay = window.document.createElement("div");
21889    paddedOverlay.style.position = "absolute";
21890    paddedOverlay.style.left = "0";
21891    paddedOverlay.style.right = "0";
21892    paddedOverlay.style.top = "0";
21893    paddedOverlay.style.bottom = "0";
21894    paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
21895    overlay.appendChild(paddedOverlay);
21896
21897    // Determine if we need to compute the display states of the cues. This could
21898    // be the case if a cue's state has been changed since the last computation or
21899    // if it has not been computed yet.
21900    function shouldCompute(cues) {
21901      for (var i = 0; i < cues.length; i++) {
21902        if (cues[i].hasBeenReset || !cues[i].displayState) {
21903          return true;
21904        }
21905      }
21906      return false;
vendor: 9,362 bytes, lines 21907-22196
21907    }
21908
21909    // We don't need to recompute the cues' display states. Just reuse them.
21910    if (!shouldCompute(cues)) {
21911      for (var i = 0; i < cues.length; i++) {
21912        paddedOverlay.appendChild(cues[i].displayState);
21913      }
21914      return;
21915    }
21916
21917    var boxPositions = [],
21918        containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
21919        fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
21920    var styleOptions = {
21921      font: fontSize + "px " + FONT_STYLE
21922    };
21923
21924    (function() {
21925      var styleBox, cue;
21926
21927      for (var i = 0; i < cues.length; i++) {
21928        cue = cues[i];
21929
21930        // Compute the intial position and styles of the cue div.
21931        styleBox = new CueStyleBox(window, cue, styleOptions);
21932        paddedOverlay.appendChild(styleBox.div);
21933
21934        // Move the cue div to it's correct line position.
21935        moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
21936
21937        // Remember the computed div so that we don't have to recompute it later
21938        // if we don't have too.
21939        cue.displayState = styleBox.div;
21940
21941        boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
21942      }
21943    })();
21944  };
21945
21946  WebVTT.Parser = function(window, vttjs, decoder) {
21947    if (!decoder) {
21948      decoder = vttjs;
21949      vttjs = {};
21950    }
21951    if (!vttjs) {
21952      vttjs = {};
21953    }
21954
21955    this.window = window;
21956    this.vttjs = vttjs;
21957    this.state = "INITIAL";
21958    this.buffer = "";
21959    this.decoder = decoder || new TextDecoder("utf8");
21960    this.regionList = [];
21961  };
21962
21963  WebVTT.Parser.prototype = {
21964    // If the error is a ParsingError then report it to the consumer if
21965    // possible. If it's not a ParsingError then throw it like normal.
21966    reportOrThrowError: function(e) {
21967      if (e instanceof ParsingError) {
21968        this.onparsingerror && this.onparsingerror(e);
21969      } else {
21970        throw e;
21971      }
21972    },
21973    parse: function (data) {
21974      var self = this;
21975
21976      // If there is no data then we won't decode it, but will just try to parse
21977      // whatever is in buffer already. This may occur in circumstances, for
21978      // example when flush() is called.
21979      if (data) {
21980        // Try to decode the data that we received.
21981        self.buffer += self.decoder.decode(data, {stream: true});
21982      }
21983
21984      function collectNextLine() {
21985        var buffer = self.buffer;
21986        var pos = 0;
21987        while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
21988          ++pos;
21989        }
21990        var line = buffer.substr(0, pos);
21991        // Advance the buffer early in case we fail below.
21992        if (buffer[pos] === '\r') {
21993          ++pos;
21994        }
21995        if (buffer[pos] === '\n') {
21996          ++pos;
21997        }
21998        self.buffer = buffer.substr(pos);
21999        return line;
22000      }
22001
22002      // 3.4 WebVTT region and WebVTT region settings syntax
22003      function parseRegion(input) {
22004        var settings = new Settings();
22005
22006        parseOptions(input, function (k, v) {
22007          switch (k) {
22008          case "id":
22009            settings.set(k, v);
22010            break;
22011          case "width":
22012            settings.percent(k, v);
22013            break;
22014          case "lines":
22015            settings.integer(k, v);
22016            break;
22017          case "regionanchor":
22018          case "viewportanchor":
22019            var xy = v.split(',');
22020            if (xy.length !== 2) {
22021              break;
22022            }
22023            // We have to make sure both x and y parse, so use a temporary
22024            // settings object here.
22025            var anchor = new Settings();
22026            anchor.percent("x", xy[0]);
22027            anchor.percent("y", xy[1]);
22028            if (!anchor.has("x") || !anchor.has("y")) {
22029              break;
22030            }
22031            settings.set(k + "X", anchor.get("x"));
22032            settings.set(k + "Y", anchor.get("y"));
22033            break;
22034          case "scroll":
22035            settings.alt(k, v, ["up"]);
22036            break;
22037          }
22038        }, /=/, /\s/);
22039
22040        // Create the region, using default values for any values that were not
22041        // specified.
22042        if (settings.has("id")) {
22043          var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
22044          region.width = settings.get("width", 100);
22045          region.lines = settings.get("lines", 3);
22046          region.regionAnchorX = settings.get("regionanchorX", 0);
22047          region.regionAnchorY = settings.get("regionanchorY", 100);
22048          region.viewportAnchorX = settings.get("viewportanchorX", 0);
22049          region.viewportAnchorY = settings.get("viewportanchorY", 100);
22050          region.scroll = settings.get("scroll", "");
22051          // Register the region.
22052          self.onregion && self.onregion(region);
22053          // Remember the VTTRegion for later in case we parse any VTTCues that
22054          // reference it.
22055          self.regionList.push({
22056            id: settings.get("id"),
22057            region: region
22058          });
22059        }
22060      }
22061
22062      // 3.2 WebVTT metadata header syntax
22063      function parseHeader(input) {
22064        parseOptions(input, function (k, v) {
22065          switch (k) {
22066          case "Region":
22067            // 3.3 WebVTT region metadata header syntax
22068            parseRegion(v);
22069            break;
22070          }
22071        }, /:/);
22072      }
22073
22074      // 5.1 WebVTT file parsing.
22075      try {
22076        var line;
22077        if (self.state === "INITIAL") {
22078          // We can't start parsing until we have the first line.
22079          if (!/\r\n|\n/.test(self.buffer)) {
22080            return this;
22081          }
22082
22083          line = collectNextLine();
22084
22085          var m = line.match(/^WEBVTT([ \t].*)?$/);
22086          if (!m || !m[0]) {
22087            throw new ParsingError(ParsingError.Errors.BadSignature);
22088          }
22089
22090          self.state = "HEADER";
22091        }
22092
22093        var alreadyCollectedLine = false;
22094        while (self.buffer) {
22095          // We can't parse a line until we have the full line.
22096          if (!/\r\n|\n/.test(self.buffer)) {
22097            return this;
22098          }
22099
22100          if (!alreadyCollectedLine) {
22101            line = collectNextLine();
22102          } else {
22103            alreadyCollectedLine = false;
22104          }
22105
22106          switch (self.state) {
22107          case "HEADER":
22108            // 13-18 - Allow a header (metadata) under the WEBVTT line.
22109            if (/:/.test(line)) {
22110              parseHeader(line);
22111            } else if (!line) {
22112              // An empty line terminates the header and starts the body (cues).
22113              self.state = "ID";
22114            }
22115            continue;
22116          case "NOTE":
22117            // Ignore NOTE blocks.
22118            if (!line) {
22119              self.state = "ID";
22120            }
22121            continue;
22122          case "ID":
22123            // Check for the start of NOTE blocks.
22124            if (/^NOTE($|[ \t])/.test(line)) {
22125              self.state = "NOTE";
22126              break;
22127            }
22128            // 19-29 - Allow any number of line terminators, then initialize new cue values.
22129            if (!line) {
22130              continue;
22131            }
22132            self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
22133            self.state = "CUE";
22134            // 30-39 - Check if self line contains an optional identifier or timing data.
22135            if (line.indexOf("-->") === -1) {
22136              self.cue.id = line;
22137              continue;
22138            }
22139            // Process line as start of a cue.
22140            /*falls through*/
22141          case "CUE":
22142            // 40 - Collect cue timings and settings.
22143            try {
22144              parseCue(line, self.cue, self.regionList);
22145            } catch (e) {
22146              self.reportOrThrowError(e);
22147              // In case of an error ignore rest of the cue.
22148              self.cue = null;
22149              self.state = "BADCUE";
22150              continue;
22151            }
22152            self.state = "CUETEXT";
22153            continue;
22154          case "CUETEXT":
22155            var hasSubstring = line.indexOf("-->") !== -1;
22156            // 34 - If we have an empty line then report the cue.
22157            // 35 - If we have the special substring '-->' then report the cue,
22158            // but do not collect the line as we need to process the current
22159            // one as a new cue.
22160            if (!line || hasSubstring && (alreadyCollectedLine = true)) {
22161              // We are done parsing self cue.
22162              self.oncue && self.oncue(self.cue);
22163              self.cue = null;
22164              self.state = "ID";
22165              continue;
22166            }
22167            if (self.cue.text) {
22168              self.cue.text += "\n";
22169            }
22170            self.cue.text += line;
22171            continue;
22172          case "BADCUE": // BADCUE
22173            // 54-62 - Collect and discard the remaining cue.
22174            if (!line) {
22175              self.state = "ID";
22176            }
22177            continue;
22178          }
22179        }
22180      } catch (e) {
22181        self.reportOrThrowError(e);
22182
22183        // If we are currently parsing a cue, report what we have.
22184        if (self.state === "CUETEXT" && self.cue && self.oncue) {
22185          self.oncue(self.cue);
22186        }
22187        self.cue = null;
22188        // Enter BADWEBVTT state if header was not parsed correctly otherwise
22189        // another exception occurred so enter BADCUE state.
22190        self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
22191      }
22192      return this;
22193    },
22194    flush: function () {
22195      var self = this;
22196      try {
22197        // Finish decoding the stream.
22198        self.buffer += self.decoder.decode();
22199        // Synthesize the end of the current cue or region.
22200        if (self.cue || self.state === "HEADER") {
22201          self.buffer += "\n\n";
22202          self.parse();
22203        }
22204        // If we've flushed, parsed, and we're still on the INITIAL state then
22205        // that means we don't have enough of the stream to parse the first
22206        // line.
22207        if (self.state === "INITIAL") {
22208          throw new ParsingError(ParsingError.Errors.BadSignature);
22209        }
22210      } catch(e) {
22211        self.reportOrThrowError(e);
22212      }
22213      self.onflush && self.onflush();
22214      return this;
22215    }
22216  };
22217
22218  global.WebVTT = WebVTT;
22219
22220}(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.