Changeset 103728 in spip-zone


Ignore:
Timestamp:
Apr 2, 2017, 5:05:29 PM (2 years ago)
Author:
real3t@…
Message:

refs #3692 : Intégration de la library MediaElement? en 4.0.2

Testé sous Windows 10 avec Edge, FireFox? et Chrome en utilisant les .mp4, .ogg et .mp3 utilisés par http://www.mediaelementjs.com/

Pas testé les skins.

Location:
_core_/plugins/medias
Files:
16 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • _core_/plugins/medias/lib/mejs/mediaelement-and-player.js

    r95131 r103728  
    11/*!
    2 * MediaElement.js
    3 * HTML5 <video> and <audio> shim and player
    4 * http://mediaelementjs.com/
    5 *
    6 * Creates a JavaScript object that mimics HTML5 MediaElement API
    7 * for browsers that don't understand HTML5 or can't play the provided codec
    8 * Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3
    9 *
    10 * Copyright 2010-2014, John Dyer (http://j.hn)
    11 * License: MIT
    12 *
    13 */
     2 * MediaElement.js
     3 * http://www.mediaelementjs.com/
     4 *
     5 * Wrapper that mimics native HTML5 MediaElement (audio and video)
     6 * using a variety of technologies (pure JavaScript, Flash, iframe)
     7 *
     8 * Copyright 2010-2017, John Dyer (http://j.hn/)
     9 * License: MIT
     10 *
     11 */(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){
     12
     13},{}],2:[function(_dereq_,module,exports){
     14(function (global){
     15var topLevel = typeof global !== 'undefined' ? global :
     16    typeof window !== 'undefined' ? window : {}
     17var minDoc = _dereq_(1);
     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},{"1":1}],3:[function(_dereq_,module,exports){
     33(function (global){
     34if (typeof window !== "undefined") {
     35    module.exports = window;
     36} else if (typeof global !== "undefined") {
     37    module.exports = global;
     38} else if (typeof self !== "undefined"){
     39    module.exports = self;
     40} else {
     41    module.exports = {};
     42}
     43
     44}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
     45},{}],4:[function(_dereq_,module,exports){
     46'use strict';
     47
     48Object.defineProperty(exports, "__esModule", {
     49        value: true
     50});
     51
     52var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
     53
     54var _mejs = _dereq_(6);
     55
     56var _mejs2 = _interopRequireDefault(_mejs);
     57
     58var _en = _dereq_(14);
     59
     60var _general = _dereq_(25);
     61
     62function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     63
     64/**
     65 * Locale.
     66 *
     67 * This object manages translations with pluralization. Also deals with WordPress compatibility.
     68 * @type {Object}
     69 */
     70var i18n = { lang: 'en', en: _en.EN };
     71
     72/**
     73 * Language setter/getter
     74 *
     75 * @param {*} args  Can pass the language code and/or the translation strings as an Object
     76 * @return {string}
     77 */
     78i18n.language = function () {
     79        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
     80                args[_key] = arguments[_key];
     81        }
     82
     83        if (args !== null && args !== undefined && args.length) {
     84
     85                if (typeof args[0] !== 'string') {
     86                        throw new TypeError('Language code must be a string value');
     87                }
     88
     89                if (!args[0].match(/^[a-z]{2}(\-[a-z]{2})?$/i)) {
     90                        throw new TypeError('Language code must have format `xx` or `xx-xx`');
     91                }
     92
     93                i18n.lang = args[0];
     94
     95                // Check if language strings were added; otherwise, check the second argument or set to English as default
     96                if (i18n[args[0]] === undefined) {
     97                        args[1] = args[1] !== null && args[1] !== undefined && _typeof(args[1]) === 'object' ? args[1] : {};
     98                        i18n[args[0]] = !(0, _general.isObjectEmpty)(args[1]) ? args[1] : _en.EN;
     99                } else if (args[1] !== null && args[1] !== undefined && _typeof(args[1]) === 'object') {
     100                        i18n[args[0]] = args[1];
     101                }
     102        }
     103
     104        return i18n.lang;
     105};
     106
     107/**
     108 * Translate a string in the language set up (or English by default)
     109 *
     110 * @param {string} message
     111 * @param {number} pluralParam
     112 * @return {string}
     113 */
     114i18n.t = function (message) {
     115        var pluralParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
     116
     117
     118        if (typeof message === 'string' && message.length) {
     119
     120                var str = void 0,
     121                    pluralForm = void 0;
     122
     123                var language = i18n.language();
     124
     125                /**
     126   * Modify string using algorithm to detect plural forms.
     127   *
     128   * @private
     129   * @see http://stackoverflow.com/questions/1353408/messageformat-in-javascript-parameters-in-localized-ui-strings
     130   * @param {String|String[]} input   - String or array of strings to pick the plural form
     131   * @param {Number} number           - Number to determine the proper plural form
     132   * @param {Number} form             - Number of language family to apply plural form
     133   * @return {String}
     134   */
     135                var _plural = function _plural(input, number, form) {
     136
     137                        if ((typeof input === 'undefined' ? 'undefined' : _typeof(input)) !== 'object' || typeof number !== 'number' || typeof form !== 'number') {
     138                                return input;
     139                        }
     140
     141                        /**
     142    *
     143    * @return {Function[]}
     144    * @private
     145    */
     146                        var _pluralForms = function () {
     147                                return [
     148                                // 0: Chinese, Japanese, Korean, Persian, Turkish, Thai, Lao, Aymará,
     149                                // Tibetan, Chiga, Dzongkha, Indonesian, Lojban, Georgian, Kazakh, Khmer, Kyrgyz, Malay,
     150                                // Burmese, Yakut, Sundanese, Tatar, Uyghur, Vietnamese, Wolof
     151                                function () {
     152                                        return arguments.length <= 1 ? undefined : arguments[1];
     153                                },
     154
     155                                // 1: Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish, Estonian, Finnish,
     156                                // Hungarian, Basque, Greek, Hebrew, Italian, Portuguese, Spanish, Catalan, Afrikaans,
     157                                // Angika, Assamese, Asturian, Azerbaijani, Bulgarian, Bengali, Bodo, Aragonese, Dogri,
     158                                // Esperanto, Argentinean Spanish, Fulah, Friulian, Galician, Gujarati, Hausa,
     159                                // Hindi, Chhattisgarhi, Armenian, Interlingua, Greenlandic, Kannada, Kurdish, Letzeburgesch,
     160                                // Maithili, Malayalam, Mongolian, Manipuri, Marathi, Nahuatl, Neapolitan, Norwegian Bokmal,
     161                                // Nepali, Norwegian Nynorsk, Norwegian (old code), Northern Sotho, Oriya, Punjabi, Papiamento,
     162                                // Piemontese, Pashto, Romansh, Kinyarwanda, Santali, Scots, Sindhi, Northern Sami, Sinhala,
     163                                // Somali, Songhay, Albanian, Swahili, Tamil, Telugu, Turkmen, Urdu, Yoruba
     164                                function () {
     165                                        return (arguments.length <= 0 ? undefined : arguments[0]) === 1 ? arguments.length <= 1 ? undefined : arguments[1] : arguments.length <= 2 ? undefined : arguments[2];
     166                                },
     167
     168                                // 2: French, Brazilian Portuguese, Acholi, Akan, Amharic, Mapudungun, Breton, Filipino,
     169                                // Gun, Lingala, Mauritian Creole, Malagasy, Maori, Occitan, Tajik, Tigrinya, Uzbek, Walloon
     170                                function () {
     171                                        return (arguments.length <= 0 ? undefined : arguments[0]) === 0 || (arguments.length <= 0 ? undefined : arguments[0]) === 1 ? arguments.length <= 1 ? undefined : arguments[1] : arguments.length <= 2 ? undefined : arguments[2];
     172                                },
     173
     174                                // 3: Latvian
     175                                function () {
     176                                        if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 === 1 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 !== 11) {
     177                                                return arguments.length <= 1 ? undefined : arguments[1];
     178                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) !== 0) {
     179                                                return arguments.length <= 2 ? undefined : arguments[2];
     180                                        } else {
     181                                                return arguments.length <= 3 ? undefined : arguments[3];
     182                                        }
     183                                },
     184
     185                                // 4: Scottish Gaelic
     186                                function () {
     187                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1 || (arguments.length <= 0 ? undefined : arguments[0]) === 11) {
     188                                                return arguments.length <= 1 ? undefined : arguments[1];
     189                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 2 || (arguments.length <= 0 ? undefined : arguments[0]) === 12) {
     190                                                return arguments.length <= 2 ? undefined : arguments[2];
     191                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) > 2 && (arguments.length <= 0 ? undefined : arguments[0]) < 20) {
     192                                                return arguments.length <= 3 ? undefined : arguments[3];
     193                                        } else {
     194                                                return arguments.length <= 4 ? undefined : arguments[4];
     195                                        }
     196                                },
     197
     198                                // 5:  Romanian
     199                                function () {
     200                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     201                                                return arguments.length <= 1 ? undefined : arguments[1];
     202                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 0 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 > 0 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 < 20) {
     203                                                return arguments.length <= 2 ? undefined : arguments[2];
     204                                        } else {
     205                                                return arguments.length <= 3 ? undefined : arguments[3];
     206                                        }
     207                                },
     208
     209                                // 6: Lithuanian
     210                                function () {
     211                                        if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 === 1 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 !== 11) {
     212                                                return arguments.length <= 1 ? undefined : arguments[1];
     213                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 >= 2 && ((arguments.length <= 0 ? undefined : arguments[0]) % 100 < 10 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 20)) {
     214                                                return arguments.length <= 2 ? undefined : arguments[2];
     215                                        } else {
     216                                                return [3];
     217                                        }
     218                                },
     219
     220                                // 7: Belarusian, Bosnian, Croatian, Serbian, Russian, Ukrainian
     221                                function () {
     222                                        if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 === 1 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 !== 11) {
     223                                                return arguments.length <= 1 ? undefined : arguments[1];
     224                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 >= 2 && (arguments.length <= 0 ? undefined : arguments[0]) % 10 <= 4 && ((arguments.length <= 0 ? undefined : arguments[0]) % 100 < 10 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 20)) {
     225                                                return arguments.length <= 2 ? undefined : arguments[2];
     226                                        } else {
     227                                                return arguments.length <= 3 ? undefined : arguments[3];
     228                                        }
     229                                },
     230
     231                                // 8:  Slovak, Czech
     232                                function () {
     233                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     234                                                return arguments.length <= 1 ? undefined : arguments[1];
     235                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) >= 2 && (arguments.length <= 0 ? undefined : arguments[0]) <= 4) {
     236                                                return arguments.length <= 2 ? undefined : arguments[2];
     237                                        } else {
     238                                                return arguments.length <= 3 ? undefined : arguments[3];
     239                                        }
     240                                },
     241
     242                                // 9: Polish
     243                                function () {
     244                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     245                                                return arguments.length <= 1 ? undefined : arguments[1];
     246                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 >= 2 && (arguments.length <= 0 ? undefined : arguments[0]) % 10 <= 4 && ((arguments.length <= 0 ? undefined : arguments[0]) % 100 < 10 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 20)) {
     247                                                return arguments.length <= 2 ? undefined : arguments[2];
     248                                        } else {
     249                                                return arguments.length <= 3 ? undefined : arguments[3];
     250                                        }
     251                                },
     252
     253                                // 10: Slovenian
     254                                function () {
     255                                        if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 === 1) {
     256                                                return arguments.length <= 2 ? undefined : arguments[2];
     257                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 === 2) {
     258                                                return arguments.length <= 3 ? undefined : arguments[3];
     259                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 === 3 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 === 4) {
     260                                                return arguments.length <= 4 ? undefined : arguments[4];
     261                                        } else {
     262                                                return arguments.length <= 1 ? undefined : arguments[1];
     263                                        }
     264                                },
     265
     266                                // 11: Irish Gaelic
     267                                function () {
     268                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     269                                                return arguments.length <= 1 ? undefined : arguments[1];
     270                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 2) {
     271                                                return arguments.length <= 2 ? undefined : arguments[2];
     272                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) > 2 && (arguments.length <= 0 ? undefined : arguments[0]) < 7) {
     273                                                return arguments.length <= 3 ? undefined : arguments[3];
     274                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) > 6 && (arguments.length <= 0 ? undefined : arguments[0]) < 11) {
     275                                                return arguments.length <= 4 ? undefined : arguments[4];
     276                                        } else {
     277                                                return arguments.length <= 5 ? undefined : arguments[5];
     278                                        }
     279                                },
     280
     281                                // 12: Arabic
     282                                function () {
     283                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 0) {
     284                                                return arguments.length <= 1 ? undefined : arguments[1];
     285                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     286                                                return arguments.length <= 2 ? undefined : arguments[2];
     287                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 2) {
     288                                                return arguments.length <= 3 ? undefined : arguments[3];
     289                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 3 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 <= 10) {
     290                                                return arguments.length <= 4 ? undefined : arguments[4];
     291                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 11) {
     292                                                return arguments.length <= 5 ? undefined : arguments[5];
     293                                        } else {
     294                                                return arguments.length <= 6 ? undefined : arguments[6];
     295                                        }
     296                                },
     297
     298                                // 13: Maltese
     299                                function () {
     300                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     301                                                return arguments.length <= 1 ? undefined : arguments[1];
     302                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 0 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 > 1 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 < 11) {
     303                                                return arguments.length <= 2 ? undefined : arguments[2];
     304                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 100 > 10 && (arguments.length <= 0 ? undefined : arguments[0]) % 100 < 20) {
     305                                                return arguments.length <= 3 ? undefined : arguments[3];
     306                                        } else {
     307                                                return arguments.length <= 4 ? undefined : arguments[4];
     308                                        }
     309                                },
     310
     311                                // 14: Macedonian
     312                                function () {
     313                                        if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 === 1) {
     314                                                return arguments.length <= 1 ? undefined : arguments[1];
     315                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 === 2) {
     316                                                return arguments.length <= 2 ? undefined : arguments[2];
     317                                        } else {
     318                                                return arguments.length <= 3 ? undefined : arguments[3];
     319                                        }
     320                                },
     321
     322                                // 15:  Icelandic
     323                                function () {
     324                                        return (arguments.length <= 0 ? undefined : arguments[0]) !== 11 && (arguments.length <= 0 ? undefined : arguments[0]) % 10 === 1 ? arguments.length <= 1 ? undefined : arguments[1] : arguments.length <= 2 ? undefined : arguments[2];
     325                                },
     326
     327                                // New additions
     328
     329                                // 16:  Kashubian
     330                                // In https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals#List_of__pluralRules
     331                                // Breton is listed as #16 but in the Localization Guide it belongs to the group 2
     332                                function () {
     333                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     334                                                return arguments.length <= 1 ? undefined : arguments[1];
     335                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) % 10 >= 2 && (arguments.length <= 0 ? undefined : arguments[0]) % 10 <= 4 && ((arguments.length <= 0 ? undefined : arguments[0]) % 100 < 10 || (arguments.length <= 0 ? undefined : arguments[0]) % 100 >= 20)) {
     336                                                return arguments.length <= 2 ? undefined : arguments[2];
     337                                        } else {
     338                                                return arguments.length <= 3 ? undefined : arguments[3];
     339                                        }
     340                                },
     341
     342                                // 17:  Welsh
     343                                function () {
     344                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     345                                                return arguments.length <= 1 ? undefined : arguments[1];
     346                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 2) {
     347                                                return arguments.length <= 2 ? undefined : arguments[2];
     348                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) !== 8 && (arguments.length <= 0 ? undefined : arguments[0]) !== 11) {
     349                                                return arguments.length <= 3 ? undefined : arguments[3];
     350                                        } else {
     351                                                return arguments.length <= 4 ? undefined : arguments[4];
     352                                        }
     353                                },
     354
     355                                // 18:  Javanese
     356                                function () {
     357                                        return (arguments.length <= 0 ? undefined : arguments[0]) === 0 ? arguments.length <= 1 ? undefined : arguments[1] : arguments.length <= 2 ? undefined : arguments[2];
     358                                },
     359
     360                                // 19:  Cornish
     361                                function () {
     362                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     363                                                return arguments.length <= 1 ? undefined : arguments[1];
     364                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 2) {
     365                                                return arguments.length <= 2 ? undefined : arguments[2];
     366                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 3) {
     367                                                return arguments.length <= 3 ? undefined : arguments[3];
     368                                        } else {
     369                                                return arguments.length <= 4 ? undefined : arguments[4];
     370                                        }
     371                                },
     372
     373                                // 20:  Mandinka
     374                                function () {
     375                                        if ((arguments.length <= 0 ? undefined : arguments[0]) === 0) {
     376                                                return arguments.length <= 1 ? undefined : arguments[1];
     377                                        } else if ((arguments.length <= 0 ? undefined : arguments[0]) === 1) {
     378                                                return arguments.length <= 2 ? undefined : arguments[2];
     379                                        } else {
     380                                                return arguments.length <= 3 ? undefined : arguments[3];
     381                                        }
     382                                }];
     383                        }();
     384
     385                        // Perform plural form or return original text
     386                        return _pluralForms[form].apply(null, [number].concat(input));
     387                };
     388
     389                // Fetch the localized version of the string
     390                if (i18n[language] !== undefined) {
     391                        str = i18n[language][message];
     392                        if (pluralParam !== null && typeof pluralParam === 'number') {
     393                                pluralForm = i18n[language]['mejs.plural-form'];
     394                                str = _plural.apply(null, [str, pluralParam, pluralForm]);
     395                        }
     396                }
     397
     398                // Fallback to default language if requested uid is not translated
     399                if (!str && i18n.en) {
     400                        str = i18n.en[message];
     401                        if (pluralParam !== null && typeof pluralParam === 'number') {
     402                                pluralForm = i18n.en['mejs.plural-form'];
     403                                str = _plural.apply(null, [str, pluralParam, pluralForm]);
     404                        }
     405                }
     406
     407                // As a last resort, use the requested uid, to mimic original behavior of i18n utils
     408                // (in which uid was the english text)
     409                str = str || message;
     410
     411                // Replace token
     412                if (pluralParam !== null && typeof pluralParam === 'number') {
     413                        str = str.replace('%1', pluralParam);
     414                }
     415
     416                return (0, _general.escapeHTML)(str);
     417        }
     418
     419        return message;
     420};
     421
     422_mejs2.default.i18n = i18n;
     423
     424// `i18n` compatibility workflow with WordPress
     425if (typeof mejsL10n !== 'undefined') {
     426        _mejs2.default.i18n.language(mejsL10n.language, mejsL10n.strings);
     427}
     428
     429exports.default = i18n;
     430
     431},{"14":14,"25":25,"6":6}],5:[function(_dereq_,module,exports){
     432'use strict';
     433
     434Object.defineProperty(exports, "__esModule", {
     435        value: true
     436});
     437
     438var _window = _dereq_(3);
     439
     440var _window2 = _interopRequireDefault(_window);
     441
     442var _document = _dereq_(2);
     443
     444var _document2 = _interopRequireDefault(_document);
     445
     446var _mejs = _dereq_(6);
     447
     448var _mejs2 = _interopRequireDefault(_mejs);
     449
     450var _general = _dereq_(25);
     451
     452var _media = _dereq_(26);
     453
     454var _renderer = _dereq_(7);
     455
     456function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     457
     458function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
     459
     460/**
     461 * Media Core
     462 *
     463 * This class is the foundation to create/render different media formats.
     464 * @class MediaElement
     465 */
     466var MediaElement = function MediaElement(idOrNode, options) {
     467        var _this = this;
     468
     469        _classCallCheck(this, MediaElement);
     470
     471        var t = this;
     472
     473        t.defaults = {
     474                /**
     475   * List of the renderers to use
     476   * @type {String[]}
     477   */
     478                renderers: [],
     479                /**
     480   * Name of MediaElement container
     481   * @type {String}
     482   */
     483                fakeNodeName: 'mediaelementwrapper',
     484                /**
     485   * The path where shims are located
     486   * @type {String}
     487   */
     488                pluginPath: 'build/',
     489                /**
     490   * Flag in `<object>` and `<embed>` to determine whether to use local or CDN
     491   * Possible values: 'always' (CDN version) or 'sameDomain' (local files)
     492   */
     493                shimScriptAccess: 'sameDomain',
     494                /**
     495   * If error happens, set up HTML message
     496   * @type {String}
     497   */
     498                customError: ''
     499        };
     500
     501        options = Object.assign(t.defaults, options);
     502
     503        // create our node (note: older versions of iOS don't support Object.defineProperty on DOM nodes)
     504        t.mediaElement = _document2.default.createElement(options.fakeNodeName);
     505        t.mediaElement.options = options;
     506
     507        var id = idOrNode,
     508            error = false;
     509
     510        if (typeof idOrNode === 'string') {
     511                t.mediaElement.originalNode = _document2.default.getElementById(idOrNode);
     512        } else {
     513                t.mediaElement.originalNode = idOrNode;
     514                id = idOrNode.id;
     515        }
     516
     517        id = id || 'mejs_' + Math.random().toString().slice(2);
     518
     519        if (t.mediaElement.originalNode !== undefined && t.mediaElement.originalNode !== null && t.mediaElement.appendChild) {
     520                // change id
     521                t.mediaElement.originalNode.setAttribute('id', id + '_from_mejs');
     522
     523                // to avoid some issues with Javascript interactions in the plugin, set `preload=none` if not set
     524                // only if video/audio tags are detected
     525                var tagName = t.mediaElement.originalNode.tagName.toLowerCase();
     526                if (['video', 'audio'].includes(tagName) && !t.mediaElement.originalNode.getAttribute('preload')) {
     527                        t.mediaElement.originalNode.setAttribute('preload', 'none');
     528                }
     529
     530                // add next to this one
     531                t.mediaElement.originalNode.parentNode.insertBefore(t.mediaElement, t.mediaElement.originalNode);
     532
     533                // insert this one inside
     534                t.mediaElement.appendChild(t.mediaElement.originalNode);
     535        } else {
     536                // TODO: where to put the node?
     537        }
     538
     539        t.mediaElement.id = id;
     540        t.mediaElement.renderers = {};
     541        t.mediaElement.renderer = null;
     542        t.mediaElement.rendererName = null;
     543        /**
     544  * Determine whether the renderer was found or not
     545  *
     546  * @public
     547  * @param {String} rendererName
     548  * @param {Object[]} mediaFiles
     549  * @return {Boolean}
     550  */
     551        t.mediaElement.changeRenderer = function (rendererName, mediaFiles) {
     552
     553                var t = _this;
     554
     555                // check for a match on the current renderer
     556                if (t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null && t.mediaElement.renderer.name === rendererName) {
     557                        t.mediaElement.renderer.pause();
     558                        if (t.mediaElement.renderer.stop) {
     559                                t.mediaElement.renderer.stop();
     560                        }
     561                        t.mediaElement.renderer.show();
     562                        t.mediaElement.renderer.setSrc(mediaFiles[0].src);
     563                        return true;
     564                }
     565
     566                // if existing renderer is not the right one, then hide it
     567                if (t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null) {
     568                        t.mediaElement.renderer.pause();
     569                        if (t.mediaElement.renderer.stop) {
     570                                t.mediaElement.renderer.stop();
     571                        }
     572                        t.mediaElement.renderer.hide();
     573                }
     574
     575                // see if we have the renderer already created
     576                var newRenderer = t.mediaElement.renderers[rendererName],
     577                    newRendererType = null;
     578
     579                if (newRenderer !== undefined && newRenderer !== null) {
     580                        newRenderer.show();
     581                        newRenderer.setSrc(mediaFiles[0].src);
     582                        t.mediaElement.renderer = newRenderer;
     583                        t.mediaElement.rendererName = rendererName;
     584                        return true;
     585                }
     586
     587                var rendererArray = t.mediaElement.options.renderers.length ? t.mediaElement.options.renderers : _renderer.renderer.order;
     588
     589                // find the desired renderer in the array of possible ones
     590                for (var i = 0, total = rendererArray.length; i < total; i++) {
     591
     592                        var index = rendererArray[i];
     593
     594                        if (index === rendererName) {
     595
     596                                // create the renderer
     597                                var rendererList = _renderer.renderer.renderers;
     598                                newRendererType = rendererList[index];
     599
     600                                var renderOptions = Object.assign(newRendererType.options, t.mediaElement.options);
     601                                newRenderer = newRendererType.create(t.mediaElement, renderOptions, mediaFiles);
     602                                newRenderer.name = rendererName;
     603
     604                                // store for later
     605                                t.mediaElement.renderers[newRendererType.name] = newRenderer;
     606                                t.mediaElement.renderer = newRenderer;
     607                                t.mediaElement.rendererName = rendererName;
     608
     609                                newRenderer.show();
     610
     611                                return true;
     612                        }
     613                }
     614
     615                return false;
     616        };
     617
     618        /**
     619  * Set the element dimensions based on selected renderer's setSize method
     620  *
     621  * @public
     622  * @param {number} width
     623  * @param {number} height
     624  */
     625        t.mediaElement.setSize = function (width, height) {
     626                if (t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null) {
     627                        t.mediaElement.renderer.setSize(width, height);
     628                }
     629        };
     630
     631        /**
     632  *
     633  * @param {Object[]} urlList
     634  */
     635        t.mediaElement.createErrorMessage = function (urlList) {
     636
     637                urlList = Array.isArray(urlList) ? urlList : [];
     638
     639                var errorContainer = _document2.default.createElement('div');
     640                errorContainer.className = 'me_cannotplay';
     641                errorContainer.style.width = '100%';
     642                errorContainer.style.height = '100%';
     643
     644                var errorContent = t.mediaElement.options.customError;
     645
     646                if (!errorContent) {
     647
     648                        var poster = t.mediaElement.originalNode.getAttribute('poster');
     649                        if (poster) {
     650                                errorContent += '<img src="' + poster + '" width="100%" height="100%" alt="' + _mejs2.default.i18n.t('mejs.download-file') + '">';
     651                        }
     652
     653                        for (var i = 0, total = urlList.length; i < total; i++) {
     654                                var url = urlList[i];
     655                                errorContent += '<a href="' + url.src + '" data-type="' + url.type + '"><span>' + _mejs2.default.i18n.t('mejs.download-file') + ': ' + url.src + '</span></a>';
     656                        }
     657                }
     658
     659                errorContainer.innerHTML = errorContent;
     660
     661                t.mediaElement.originalNode.parentNode.insertBefore(errorContainer, t.mediaElement.originalNode);
     662                t.mediaElement.originalNode.style.display = 'none';
     663                error = true;
     664        };
     665
     666        var props = _mejs2.default.html5media.properties,
     667            methods = _mejs2.default.html5media.methods,
     668            addProperty = function addProperty(obj, name, onGet, onSet) {
     669
     670                // wrapper functions
     671                var oldValue = obj[name];
     672                var getFn = function getFn() {
     673                        return onGet.apply(obj, [oldValue]);
     674                },
     675                    setFn = function setFn(newValue) {
     676                        oldValue = onSet.apply(obj, [newValue]);
     677                        return oldValue;
     678                };
     679
     680                Object.defineProperty(obj, name, {
     681                        get: getFn,
     682                        set: setFn
     683                });
     684        },
     685            assignGettersSetters = function assignGettersSetters(propName) {
     686                if (propName !== 'src') {
     687                        (function () {
     688
     689                                var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1),
     690                                    getFn = function getFn() {
     691                                        return t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null ? t.mediaElement.renderer['get' + capName]() : null;
     692                                },
     693                                    setFn = function setFn(value) {
     694                                        if (t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null) {
     695                                                t.mediaElement.renderer['set' + capName](value);
     696                                        }
     697                                };
     698
     699                                addProperty(t.mediaElement, propName, getFn, setFn);
     700                                t.mediaElement['get' + capName] = getFn;
     701                                t.mediaElement['set' + capName] = setFn;
     702                        })();
     703                }
     704        },
     705
     706        // `src` is a property separated from the others since it carries the logic to set the proper renderer
     707        // based on the media files detected
     708        getSrc = function getSrc() {
     709                return t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null ? t.mediaElement.renderer.getSrc() : null;
     710        },
     711            setSrc = function setSrc(value) {
     712
     713                var mediaFiles = [];
     714
     715                // clean up URLs
     716                if (typeof value === 'string') {
     717                        mediaFiles.push({
     718                                src: value,
     719                                type: value ? (0, _media.getTypeFromFile)(value) : ''
     720                        });
     721                } else {
     722                        for (var i = 0, total = value.length; i < total; i++) {
     723
     724                                var src = (0, _media.absolutizeUrl)(value[i].src),
     725                                    type = value[i].type;
     726
     727                                mediaFiles.push({
     728                                        src: src,
     729                                        type: (type === '' || type === null || type === undefined) && src ? (0, _media.getTypeFromFile)(src) : type
     730                                });
     731                        }
     732                }
     733
     734                // find a renderer and URL match
     735                var renderInfo = _renderer.renderer.select(mediaFiles, t.mediaElement.options.renderers.length ? t.mediaElement.options.renderers : []),
     736                    event = void 0;
     737
     738                // Ensure that the original gets the first source found
     739                if (!t.mediaElement.paused) {
     740                        t.mediaElement.pause();
     741                        event = (0, _general.createEvent)('pause', t.mediaElement);
     742                        t.mediaElement.dispatchEvent(event);
     743                }
     744
     745                t.mediaElement.originalNode.setAttribute('src', mediaFiles[0].src || '');
     746
     747                if (t.mediaElement.querySelector('.me_cannotplay')) {
     748                        t.mediaElement.querySelector('.me_cannotplay').remove();
     749                }
     750
     751                // did we find a renderer?
     752                if (renderInfo === null) {
     753                        t.mediaElement.createErrorMessage(mediaFiles);
     754                        event = (0, _general.createEvent)('error', t.mediaElement);
     755                        event.message = 'No renderer found';
     756                        t.mediaElement.dispatchEvent(event);
     757                        return;
     758                }
     759
     760                // turn on the renderer (this checks for the existing renderer already)
     761                t.mediaElement.changeRenderer(renderInfo.rendererName, mediaFiles);
     762
     763                if (t.mediaElement.renderer === undefined || t.mediaElement.renderer === null) {
     764                        event = (0, _general.createEvent)('error', t.mediaElement);
     765                        event.message = 'Error creating renderer';
     766                        t.mediaElement.dispatchEvent(event);
     767                        t.mediaElement.createErrorMessage(mediaFiles);
     768                        return;
     769                }
     770        },
     771            assignMethods = function assignMethods(methodName) {
     772                // run the method on the current renderer
     773                t.mediaElement[methodName] = function () {
     774                        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
     775                                args[_key] = arguments[_key];
     776                        }
     777
     778                        if (t.mediaElement.renderer !== undefined && t.mediaElement.renderer !== null && typeof t.mediaElement.renderer[methodName] === 'function') {
     779                                try {
     780                                        t.mediaElement.renderer[methodName](args);
     781                                } catch (e) {
     782                                        t.mediaElement.createErrorMessage();
     783                                }
     784                        }
     785                        return null;
     786                };
     787        };
     788
     789        // Assign all methods/properties/events to fake node if renderer was found
     790        addProperty(t.mediaElement, 'src', getSrc, setSrc);
     791        t.mediaElement.getSrc = getSrc;
     792        t.mediaElement.setSrc = setSrc;
     793
     794        for (var i = 0, total = props.length; i < total; i++) {
     795                assignGettersSetters(props[i]);
     796        }
     797
     798        for (var _i = 0, _total = methods.length; _i < _total; _i++) {
     799                assignMethods(methods[_i]);
     800        }
     801
     802        // IE && iOS
     803        t.mediaElement.events = {};
     804
     805        // start: fake events
     806        t.mediaElement.addEventListener = function (eventName, callback) {
     807                // create or find the array of callbacks for this eventName
     808                t.mediaElement.events[eventName] = t.mediaElement.events[eventName] || [];
     809
     810                // push the callback into the stack
     811                t.mediaElement.events[eventName].push(callback);
     812        };
     813        t.mediaElement.removeEventListener = function (eventName, callback) {
     814                // no eventName means remove all listeners
     815                if (!eventName) {
     816                        t.mediaElement.events = {};
     817                        return true;
     818                }
     819
     820                // see if we have any callbacks for this eventName
     821                var callbacks = t.mediaElement.events[eventName];
     822
     823                if (!callbacks) {
     824                        return true;
     825                }
     826
     827                // check for a specific callback
     828                if (!callback) {
     829                        t.mediaElement.events[eventName] = [];
     830                        return true;
     831                }
     832
     833                // remove the specific callback
     834                for (var _i2 = 0; _i2 < callbacks.length; _i2++) {
     835                        if (callbacks[_i2] === callback) {
     836                                t.mediaElement.events[eventName].splice(_i2, 1);
     837                                return true;
     838                        }
     839                }
     840                return false;
     841        };
     842
     843        /**
     844  *
     845  * @param {Event} event
     846  */
     847        t.mediaElement.dispatchEvent = function (event) {
     848
     849                var callbacks = t.mediaElement.events[event.type];
     850
     851                if (callbacks) {
     852                        for (var _i3 = 0; _i3 < callbacks.length; _i3++) {
     853                                callbacks[_i3].apply(null, [event]);
     854                        }
     855                }
     856        };
     857
     858        if (t.mediaElement.originalNode !== null) {
     859                var mediaFiles = [];
     860
     861                switch (t.mediaElement.originalNode.nodeName.toLowerCase()) {
     862
     863                        case 'iframe':
     864                                mediaFiles.push({
     865                                        type: '',
     866                                        src: t.mediaElement.originalNode.getAttribute('src')
     867                                });
     868
     869                                break;
     870
     871                        case 'audio':
     872                        case 'video':
     873                                var n = void 0,
     874                                    src = void 0,
     875                                    type = void 0,
     876                                    sources = t.mediaElement.originalNode.childNodes.length,
     877                                    nodeSource = t.mediaElement.originalNode.getAttribute('src');
     878
     879                                // Consider if node contains the `src` and `type` attributes
     880                                if (nodeSource) {
     881                                        var node = t.mediaElement.originalNode;
     882                                        mediaFiles.push({
     883                                                type: (0, _media.formatType)(nodeSource, node.getAttribute('type')),
     884                                                src: nodeSource
     885                                        });
     886                                }
     887
     888                                // test <source> types to see if they are usable
     889                                for (var _i4 = 0; _i4 < sources; _i4++) {
     890                                        n = t.mediaElement.originalNode.childNodes[_i4];
     891                                        if (n.nodeType === Node.ELEMENT_NODE && n.tagName.toLowerCase() === 'source') {
     892                                                src = n.getAttribute('src');
     893                                                type = (0, _media.formatType)(src, n.getAttribute('type'));
     894                                                mediaFiles.push({ type: type, src: src });
     895                                        }
     896                                }
     897                                break;
     898                }
     899
     900                if (mediaFiles.length > 0) {
     901                        t.mediaElement.src = mediaFiles;
     902                }
     903        }
     904
     905        if (t.mediaElement.options.success) {
     906                t.mediaElement.options.success(t.mediaElement, t.mediaElement.originalNode);
     907        }
     908
     909        if (error && t.mediaElement.options.error) {
     910                t.mediaElement.options.error(t.mediaElement, t.mediaElement.originalNode);
     911        }
     912
     913        return t.mediaElement;
     914};
     915
     916_window2.default.MediaElement = MediaElement;
     917
     918exports.default = MediaElement;
     919
     920},{"2":2,"25":25,"26":26,"3":3,"6":6,"7":7}],6:[function(_dereq_,module,exports){
     921'use strict';
     922
     923Object.defineProperty(exports, "__esModule", {
     924        value: true
     925});
     926
     927var _window = _dereq_(3);
     928
     929var _window2 = _interopRequireDefault(_window);
     930
     931function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     932
    14933// Namespace
    15 var mejs = mejs || {};
     934var mejs = {};
    16935
    17936// version number
    18 mejs.version = '2.15.1';
    19 
    20 
    21 // player number (for missing, same id attr)
    22 mejs.meIndex = 0;
    23 
    24 // media types accepted by plugins
    25 mejs.plugins = {
    26         silverlight: [
    27                 {version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
    28         ],
    29         flash: [
    30                 {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube', 'application/x-mpegURL']}
    31                 //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
    32         ],
    33         youtube: [
    34                 {version: null, types: ['video/youtube', 'video/x-youtube', 'audio/youtube', 'audio/x-youtube']}
    35         ],
    36         vimeo: [
    37                 {version: null, types: ['video/vimeo', 'video/x-vimeo']}
    38         ]
     937mejs.version = '4.0.2';
     938
     939// Basic HTML5 settings
     940mejs.html5media = {
     941        /**
     942  * @type {String[]}
     943  */
     944        properties: [
     945        // GET/SET
     946        'volume', 'src', 'currentTime', 'muted',
     947
     948        // GET only
     949        'duration', 'paused', 'ended', 'buffered', 'error', 'networkState', 'readyState', 'seeking', 'seekable',
     950
     951        // OTHERS
     952        'currentSrc', 'preload', 'bufferedBytes', 'bufferedTime', 'initialTime', 'startOffsetTime', 'defaultPlaybackRate', 'playbackRate', 'played', 'autoplay', 'loop', 'controls'],
     953        readOnlyProperties: ['duration', 'paused', 'ended', 'buffered', 'error', 'networkState', 'readyState', 'seeking', 'seekable'],
     954        /**
     955  * @type {String[]}
     956  */
     957        methods: ['load', 'play', 'pause', 'canPlayType'],
     958        /**
     959  * @type {String[]}
     960  */
     961        events: ['loadstart', 'progress', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'play', 'pause', 'loadedmetadata', 'loadeddata', 'waiting', 'playing', 'canplay', 'canplaythrough', 'seeking', 'seeked', 'timeupdate', 'ended', 'ratechange', 'durationchange', 'volumechange'],
     962        /**
     963  * @type {String[]}
     964  */
     965        mediaTypes: ['audio/mp3', 'audio/ogg', 'audio/oga', 'audio/wav', 'audio/x-wav', 'audio/wave', 'audio/x-pn-wav', 'audio/mpeg', 'audio/mp4', 'video/mp4', 'video/webm', 'video/ogg']
    39966};
    40967
     968_window2.default.mejs = mejs;
     969
     970exports.default = mejs;
     971
     972},{"3":3}],7:[function(_dereq_,module,exports){
     973'use strict';
     974
     975Object.defineProperty(exports, "__esModule", {
     976        value: true
     977});
     978exports.renderer = undefined;
     979
     980var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
     981
     982var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
     983
     984var _mejs = _dereq_(6);
     985
     986var _mejs2 = _interopRequireDefault(_mejs);
     987
     988function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     989
     990function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
     991
     992/**
     993 *
     994 * Class to manage renderer selection and addition.
     995 * @class Renderer
     996 */
     997var Renderer = function () {
     998        function Renderer() {
     999                _classCallCheck(this, Renderer);
     1000
     1001                this.renderers = {};
     1002                this.order = [];
     1003        }
     1004
     1005        /**
     1006  * Register a new renderer.
     1007  *
     1008  * @param {Object} renderer - An object with all the rendered information (name REQUIRED)
     1009  * @method add
     1010  */
     1011
     1012
     1013        _createClass(Renderer, [{
     1014                key: 'add',
     1015                value: function add(renderer) {
     1016
     1017                        if (renderer.name === undefined) {
     1018                                throw new TypeError('renderer must contain at least `name` property');
     1019                        }
     1020
     1021                        this.renderers[renderer.name] = renderer;
     1022                        this.order.push(renderer.name);
     1023                }
     1024
     1025                /**
     1026   * Iterate a list of renderers to determine which one should the player use.
     1027   *
     1028   * @param {Object[]} mediaFiles - A list of source and type obtained from video/audio/source tags: [{src:'',type:''}]
     1029   * @param {?String[]} renderers - Optional list of pre-selected renderers
     1030   * @return {?Object} The renderer's name and source selected
     1031   * @method select
     1032   */
     1033
     1034        }, {
     1035                key: 'select',
     1036                value: function select(mediaFiles) {
     1037                        var renderers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
     1038
     1039
     1040                        var renderersLength = renderers.length;
     1041
     1042                        renderers = renderers.length ? renderers : this.order;
     1043
     1044                        // If renderers are not set, set a default order:
     1045                        // 1) Native renderers (HTML5, HLS, M(PEG)-DASH, FLV)
     1046                        // 2) Flash shims (RTMP, FLV, HLS, M(PEG)-DASH, MP3, OGG)
     1047                        // 3) Iframe renderers (YouTube, SoundCloud, Facebook. etc.)
     1048                        if (!renderersLength) {
     1049                                (function () {
     1050                                        var rendererIndicator = [/^(html5|native)/, /^flash/, /iframe$/],
     1051                                            rendererRanking = function rendererRanking(renderer) {
     1052                                                for (var i = 0, total = rendererIndicator.length; i < total; i++) {
     1053                                                        if (renderer.match(rendererIndicator[i]) !== null) {
     1054                                                                return i;
     1055                                                        }
     1056                                                }
     1057                                                return rendererIndicator.length;
     1058                                        };
     1059
     1060                                        renderers.sort(function (a, b) {
     1061                                                return rendererRanking(a) - rendererRanking(b);
     1062                                        });
     1063                                })();
     1064                        }
     1065
     1066                        for (var i = 0, total = renderers.length; i < total; i++) {
     1067                                var key = renderers[i],
     1068                                    _renderer = this.renderers[key];
     1069
     1070                                if (_renderer !== null && _renderer !== undefined) {
     1071                                        for (var j = 0, jl = mediaFiles.length; j < jl; j++) {
     1072                                                if (typeof _renderer.canPlayType === 'function' && typeof mediaFiles[j].type === 'string' && _renderer.canPlayType(mediaFiles[j].type)) {
     1073                                                        return {
     1074                                                                rendererName: _renderer.name,
     1075                                                                src: mediaFiles[j].src
     1076                                                        };
     1077                                                }
     1078                                        }
     1079                                }
     1080                        }
     1081
     1082                        return null;
     1083                }
     1084
     1085                // Setters/getters
     1086
     1087        }, {
     1088                key: 'order',
     1089                set: function set(order) {
     1090
     1091                        if (!Array.isArray(order)) {
     1092                                throw new TypeError('order must be an array of strings.');
     1093                        }
     1094
     1095                        this._order = order;
     1096                },
     1097                get: function get() {
     1098                        return this._order;
     1099                }
     1100        }, {
     1101                key: 'renderers',
     1102                set: function set(renderers) {
     1103
     1104                        if (renderers !== null && (typeof renderers === 'undefined' ? 'undefined' : _typeof(renderers)) !== 'object') {
     1105                                throw new TypeError('renderers must be an array of objects.');
     1106                        }
     1107
     1108                        this._renderers = renderers;
     1109                },
     1110                get: function get() {
     1111                        return this._renderers;
     1112                }
     1113        }]);
     1114
     1115        return Renderer;
     1116}();
     1117
     1118var renderer = exports.renderer = new Renderer();
     1119
     1120_mejs2.default.Renderers = renderer;
     1121
     1122},{"6":6}],8:[function(_dereq_,module,exports){
     1123'use strict';
     1124
     1125var _window = _dereq_(3);
     1126
     1127var _window2 = _interopRequireDefault(_window);
     1128
     1129var _document = _dereq_(2);
     1130
     1131var _document2 = _interopRequireDefault(_document);
     1132
     1133var _i18n = _dereq_(4);
     1134
     1135var _i18n2 = _interopRequireDefault(_i18n);
     1136
     1137var _player = _dereq_(16);
     1138
     1139var _player2 = _interopRequireDefault(_player);
     1140
     1141var _constants = _dereq_(23);
     1142
     1143var Features = _interopRequireWildcard(_constants);
     1144
     1145var _general = _dereq_(25);
     1146
     1147var _dom = _dereq_(24);
     1148
     1149function _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; } }
     1150
     1151function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     1152
     1153/**
     1154 * Fullscreen button
     1155 *
     1156 * This feature creates a button to toggle fullscreen on video; it considers a letiety of possibilities when dealing with it
     1157 * since it is not consistent across browsers. It also accounts for triggering the event through Flash shim.
     1158 */
     1159
     1160// Feature configuration
     1161Object.assign(_player.config, {
     1162        /**
     1163  * @type {Boolean}
     1164  */
     1165        usePluginFullScreen: true,
     1166        /**
     1167  * @type {?String}
     1168  */
     1169        fullscreenText: null
     1170});
     1171
     1172Object.assign(_player2.default.prototype, {
     1173
     1174        /**
     1175  * @type {Boolean}
     1176  */
     1177        isFullScreen: false,
     1178        /**
     1179  * @type {Boolean}
     1180  */
     1181        isNativeFullScreen: false,
     1182        /**
     1183  * @type {Boolean}
     1184  */
     1185        isInIframe: false,
     1186        /**
     1187  * @type {Boolean}
     1188  */
     1189        isPluginClickThroughCreated: false,
     1190        /**
     1191  * Possible modes
     1192  * (1) 'native-native'  HTML5 video  + browser fullscreen (IE10+, etc.)
     1193  * (2) 'plugin-native'  plugin video + browser fullscreen (fails in some versions of Firefox)
     1194  * (3) 'fullwindow'     Full window (retains all UI)
     1195  *
     1196  * @type {String}
     1197  */
     1198        fullscreenMode: '',
     1199        /**
     1200  *
     1201  */
     1202        containerSizeTimeout: null,
     1203
     1204        /**
     1205  * Feature constructor.
     1206  *
     1207  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     1208  * @param {MediaElementPlayer} player
     1209  * @param {$} controls
     1210  * @param {$} layers
     1211  * @param {HTMLElement} media
     1212  */
     1213        buildfullscreen: function buildfullscreen(player, controls, layers, media) {
     1214
     1215                if (!player.isVideo) {
     1216                        return;
     1217                }
     1218
     1219                player.isInIframe = _window2.default.location !== _window2.default.parent.location;
     1220
     1221                // detect on start
     1222                media.addEventListener('loadstart', function () {
     1223                        player.detectFullscreenMode();
     1224                });
     1225
     1226                var t = this,
     1227                    fullscreenTitle = (0, _general.isString)(t.options.fullscreenText) ? t.options.fullscreenText : _i18n2.default.t('mejs.fullscreen'),
     1228                    fullscreenBtn = _document2.default.createElement('div');
     1229
     1230                fullscreenBtn.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'fullscreen-button';
     1231                fullscreenBtn.innerHTML = '<button type="button" aria-controls="' + t.id + '" title="' + fullscreenTitle + '" aria-label="' + fullscreenTitle + '" tabindex="0"></button>';
     1232                t.addControlElement(fullscreenBtn, 'fullscreen');
     1233
     1234                fullscreenBtn.addEventListener('click', function () {
     1235                        // toggle fullscreen
     1236                        var isFullScreen = Features.HAS_TRUE_NATIVE_FULLSCREEN && Features.IS_FULLSCREEN || player.isFullScreen;
     1237
     1238                        if (isFullScreen) {
     1239                                player.exitFullScreen();
     1240                        } else {
     1241                                player.enterFullScreen();
     1242                        }
     1243                });
     1244
     1245                player.fullscreenBtn = fullscreenBtn;
     1246
     1247                t.globalBind('keydown', function (e) {
     1248                        var key = e.which || e.keyCode || 0;
     1249                        if (key === 27 && (Features.HAS_TRUE_NATIVE_FULLSCREEN && Features.IS_FULLSCREEN || t.isFullScreen)) {
     1250                                player.exitFullScreen();
     1251                        }
     1252                });
     1253
     1254                t.normalHeight = 0;
     1255                t.normalWidth = 0;
     1256
     1257                // setup native fullscreen event
     1258                if (Features.HAS_TRUE_NATIVE_FULLSCREEN) {
     1259
     1260                        //
     1261                        /**
     1262    * Detect any changes on fullscreen
     1263    *
     1264    * Chrome doesn't always fire this in an `<iframe>`
     1265    * @private
     1266    */
     1267                        var fullscreenChanged = function fullscreenChanged() {
     1268                                if (player.isFullScreen) {
     1269                                        if (Features.isFullScreen()) {
     1270                                                player.isNativeFullScreen = true;
     1271                                                // reset the controls once we are fully in full screen
     1272                                                player.setControlsSize();
     1273                                        } else {
     1274                                                player.isNativeFullScreen = false;
     1275                                                // when a user presses ESC
     1276                                                // make sure to put the player back into place
     1277                                                player.exitFullScreen();
     1278                                        }
     1279                                }
     1280                        };
     1281
     1282                        player.globalBind(Features.FULLSCREEN_EVENT_NAME, fullscreenChanged);
     1283                }
     1284        },
     1285
     1286
     1287        /**
     1288  * Detect the type of fullscreen based on browser's capabilities
     1289  *
     1290  * @return {String}
     1291  */
     1292        detectFullscreenMode: function detectFullscreenMode() {
     1293
     1294                var t = this,
     1295                    isNative = t.media.rendererName !== null && t.media.rendererName.match(/(native|html5)/) !== null;
     1296
     1297                var mode = '';
     1298
     1299                if (Features.HAS_TRUE_NATIVE_FULLSCREEN && isNative) {
     1300                        mode = 'native-native';
     1301                } else if (Features.HAS_TRUE_NATIVE_FULLSCREEN && !isNative) {
     1302                        mode = 'plugin-native';
     1303                } else if (t.usePluginFullScreen && Features.SUPPORT_POINTER_EVENTS) {
     1304                        mode = 'plugin-click';
     1305                } else {
     1306                        mode = 'fullwindow';
     1307                }
     1308
     1309                t.fullscreenMode = mode;
     1310                return mode;
     1311        },
     1312
     1313
     1314        /**
     1315  * Feature destructor.
     1316  *
     1317  * Always has to be prefixed with `clean` and the name that was used in features list
     1318  * @param {MediaElementPlayer} player
     1319  */
     1320        cleanfullscreen: function cleanfullscreen(player) {
     1321                player.exitFullScreen();
     1322        },
     1323
     1324
     1325        /**
     1326  *
     1327  */
     1328        enterFullScreen: function enterFullScreen() {
     1329
     1330                var t = this,
     1331                    isNative = t.media.rendererName !== null && t.media.rendererName.match(/(html5|native)/) !== null,
     1332                    containerStyles = getComputedStyle(t.container);
     1333
     1334                if (Features.IS_IOS && Features.HAS_IOS_FULLSCREEN && typeof t.media.webkitEnterFullscreen === 'function') {
     1335                        t.media.webkitEnterFullscreen();
     1336                        return;
     1337                }
     1338
     1339                // set it to not show scroll bars so 100% will work
     1340                (0, _dom.addClass)(_document2.default.documentElement, t.options.classPrefix + 'fullscreen');
     1341                (0, _dom.addClass)(t.container, t.options.classPrefix + 'container-fullscreen');
     1342
     1343                // store sizing
     1344                t.normalHeight = parseFloat(containerStyles.height);
     1345                t.normalWidth = parseFloat(containerStyles.width);
     1346
     1347                // attempt to do true fullscreen
     1348                if (t.fullscreenMode === 'native-native' || t.fullscreenMode === 'plugin-native') {
     1349
     1350                        Features.requestFullScreen(t.container);
     1351
     1352                        if (t.isInIframe) {
     1353                                // sometimes exiting from fullscreen doesn't work
     1354                                // notably in Chrome <iframe>. Fixed in version 17
     1355                                setTimeout(function checkFullscreen() {
     1356
     1357                                        if (t.isNativeFullScreen) {
     1358                                                var percentErrorMargin = 0.002,
     1359                                                    // 0.2%
     1360                                                windowWidth = _window2.default.innerWidth || _document2.default.documentElement.clientWidth || _document2.default.body.clientWidth,
     1361                                                    screenWidth = screen.width,
     1362                                                    absDiff = Math.abs(screenWidth - windowWidth),
     1363                                                    marginError = screenWidth * percentErrorMargin;
     1364
     1365                                                // check if the video is suddenly not really fullscreen
     1366                                                if (absDiff > marginError) {
     1367                                                        // manually exit
     1368                                                        t.exitFullScreen();
     1369                                                } else {
     1370                                                        // test again
     1371                                                        setTimeout(checkFullscreen, 500);
     1372                                                }
     1373                                        }
     1374                                }, 1000);
     1375                        }
     1376                } else if (t.fullscreeMode === 'fullwindow') {}
     1377                // move into position
     1378
     1379                // make full size
     1380                t.container.style.width = '100%';
     1381                t.container.style.height = '100%';
     1382
     1383                // Only needed for safari 5.1 native full screen, can cause display issues elsewhere
     1384                // Actually, it seems to be needed for IE8, too
     1385                t.containerSizeTimeout = setTimeout(function () {
     1386                        t.container.style.width = '100%';
     1387                        t.container.style.height = '100%';
     1388                        t.setControlsSize();
     1389                }, 500);
     1390
     1391                if (isNative) {
     1392                        t.node.style.width = '100%';
     1393                        t.node.style.height = '100%';
     1394                } else {
     1395                        var elements = t.container.querySelectorAll('iframe, embed, object, video'),
     1396                            _total = elements.length;
     1397                        for (var i = 0; i < _total; i++) {
     1398                                elements[i].style.width = '100%';
     1399                                elements[i].style.height = '100%';
     1400                        }
     1401                }
     1402
     1403                if (t.options.setDimensions && typeof t.media.setSize === 'function') {
     1404                        t.media.setSize(screen.width, screen.height);
     1405                }
     1406
     1407                var layers = t.layers.childNodes,
     1408                    total = layers.length;
     1409                for (var _i = 0; _i < total; _i++) {
     1410                        layers[_i].style.width = '100%';
     1411                        layers[_i].style.height = '100%';
     1412                }
     1413
     1414                if (t.fullscreenBtn) {
     1415                        (0, _dom.removeClass)(t.fullscreenBtn, t.options.classPrefix + 'fullscreen');
     1416                        (0, _dom.addClass)(t.fullscreenBtn, t.options.classPrefix + 'unfullscreen');
     1417                }
     1418
     1419                t.setControlsSize();
     1420                t.isFullScreen = true;
     1421
     1422                var zoomFactor = Math.min(screen.width / t.width, screen.height / t.height),
     1423                    captionText = t.container.querySelector('.' + t.options.classPrefix + 'captions-text');
     1424                if (captionText) {
     1425                        captionText.style.fontSize = zoomFactor * 100 + '%';
     1426                        captionText.style.lineHeight = 'normal';
     1427                        t.container.querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = '45px';
     1428                }
     1429                var event = (0, _general.createEvent)('enteredfullscreen', t.container);
     1430                t.container.dispatchEvent(event);
     1431        },
     1432
     1433
     1434        /**
     1435  *
     1436  */
     1437        exitFullScreen: function exitFullScreen() {
     1438
     1439                var t = this,
     1440                    isNative = t.media.rendererName !== null && t.media.rendererName.match(/(native|html5)/) !== null;
     1441
     1442                // Prevent container from attempting to stretch a second time
     1443                clearTimeout(t.containerSizeTimeout);
     1444
     1445                // come out of native fullscreen
     1446                if (Features.HAS_TRUE_NATIVE_FULLSCREEN && (Features.IS_FULLSCREEN || t.isFullScreen)) {
     1447                        Features.cancelFullScreen();
     1448                }
     1449
     1450                // restore scroll bars to document
     1451                (0, _dom.removeClass)(_document2.default.documentElement, t.options.classPrefix + 'fullscreen');
     1452                (0, _dom.removeClass)(t.container, t.options.classPrefix + 'container-fullscreen');
     1453
     1454                if (t.options.setDimensions) {
     1455                        t.container.style.width = t.normalWidth + 'px';
     1456                        t.container.style.height = t.normalHeight + 'px';
     1457
     1458                        if (isNative) {
     1459                                t.node.style.width = t.normalWidth + 'px';
     1460                                t.node.style.height = t.normalHeight + 'px';
     1461                        } else {
     1462                                var elements = t.container.querySelectorAll('iframe, embed, object, video'),
     1463                                    _total2 = elements.length;
     1464                                for (var i = 0; i < _total2; i++) {
     1465                                        elements[i].style.width = t.normalWidth + 'px';
     1466                                        elements[i].style.height = t.normalHeight + 'px';
     1467                                }
     1468                        }
     1469
     1470                        if (typeof t.media.setSize === 'function') {
     1471                                t.media.setSize(t.normalWidth, t.normalHeight);
     1472                        }
     1473
     1474                        var layers = t.layers.childNodes,
     1475                            total = layers.length;
     1476                        for (var _i2 = 0; _i2 < total; _i2++) {
     1477                                layers[_i2].style.width = t.normalWidth + 'px';
     1478                                layers[_i2].style.height = t.normalHeight + 'px';
     1479                        }
     1480                }
     1481
     1482                (0, _dom.removeClass)(t.fullscreenBtn, t.options.classPrefix + 'unfullscreen');
     1483                (0, _dom.addClass)(t.fullscreenBtn, t.options.classPrefix + 'fullscreen');
     1484
     1485                t.setControlsSize();
     1486                t.isFullScreen = false;
     1487
     1488                var captionText = t.container.querySelector('.' + t.options.classPrefix + 'captions-text');
     1489                if (captionText) {
     1490                        captionText.style.fontSize = '';
     1491                        captionText.style.lineHeight = '';
     1492                        t.container.querySelector('.' + t.options.classPrefix + 'captions-position').style.bottom = '';
     1493                }
     1494                var event = (0, _general.createEvent)('exitedfullscreen', t.container);
     1495                t.container.dispatchEvent(event);
     1496        }
     1497});
     1498
     1499},{"16":16,"2":2,"23":23,"24":24,"25":25,"3":3,"4":4}],9:[function(_dereq_,module,exports){
     1500'use strict';
     1501
     1502var _document = _dereq_(2);
     1503
     1504var _document2 = _interopRequireDefault(_document);
     1505
     1506var _player = _dereq_(16);
     1507
     1508var _player2 = _interopRequireDefault(_player);
     1509
     1510var _i18n = _dereq_(4);
     1511
     1512var _i18n2 = _interopRequireDefault(_i18n);
     1513
     1514var _general = _dereq_(25);
     1515
     1516var _dom = _dereq_(24);
     1517
     1518function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     1519
     1520/**
     1521 * Play/Pause button
     1522 *
     1523 * This feature enables the displaying of a Play button in the control bar, and also contains logic to toggle its state
     1524 * between paused and playing.
     1525 */
     1526
     1527// Feature configuration
     1528Object.assign(_player.config, {
     1529        /**
     1530  * @type {?String}
     1531  */
     1532        playText: null,
     1533        /**
     1534  * @type {?String}
     1535  */
     1536        pauseText: null
     1537});
     1538
     1539Object.assign(_player2.default.prototype, {
     1540        /**
     1541  * Feature constructor.
     1542  *
     1543  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     1544  * @param {MediaElementPlayer} player
     1545  * @param {$} controls
     1546  * @param {$} layers
     1547  * @param {HTMLElement} media
     1548  * @public
     1549  */
     1550        buildplaypause: function buildplaypause(player, controls, layers, media) {
     1551
     1552                var t = this,
     1553                    op = t.options,
     1554                    playTitle = (0, _general.isString)(op.playText) ? op.playText : _i18n2.default.t('mejs.play'),
     1555                    pauseTitle = (0, _general.isString)(op.pauseText) ? op.pauseText : _i18n2.default.t('mejs.pause'),
     1556                    play = _document2.default.createElement('div');
     1557
     1558                play.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'playpause-button ' + t.options.classPrefix + 'play';
     1559                play.innerHTML = '<button type="button" aria-controls="' + t.id + '" title="' + playTitle + '" aria-label="' + pauseTitle + '" tabindex="0"></button>';
     1560                play.addEventListener('click', function () {
     1561                        if (media.paused) {
     1562                                media.play();
     1563                        } else {
     1564                                media.pause();
     1565                        }
     1566                });
     1567
     1568                var playBtn = play.querySelector('button');
     1569                t.addControlElement(play, 'playpause');
     1570
     1571                /**
     1572   * @private
     1573   * @param {String} which - token to determine new state of button
     1574   */
     1575                function togglePlayPause(which) {
     1576                        if ('play' === which) {
     1577                                (0, _dom.removeClass)(play, t.options.classPrefix + 'play');
     1578                                (0, _dom.removeClass)(play, t.options.classPrefix + 'replay');
     1579                                (0, _dom.addClass)(play, t.options.classPrefix + 'pause');
     1580                                playBtn.setAttribute('title', pauseTitle);
     1581                                playBtn.setAttribute('aria-label', pauseTitle);
     1582                        } else {
     1583
     1584                                (0, _dom.removeClass)(play, t.options.classPrefix + 'pause');
     1585                                (0, _dom.removeClass)(play, t.options.classPrefix + 'replay');
     1586                                (0, _dom.addClass)(play, t.options.classPrefix + 'play');
     1587                                playBtn.setAttribute('title', playTitle);
     1588                                playBtn.setAttribute('aria-label', playTitle);
     1589                        }
     1590                }
     1591
     1592                togglePlayPause('pse');
     1593
     1594                media.addEventListener('loadedmetadata', function () {
     1595                        togglePlayPause('pse');
     1596                });
     1597
     1598                media.addEventListener('play', function () {
     1599                        togglePlayPause('play');
     1600                });
     1601                media.addEventListener('playing', function () {
     1602                        togglePlayPause('play');
     1603                });
     1604
     1605                media.addEventListener('pause', function () {
     1606                        togglePlayPause('pse');
     1607                });
     1608                media.addEventListener('paused', function () {
     1609                        togglePlayPause('pse');
     1610                });
     1611
     1612                media.addEventListener('ended', function () {
     1613
     1614                        if (!player.options.loop) {
     1615                                (0, _dom.removeClass)(play, t.options.classPrefix + 'pause');
     1616                                (0, _dom.removeClass)(play, t.options.classPrefix + 'play');
     1617                                (0, _dom.addClass)(play, t.options.classPrefix + 'replay');
     1618                                playBtn.setAttribute('title', playTitle);
     1619                                playBtn.setAttribute('aria-label', playTitle);
     1620                        }
     1621                });
     1622        }
     1623});
     1624
     1625},{"16":16,"2":2,"24":24,"25":25,"4":4}],10:[function(_dereq_,module,exports){
     1626'use strict';
     1627
     1628var _document = _dereq_(2);
     1629
     1630var _document2 = _interopRequireDefault(_document);
     1631
     1632var _player = _dereq_(16);
     1633
     1634var _player2 = _interopRequireDefault(_player);
     1635
     1636var _i18n = _dereq_(4);
     1637
     1638var _i18n2 = _interopRequireDefault(_i18n);
     1639
     1640var _constants = _dereq_(23);
     1641
     1642var _time = _dereq_(28);
     1643
     1644var _dom = _dereq_(24);
     1645
     1646function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     1647
     1648/**
     1649 * Progress/loaded bar
     1650 *
     1651 * This feature creates a progress bar with a slider in the control bar, and updates it based on native events.
     1652 */
     1653
     1654// Feature configuration
     1655Object.assign(_player.config, {
     1656        /**
     1657  * Enable tooltip that shows time in progress bar
     1658  * @type {Boolean}
     1659  */
     1660        enableProgressTooltip: true
     1661});
     1662
     1663Object.assign(_player2.default.prototype, {
     1664
     1665        /**
     1666  * Feature constructor.
     1667  *
     1668  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     1669  * @param {MediaElementPlayer} player
     1670  * @param {$} controls
     1671  * @param {$} layers
     1672  * @param {HTMLElement} media
     1673  */
     1674        buildprogress: function buildprogress(player, controls, layers, media) {
     1675
     1676                var lastKeyPressTime = 0,
     1677                    mouseIsDown = false,
     1678                    startedPaused = false;
     1679
     1680                var t = this,
     1681                    autoRewindInitial = player.options.autoRewind,
     1682                    tooltip = player.options.enableProgressTooltip ? '<span class="' + t.options.classPrefix + 'time-float">' + ('<span class="' + t.options.classPrefix + 'time-float-current">00:00</span>') + ('<span class="' + t.options.classPrefix + 'time-float-corner"></span>') + '</span>' : "",
     1683                    rail = _document2.default.createElement('div');
     1684
     1685                rail.className = t.options.classPrefix + 'time-rail';
     1686                rail.innerHTML = '<span class="' + t.options.classPrefix + 'time-total ' + t.options.classPrefix + 'time-slider">' + ('<span class="' + t.options.classPrefix + 'time-buffering"></span>') + ('<span class="' + t.options.classPrefix + 'time-loaded"></span>') + ('<span class="' + t.options.classPrefix + 'time-current"></span>') + ('<span class="' + t.options.classPrefix + 'time-handle"></span>') + ('' + tooltip) + '</span>';
     1687
     1688                t.addControlElement(rail, 'progress');
     1689
     1690                controls.querySelector('.' + t.options.classPrefix + 'time-buffering').style.display = 'none';
     1691
     1692                t.rail = controls.querySelector('.' + t.options.classPrefix + 'time-rail');
     1693                t.total = controls.querySelector('.' + t.options.classPrefix + 'time-total');
     1694                t.loaded = controls.querySelector('.' + t.options.classPrefix + 'time-loaded');
     1695                t.current = controls.querySelector('.' + t.options.classPrefix + 'time-current');
     1696                t.handle = controls.querySelector('.' + t.options.classPrefix + 'time-handle');
     1697                t.timefloat = controls.querySelector('.' + t.options.classPrefix + 'time-float');
     1698                t.timefloatcurrent = controls.querySelector('.' + t.options.classPrefix + 'time-float-current');
     1699                t.slider = controls.querySelector('.' + t.options.classPrefix + 'time-slider');
     1700                t.newTime = 0;
     1701                t.forcedHandlePause = false;
     1702
     1703                /**
     1704   *
     1705   * @private
     1706   * @param {Event} e
     1707   */
     1708                var handleMouseMove = function handleMouseMove(e) {
     1709
     1710                        var totalStyles = getComputedStyle(t.total),
     1711                            offsetStyles = (0, _dom.offset)(t.total),
     1712                            width = parseFloat(totalStyles.width);
     1713
     1714                        var percentage = 0,
     1715                            pos = 0,
     1716                            x = void 0;
     1717
     1718                        // mouse or touch position relative to the object
     1719                        if (e.originalEvent && e.originalEvent.changedTouches) {
     1720                                x = e.originalEvent.changedTouches[0].pageX;
     1721                        } else if (e.changedTouches) {
     1722                                // for Zepto
     1723                                x = e.changedTouches[0].pageX;
     1724                        } else {
     1725                                x = e.pageX;
     1726                        }
     1727
     1728                        if (media.duration) {
     1729                                if (x < offsetStyles.left) {
     1730                                        x = offsetStyles.left;
     1731                                } else if (x > width + offsetStyles.left) {
     1732                                        x = width + offsetStyles.left;
     1733                                }
     1734
     1735                                pos = x - offsetStyles.left;
     1736                                percentage = pos / width;
     1737                                t.newTime = percentage <= 0.02 ? 0 : percentage * media.duration;
     1738
     1739                                // fake seek to where the mouse is
     1740                                if (mouseIsDown && media.currentTime !== null && t.newTime.toFixed(4) !== media.currentTime.toFixed(4)) {
     1741                                        t.setCurrentRailHandle(t.newTime);
     1742                                        t.updateCurrent(t.newTime);
     1743                                }
     1744
     1745                                // position floating time box
     1746                                if (!_constants.IS_IOS && !_constants.IS_ANDROID && t.timefloat) {
     1747                                        t.timefloat.style.left = pos + 'px';
     1748                                        t.timefloatcurrent.innerHTML = (0, _time.secondsToTimeCode)(t.newTime, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength);
     1749                                        t.timefloat.style.display = 'block';
     1750                                }
     1751                        }
     1752                },
     1753
     1754                /**
     1755   * Update elements in progress bar for accessibility purposes only when player is paused.
     1756   *
     1757   * This is to avoid attempts to repeat the time over and over again when media is playing.
     1758   * @private
     1759   */
     1760                updateSlider = function updateSlider() {
     1761
     1762                        var seconds = media.currentTime,
     1763                            timeSliderText = _i18n2.default.t('mejs.time-slider'),
     1764                            time = (0, _time.secondsToTimeCode)(seconds, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength),
     1765                            duration = media.duration;
     1766
     1767                        t.slider.setAttribute('role', 'slider');
     1768                        t.slider.tabIndex = 0;
     1769
     1770                        if (media.paused) {
     1771                                t.slider.setAttribute('aria-label', timeSliderText);
     1772                                t.slider.setAttribute('aria-valuemin', 0);
     1773                                t.slider.setAttribute('aria-valuemax', duration);
     1774                                t.slider.setAttribute('aria-valuenow', seconds);
     1775                                t.slider.setAttribute('aria-valuetext', time);
     1776                        } else {
     1777                                t.slider.removeAttribute('aria-label');
     1778                                t.slider.removeAttribute('aria-valuemin');
     1779                                t.slider.removeAttribute('aria-valuemax');
     1780                                t.slider.removeAttribute('aria-valuenow');
     1781                                t.slider.removeAttribute('aria-valuetext');
     1782                        }
     1783                },
     1784
     1785                /**
     1786   *
     1787   * @private
     1788   */
     1789                restartPlayer = function restartPlayer() {
     1790                        var now = new Date();
     1791                        if (now - lastKeyPressTime >= 1000) {
     1792                                media.play();
     1793                        }
     1794                },
     1795                    handleMouseup = function handleMouseup() {
     1796
     1797                        if (mouseIsDown && media.currentTime !== null && t.newTime.toFixed(4) !== media.currentTime.toFixed(4)) {
     1798                                media.setCurrentTime(t.newTime);
     1799                                player.setCurrentRail();
     1800                                t.updateCurrent(t.newTime);
     1801                        }
     1802                        if (t.forcedHandlePause) {
     1803                                t.media.play();
     1804                        }
     1805                        t.forcedHandlePause = false;
     1806                };
     1807
     1808                // Events
     1809                t.slider.addEventListener('focus', function () {
     1810                        player.options.autoRewind = false;
     1811                });
     1812                t.slider.addEventListener('blur', function () {
     1813                        player.options.autoRewind = autoRewindInitial;
     1814                });
     1815                t.slider.addEventListener('keydown', function (e) {
     1816
     1817                        if (new Date() - lastKeyPressTime >= 1000) {
     1818                                startedPaused = media.paused;
     1819                        }
     1820
     1821                        if (t.options.keyActions.length) {
     1822
     1823                                var keyCode = e.which || e.keyCode || 0,
     1824                                    duration = media.duration,
     1825                                    seekForward = player.options.defaultSeekForwardInterval(media),
     1826                                    seekBackward = player.options.defaultSeekBackwardInterval(media);
     1827
     1828                                var seekTime = media.currentTime;
     1829
     1830                                switch (keyCode) {
     1831                                        case 37: // left
     1832                                        case 40:
     1833                                                // Down
     1834                                                if (media.duration !== Infinity) {
     1835                                                        seekTime -= seekBackward;
     1836                                                }
     1837                                                break;
     1838                                        case 39: // Right
     1839                                        case 38:
     1840                                                // Up
     1841                                                if (media.duration !== Infinity) {
     1842                                                        seekTime += seekForward;
     1843                                                }
     1844                                                break;
     1845                                        case 36:
     1846                                                // Home
     1847                                                seekTime = 0;
     1848                                                break;
     1849                                        case 35:
     1850                                                // end
     1851                                                seekTime = duration;
     1852                                                break;
     1853                                        case 32:
     1854                                                // space
     1855                                                if (!_constants.IS_FIREFOX) {
     1856                                                        if (media.paused) {
     1857                                                                media.play();
     1858                                                        } else {
     1859                                                                media.pause();
     1860                                                        }
     1861                                                }
     1862                                                return;
     1863                                        case 13:
     1864                                                // enter
     1865                                                if (media.paused) {
     1866                                                        media.play();
     1867                                                } else {
     1868                                                        media.pause();
     1869                                                }
     1870                                                return;
     1871                                        default:
     1872                                                return;
     1873                                }
     1874
     1875                                seekTime = seekTime < 0 ? 0 : seekTime >= duration ? duration : Math.floor(seekTime);
     1876                                lastKeyPressTime = new Date();
     1877                                if (!startedPaused) {
     1878                                        media.pause();
     1879                                }
     1880
     1881                                if (seekTime < media.duration && !startedPaused) {
     1882                                        setTimeout(restartPlayer, 1100);
     1883                                }
     1884
     1885                                media.setCurrentTime(seekTime);
     1886
     1887                                e.preventDefault();
     1888                                e.stopPropagation();
     1889                        }
     1890                });
     1891
     1892                var events = ['mousedown', 'touchstart'];
     1893
     1894                // Required to manipulate mouse movements that require drag 'n' drop properly
     1895                t.slider.addEventListener('dragstart', function () {
     1896                        return false;
     1897                });
     1898
     1899                for (var i = 0, total = events.length; i < total; i++) {
     1900                        t.slider.addEventListener(events[i], function (e) {
     1901                                t.forcedHandlePause = false;
     1902                                if (media.duration !== Infinity) {
     1903                                        // only handle left clicks or touch
     1904                                        if (e.which === 1 || e.which === 0) {
     1905
     1906                                                if (!media.paused) {
     1907                                                        t.media.pause();
     1908                                                        t.forcedHandlePause = true;
     1909                                                }
     1910
     1911                                                mouseIsDown = true;
     1912                                                handleMouseMove(e);
     1913                                                t.globalBind('mousemove.dur touchmove.dur', function (event) {
     1914                                                        var target = event.target;
     1915                                                        if (target === t.slider || target.closest('.' + t.options.classPrefix + 'time-slider')) {
     1916                                                                handleMouseMove(event);
     1917                                                        }
     1918                                                });
     1919                                                t.globalBind('mouseup.dur touchend.dur', function () {
     1920                                                        handleMouseup();
     1921                                                        mouseIsDown = false;
     1922                                                        if (t.timefloat) {
     1923                                                                t.timefloat.style.display = 'none';
     1924                                                        }
     1925                                                        t.globalUnbind('mousemove.dur touchmove.dur mouseup.dur touchend.dur');
     1926                                                });
     1927                                        }
     1928                                }
     1929                        });
     1930                }
     1931                t.slider.addEventListener('mouseenter', function (e) {
     1932                        if (e.target === t.slider && media.duration !== Infinity) {
     1933                                t.globalBind('mousemove.dur', function (event) {
     1934                                        var target = event.target;
     1935                                        if (target === t.slider || target.closest('.' + t.options.classPrefix + 'time-slider')) {
     1936                                                handleMouseMove(event);
     1937                                        }
     1938                                });
     1939                                if (t.timefloat && !_constants.IS_IOS && !_constants.IS_ANDROID) {
     1940                                        t.timefloat.style.display = 'block';
     1941                                }
     1942                        }
     1943                });
     1944                t.slider.addEventListener('mouseleave', function () {
     1945                        if (media.duration !== Infinity) {
     1946                                if (!mouseIsDown) {
     1947                                        t.globalUnbind('mousemove.dur');
     1948                                        if (t.timefloat) {
     1949                                                t.timefloat.style.display = 'none';
     1950                                        }
     1951                                }
     1952                        }
     1953                });
     1954
     1955                // loading
     1956                // If media is does not have a finite duration, remove progress bar interaction
     1957                // and indicate that is a live broadcast
     1958                media.addEventListener('progress', function (e) {
     1959                        var broadcast = controls.querySelector('.' + t.options.classPrefix + 'broadcast');
     1960                        if (media.duration !== Infinity) {
     1961                                if (broadcast) {
     1962                                        t.slider.style.display = '';
     1963                                        broadcast.remove();
     1964                                }
     1965
     1966                                player.setProgressRail(e);
     1967                                if (!t.forcedHandlePause) {
     1968                                        player.setCurrentRail(e);
     1969                                }
     1970                        } else if (!broadcast) {
     1971                                var label = _document2.default.createElement('span');
     1972                                label.className = t.options.classPrefix + 'broadcast';
     1973                                label.innerText = _i18n2.default.t('mejs.live-broadcast');
     1974                                t.slider.style.display = 'none';
     1975                        }
     1976                });
     1977
     1978                // current time
     1979                media.addEventListener('timeupdate', function (e) {
     1980                        var broadcast = controls.querySelector('.' + t.options.classPrefix + 'broadcast');
     1981                        if (media.duration !== Infinity) {
     1982                                if (broadcast) {
     1983                                        t.slider.style.display = '';
     1984                                        broadcast.remove();
     1985                                }
     1986
     1987                                player.setProgressRail(e);
     1988                                if (!t.forcedHandlePause) {
     1989                                        player.setCurrentRail(e);
     1990                                }
     1991                                updateSlider(e);
     1992                        } else if (!broadcast) {
     1993                                var label = _document2.default.createElement('span');
     1994                                label.className = t.options.classPrefix + 'broadcast';
     1995                                label.innerText = _i18n2.default.t('mejs.live-broadcast');
     1996                                controls.querySelector('.' + t.options.classPrefix + 'time-rail').appendChild(label);
     1997                                t.slider.style.display = 'none';
     1998                        }
     1999                });
     2000
     2001                t.container.addEventListener('controlsresize', function (e) {
     2002                        if (media.duration !== Infinity) {
     2003                                player.setProgressRail(e);
     2004                                if (!t.forcedHandlePause) {
     2005                                        player.setCurrentRail(e);
     2006                                }
     2007                        }
     2008                });
     2009        },
     2010
     2011
     2012        /**
     2013  * Calculate the progress on the media and update progress bar's width
     2014  *
     2015  * @param {Event} e
     2016  */
     2017        setProgressRail: function setProgressRail(e) {
     2018
     2019                var percent = null;
     2020
     2021                var t = this,
     2022                    target = e !== undefined ? e.target : t.media;
     2023
     2024                // newest HTML5 spec has buffered array (FF4, Webkit)
     2025                if (target && target.buffered && target.buffered.length > 0 && target.buffered.end && target.duration) {
     2026                        // account for a real array with multiple values - always read the end of the last buffer
     2027                        percent = target.buffered.end(target.buffered.length - 1) / target.duration;
     2028                }
     2029                // Some browsers (e.g., FF3.6 and Safari 5) cannot calculate target.bufferered.end()
     2030                // to be anything other than 0. If the byte count is available we use this instead.
     2031                // Browsers that support the else if do not seem to have the bufferedBytes value and
     2032                // should skip to there. Tested in Safari 5, Webkit head, FF3.6, Chrome 6, IE 7/8.
     2033                else if (target && target.bytesTotal !== undefined && target.bytesTotal > 0 && target.bufferedBytes !== undefined) {
     2034                                percent = target.bufferedBytes / target.bytesTotal;
     2035                        }
     2036                        // Firefox 3 with an Ogg file seems to go this way
     2037                        else if (e && e.lengthComputable && e.total !== 0) {
     2038                                        percent = e.loaded / e.total;
     2039                                }
     2040
     2041                // finally update the progress bar
     2042                if (percent !== null) {
     2043                        percent = Math.min(1, Math.max(0, percent));
     2044                        // update loaded bar
     2045                        if (t.loaded && t.total) {
     2046                                t.loaded.style.width = percent * 100 + '%';
     2047                        }
     2048                }
     2049        },
     2050
     2051        /**
     2052  * Update the slider's width depending on the time assigned
     2053  *
     2054  * @param {Number} fakeTime
     2055  */
     2056        setCurrentRailHandle: function setCurrentRailHandle(fakeTime) {
     2057                var t = this;
     2058                t.setCurrentRailMain(t, fakeTime);
     2059        },
     2060
     2061        /**
     2062  * Update the slider's width depending on the current time
     2063  *
     2064  */
     2065        setCurrentRail: function setCurrentRail() {
     2066                var t = this;
     2067                t.setCurrentRailMain(t);
     2068        },
     2069
     2070        /**
     2071  * Method that handles the calculation of the width of the rail.
     2072  *
     2073  * @param {MediaElementPlayer} t
     2074  * @param {?Number} fakeTime
     2075  */
     2076        setCurrentRailMain: function setCurrentRailMain(t, fakeTime) {
     2077                if (t.media.currentTime !== undefined && t.media.duration) {
     2078                        var nTime = typeof fakeTime === 'undefined' ? t.media.currentTime : fakeTime;
     2079
     2080                        // update bar and handle
     2081                        if (t.total && t.handle) {
     2082                                var newWidth = Math.round(parseFloat(getComputedStyle(t.total).width) * nTime / t.media.duration),
     2083                                    handlePos = newWidth - Math.round(t.handle.offsetWidth / 2);
     2084
     2085                                newWidth = nTime / t.media.duration * 100;
     2086                                t.current.style.width = newWidth + '%';
     2087                                t.handle.style.left = handlePos + 'px';
     2088                        }
     2089                }
     2090        }
     2091});
     2092
     2093},{"16":16,"2":2,"23":23,"24":24,"28":28,"4":4}],11:[function(_dereq_,module,exports){
     2094'use strict';
     2095
     2096var _document = _dereq_(2);
     2097
     2098var _document2 = _interopRequireDefault(_document);
     2099
     2100var _player = _dereq_(16);
     2101
     2102var _player2 = _interopRequireDefault(_player);
     2103
     2104var _time = _dereq_(28);
     2105
     2106var _dom = _dereq_(24);
     2107
     2108function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     2109
     2110/**
     2111 * Current/duration times
     2112 *
     2113 * This feature creates/updates the duration and progress times in the control bar, based on native events.
     2114 */
     2115
     2116// Feature configuration
     2117Object.assign(_player.config, {
     2118        /**
     2119  * The initial duration
     2120  * @type {Number}
     2121  */
     2122        duration: 0,
     2123        /**
     2124  * @type {String}
     2125  */
     2126        timeAndDurationSeparator: '<span> | </span>'
     2127});
     2128
     2129Object.assign(_player2.default.prototype, {
     2130
     2131        /**
     2132  * Current time constructor.
     2133  *
     2134  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     2135  * @param {MediaElementPlayer} player
     2136  * @param {$} controls
     2137  * @param {$} layers
     2138  * @param {HTMLElement} media
     2139  */
     2140        buildcurrent: function buildcurrent(player, controls, layers, media) {
     2141                var t = this,
     2142                    time = _document2.default.createElement('div');
     2143
     2144                time.className = t.options.classPrefix + 'time';
     2145                time.setAttribute('role', 'timer');
     2146                time.setAttribute('aria-live', 'off');
     2147                time.innerHTML = '<span class="' + t.options.classPrefix + 'currenttime">' + (0, _time.secondsToTimeCode)(0, player.options.alwaysShowHours, player.options.showTimecodeFrameCount, player.options.framesPerSecond, player.options.secondsDecimalLength) + '</span>';
     2148
     2149                t.addControlElement(time, 'current');
     2150
     2151                media.addEventListener('timeupdate', function () {
     2152                        if (t.controlsAreVisible) {
     2153                                player.updateCurrent();
     2154                        }
     2155                });
     2156        },
     2157
     2158
     2159        /**
     2160  * Duration time constructor.
     2161  *
     2162  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     2163  * @param {MediaElementPlayer} player
     2164  * @param {$} controls
     2165  * @param {$} layers
     2166  * @param {HTMLElement} media
     2167  */
     2168        buildduration: function buildduration(player, controls, layers, media) {
     2169
     2170                var t = this,
     2171                    currTime = controls.lastChild.querySelector('.' + t.options.classPrefix + 'currenttime');
     2172
     2173                if (currTime) {
     2174                        controls.querySelector('.' + t.options.classPrefix + 'time').innerHTML += t.options.timeAndDurationSeparator + '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength) + '</span>');
     2175                } else {
     2176
     2177                        // add class to current time
     2178                        if (controls.querySelector('.' + t.options.classPrefix + 'currenttime')) {
     2179                                (0, _dom.addClass)(controls.querySelector('.' + t.options.classPrefix + 'currenttime').parentNode, t.options.classPrefix + 'currenttime-container');
     2180                        }
     2181
     2182                        var duration = _document2.default.createElement('div');
     2183                        duration.className = t.options.classPrefix + 'time ' + t.options.classPrefix + 'duration-container';
     2184                        duration.innerHTML = '<span class="' + t.options.classPrefix + 'duration">' + ((0, _time.secondsToTimeCode)(t.options.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength) + '</span>');
     2185
     2186                        t.addControlElement(duration, 'duration');
     2187                }
     2188
     2189                media.addEventListener('timeupdate', function () {
     2190                        if (t.controlsAreVisible) {
     2191                                player.updateDuration();
     2192                        }
     2193                });
     2194        },
     2195
     2196
     2197        /**
     2198  * Update the current time and output it in format 00:00
     2199  *
     2200  */
     2201        updateCurrent: function updateCurrent() {
     2202                var t = this;
     2203
     2204                var currentTime = t.media.currentTime;
     2205
     2206                if (isNaN(currentTime)) {
     2207                        currentTime = 0;
     2208                }
     2209
     2210                if (t.controls.querySelector('.' + t.options.classPrefix + 'currenttime')) {
     2211                        t.controls.querySelector('.' + t.options.classPrefix + 'currenttime').innerText = (0, _time.secondsToTimeCode)(currentTime, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength);
     2212                }
     2213        },
     2214
     2215
     2216        /**
     2217  * Update the duration time and output it in format 00:00
     2218  *
     2219  */
     2220        updateDuration: function updateDuration() {
     2221                var t = this;
     2222
     2223                var duration = t.media.duration;
     2224
     2225                if (isNaN(duration) || duration === Infinity || duration < 0) {
     2226                        t.media.duration = t.options.duration = duration = 0;
     2227                }
     2228
     2229                if (t.options.duration > 0) {
     2230                        duration = t.options.duration;
     2231                }
     2232
     2233                var timecode = (0, _time.secondsToTimeCode)(duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond, t.options.secondsDecimalLength);
     2234
     2235                // Toggle long-video class if time code is >5 digits (MM:SS)
     2236                if (timecode.length > 5) {
     2237                        (0, _dom.toggleClass)(t.container, t.options.classPrefix + 'long-video');
     2238                }
     2239
     2240                if (t.controls.querySelector('.' + t.options.classPrefix + 'duration') && duration > 0) {
     2241                        t.controls.querySelector('.' + t.options.classPrefix + 'duration').innerHTML = timecode;
     2242                }
     2243        }
     2244});
     2245
     2246},{"16":16,"2":2,"24":24,"28":28}],12:[function(_dereq_,module,exports){
     2247'use strict';
     2248
     2249var _document = _dereq_(2);
     2250
     2251var _document2 = _interopRequireDefault(_document);
     2252
     2253var _mejs = _dereq_(6);
     2254
     2255var _mejs2 = _interopRequireDefault(_mejs);
     2256
     2257var _i18n = _dereq_(4);
     2258
     2259var _i18n2 = _interopRequireDefault(_i18n);
     2260
     2261var _player = _dereq_(16);
     2262
     2263var _player2 = _interopRequireDefault(_player);
     2264
     2265var _time = _dereq_(28);
     2266
     2267var _general = _dereq_(25);
     2268
     2269var _dom = _dereq_(24);
     2270
     2271function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     2272
     2273/**
     2274 * Closed Captions (CC) button
     2275 *
     2276 * This feature enables the displaying of a CC button in the control bar, and also contains the methods to start media
     2277 * with a certain language (if available), toggle captions, etc.
     2278 */
     2279
     2280// Feature configuration
     2281Object.assign(_player.config, {
     2282        /**
     2283  * Default language to start media using ISO 639-2 Language Code List (en, es, it, etc.)
     2284  * If there are multiple tracks for one language, the last track node found is activated
     2285  * @see https://www.loc.gov/standards/iso639-2/php/code_list.php
     2286  * @type {String}
     2287  */
     2288        startLanguage: '',
     2289        /**
     2290  * @type {?String}
     2291  */
     2292        tracksText: null,
     2293        /**
     2294  * @type {?String}
     2295  */
     2296        chaptersText: null,
     2297        /**
     2298  * Avoid to screen reader speak captions over an audio track.
     2299  *
     2300  * @type {Boolean}
     2301  */
     2302        tracksAriaLive: false,
     2303        /**
     2304  * Remove the [cc] button when no track nodes are present
     2305  * @type {Boolean}
     2306  */
     2307        hideCaptionsButtonWhenEmpty: true,
     2308        /**
     2309  * Change captions to pop-up if true and only one track node is found
     2310  * @type {Boolean}
     2311  */
     2312        toggleCaptionsButtonWhenOnlyOne: false,
     2313        /**
     2314  * @type {String}
     2315  */
     2316        slidesSelector: ''
     2317});
     2318
     2319Object.assign(_player2.default.prototype, {
     2320
     2321        /**
     2322  * @type {Boolean}
     2323  */
     2324        hasChapters: false,
     2325
     2326        /**
     2327  * Feature constructor.
     2328  *
     2329  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     2330  * @param {MediaElementPlayer} player
     2331  * @param {$} controls
     2332  * @param {$} layers
     2333  * @param {HTMLElement} media
     2334  */
     2335        buildtracks: function buildtracks(player, controls, layers, media) {
     2336                if (player.tracks.length === 0) {
     2337                        return;
     2338                }
     2339
     2340                var t = this,
     2341                    attr = t.options.tracksAriaLive ? ' role="log" aria-live="assertive" aria-atomic="false"' : '',
     2342                    tracksTitle = (0, _general.isString)(t.options.tracksText) ? t.options.tracksText : _i18n2.default.t('mejs.captions-subtitles'),
     2343                    chaptersTitle = (0, _general.isString)(t.options.chaptersText) ? t.options.chaptersText : _i18n2.default.t('mejs.captions-chapters'),
     2344                    total = player.tracks.length;
     2345
     2346                // If browser will do native captions, prefer mejs captions, loop through tracks and hide
     2347                if (t.domNode.textTracks) {
     2348                        for (var i = t.domNode.textTracks.length - 1; i >= 0; i--) {
     2349                                t.domNode.textTracks[i].mode = 'hidden';
     2350                        }
     2351                }
     2352
     2353                t.cleartracks(player);
     2354
     2355                player.captions = _document2.default.createElement('div');
     2356                player.captions.className = t.options.classPrefix + 'captions-layer ' + t.options.classPrefix + 'layer';
     2357                player.captions.innerHTML = '<div class="' + t.options.classPrefix + 'captions-position ' + t.options.classPrefix + 'captions-position-hover"' + attr + '>' + ('<span class="' + t.options.classPrefix + 'captions-text"></span>') + '</div>';
     2358                player.captions.style.display = 'none';
     2359                layers.insertBefore(player.captions, layers.firstChild);
     2360
     2361                player.captionsText = player.captions.querySelector('.' + t.options.classPrefix + 'captions-text');
     2362
     2363                player.captionsButton = _document2.default.createElement('div');
     2364                player.captionsButton.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'captions-button';
     2365                player.captionsButton.innerHTML = '<button type="button" aria-controls="' + t.id + '" title="' + tracksTitle + '" aria-label="' + tracksTitle + '" tabindex="0"></button>' + ('<div class="' + t.options.classPrefix + 'captions-selector ' + t.options.classPrefix + 'offscreen">') + ('<ul class="' + t.options.classPrefix + 'captions-selector-list">') + ('<li class="' + t.options.classPrefix + 'captions-selector-list-item">') + ('<input type="radio" class="' + t.options.classPrefix + 'captions-selector-input" ') + ('name="' + player.id + '_captions" id="' + player.id + '_captions_none" ') + 'value="none" checked disabled>' + ('<label class="' + t.options.classPrefix + 'captions-selector-label ') + (t.options.classPrefix + 'captions-selected" ') + ('for="' + player.id + '_captions_none">' + _i18n2.default.t('mejs.none') + '</label>') + '</li>' + '</ul>' + '</div>';
     2366
     2367                t.addControlElement(player.captionsButton, 'tracks');
     2368
     2369                player.captionsButton.querySelector('.' + t.options.classPrefix + 'captions-selector-list-item').disabled = false;
     2370
     2371                player.chaptersButton = _document2.default.createElement('div');
     2372                player.chaptersButton.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'chapters-button';
     2373                player.chaptersButton.innerHTML = '<button type="button" aria-controls="' + t.id + '" title="' + chaptersTitle + '" aria-label="' + chaptersTitle + '" tabindex="0"></button>' + ('<div class="' + t.options.classPrefix + 'chapters-selector ' + t.options.classPrefix + 'offscreen">') + ('<ul class="' + t.options.classPrefix + 'chapters-selector-list"></ul>') + '</div>';
     2374
     2375                var subtitleCount = 0;
     2376
     2377                for (var _i = 0; _i < total; _i++) {
     2378                        var kind = player.tracks[_i].kind;
     2379                        if (kind === 'subtitles' || kind === 'captions') {
     2380                                subtitleCount++;
     2381                        } else if (kind === 'chapters' && !controls.querySelector('.' + t.options.classPrefix + 'chapter-selector')) {
     2382                                player.captionsButton.parentNode.insertBefore(player.chaptersButton, player.captionsButton);
     2383                        }
     2384                }
     2385
     2386                player.trackToLoad = -1;
     2387                player.selectedTrack = null;
     2388                player.isLoadingTrack = false;
     2389
     2390                // add to list
     2391                for (var _i2 = 0; _i2 < total; _i2++) {
     2392                        var _kind = player.tracks[_i2].kind;
     2393                        if (_kind === 'subtitles' || _kind === 'captions') {
     2394                                player.addTrackButton(player.tracks[_i2].trackId, player.tracks[_i2].srclang, player.tracks[_i2].label);
     2395                        }
     2396                }
     2397
     2398                // start loading tracks
     2399                player.loadNextTrack();
     2400
     2401                var inEvents = ['mouseenter', 'focusin'],
     2402                    outEvents = ['mouseleave', 'focusout'];
     2403
     2404                // if only one language then just make the button a toggle
     2405                if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitleCount === 1) {
     2406                        // click
     2407                        player.captionsButton.addEventListener('click', function () {
     2408                                var trackId = 'none';
     2409                                if (player.selectedTrack === null) {
     2410                                        trackId = player.tracks[0].trackId;
     2411                                }
     2412                                player.setTrack(trackId);
     2413                        });
     2414                } else {
     2415                        var labels = player.captionsButton.querySelectorAll('.' + t.options.classPrefix + 'captions-selector-label'),
     2416                            captions = player.captionsButton.querySelectorAll('input[type=radio]');
     2417                        // hover or keyboard focus
     2418                        for (var _i3 = 0, _total = inEvents.length; _i3 < _total; _i3++) {
     2419                                player.captionsButton.addEventListener(inEvents[_i3], function () {
     2420                                        (0, _dom.removeClass)(this.querySelector('.' + t.options.classPrefix + 'captions-selector'), t.options.classPrefix + 'offscreen');
     2421                                });
     2422                        }
     2423
     2424                        for (var _i4 = 0, _total2 = outEvents.length; _i4 < _total2; _i4++) {
     2425                                player.captionsButton.addEventListener(outEvents[_i4], function () {
     2426                                        (0, _dom.addClass)(this.querySelector('.' + t.options.classPrefix + 'captions-selector'), t.options.classPrefix + 'offscreen');
     2427                                });
     2428                        }
     2429
     2430                        // handle clicks to the language radio buttons
     2431                        for (var _i5 = 0, _total3 = captions.length; _i5 < _total3; _i5++) {
     2432                                captions[_i5].addEventListener('click', function () {
     2433                                        // value is trackId, same as the actual id, and we're using it here
     2434                                        // because the "none" checkbox doesn't have a trackId
     2435                                        // to use, but we want to know when "none" is clicked
     2436                                        player.setTrack(this.value);
     2437                                });
     2438                        }
     2439
     2440                        for (var _i6 = 0, _total4 = labels.length; _i6 < _total4; _i6++) {
     2441                                labels[_i6].addEventListener('click', function () {
     2442                                        var radio = (0, _dom.siblings)(this, function (el) {
     2443                                                return el.tagName === 'INPUT';
     2444                                        })[0],
     2445                                            event = (0, _general.createEvent)('click', radio);
     2446                                        radio.dispatchEvent(event);
     2447                                });
     2448                        }
     2449
     2450                        //Allow up/down arrow to change the selected radio without changing the volume.
     2451                        player.captionsButton.addEventListener('keydown', function (e) {
     2452                                e.stopPropagation();
     2453                        });
     2454                }
     2455
     2456                for (var _i7 = 0, _total5 = inEvents.length; _i7 < _total5; _i7++) {
     2457                        player.chaptersButton.addEventListener(inEvents[_i7], function () {
     2458                                if (this.querySelector('.' + t.options.classPrefix + 'chapters-selector-list').childNodes.length) {
     2459                                        (0, _dom.removeClass)(this.querySelector('.' + t.options.classPrefix + 'chapters-selector'), t.options.classPrefix + 'offscreen');
     2460                                }
     2461                        });
     2462                }
     2463
     2464                for (var _i8 = 0, _total6 = outEvents.length; _i8 < _total6; _i8++) {
     2465                        player.chaptersButton.addEventListener(outEvents[_i8], function () {
     2466                                (0, _dom.addClass)(this.querySelector('.' + t.options.classPrefix + 'chapters-selector'), t.options.classPrefix + 'offscreen');
     2467                        });
     2468                }
     2469
     2470                //Allow up/down arrow to change the selected radio without changing the volume.
     2471                player.chaptersButton.addEventListener('keydown', function (e) {
     2472                        e.stopPropagation();
     2473                });
     2474
     2475                if (!player.options.alwaysShowControls) {
     2476                        // move with controls
     2477                        player.container.addEventListener('controlsshown', function () {
     2478                                // push captions above controls
     2479                                (0, _dom.addClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
     2480                        });
     2481
     2482                        player.container.addEventListener('controlshidden', function () {
     2483                                if (!media.paused) {
     2484                                        // move back to normal place
     2485                                        (0, _dom.removeClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
     2486                                }
     2487                        });
     2488                } else {
     2489                        (0, _dom.addClass)(player.container.querySelector('.' + t.options.classPrefix + 'captions-position'), t.options.classPrefix + 'captions-position-hover');
     2490                }
     2491
     2492                media.addEventListener('timeupdate', function () {
     2493                        player.displayCaptions();
     2494                });
     2495
     2496                if (player.options.slidesSelector !== '') {
     2497                        player.slidesContainer = _document2.default.querySelectorAll(player.options.slidesSelector);
     2498
     2499                        media.addEventListener('timeupdate', function () {
     2500                                player.displaySlides();
     2501                        });
     2502                }
     2503        },
     2504
     2505
     2506        /**
     2507  * Feature destructor.
     2508  *
     2509  * Always has to be prefixed with `clean` and the name that was used in MepDefaults.features list
     2510  * @param {MediaElementPlayer} player
     2511  */
     2512        cleartracks: function cleartracks(player) {
     2513                if (player) {
     2514                        if (player.captions) {
     2515                                player.captions.remove();
     2516                        }
     2517                        if (player.chapters) {
     2518                                player.chapters.remove();
     2519                        }
     2520                        if (player.captionsText) {
     2521                                player.captionsText.remove();
     2522                        }
     2523                        if (player.captionsButton) {
     2524                                player.captionsButton.remove();
     2525                        }
     2526                        if (player.chaptersButton) {
     2527                                player.chaptersButton.remove();
     2528                        }
     2529                }
     2530        },
     2531        rebuildtracks: function rebuildtracks() {
     2532                var t = this;
     2533                t.findTracks();
     2534                t.buildtracks(t, t.controls, t.layers, t.media);
     2535        },
     2536        findTracks: function findTracks() {
     2537                var t = this,
     2538                    tracktags = t.node.querySelectorAll('track'),
     2539                    total = tracktags.length;
     2540
     2541                // store for use by plugins
     2542                t.tracks = [];
     2543                for (var i = 0; i < total; i++) {
     2544                        var track = tracktags[i],
     2545                            srclang = track.getAttribute('srclang').toLowerCase() || '',
     2546                            trackId = t.id + '_track_' + i + '_' + track.getAttribute('kind') + '_' + srclang;
     2547                        t.tracks.push({
     2548                                trackId: trackId,
     2549                                srclang: srclang,
     2550                                src: track.getAttribute('src'),
     2551                                kind: track.getAttribute('kind'),
     2552                                label: track.getAttribute('label') || '',
     2553                                entries: [],
     2554                                isLoaded: false
     2555                        });
     2556                }
     2557        },
     2558
     2559
     2560        /**
     2561  *
     2562  * @param {String} trackId, or "none" to disable captions
     2563  */
     2564        setTrack: function setTrack(trackId) {
     2565
     2566                var t = this,
     2567                    radios = t.captionsButton.querySelectorAll('input[type="radio"]'),
     2568                    captions = t.captionsButton.querySelectorAll('.' + t.options.classPrefix + 'captions-selected'),
     2569                    track = t.captionsButton.querySelector('input[value="' + trackId + '"]');
     2570
     2571                for (var i = 0, total = radios.length; i < total; i++) {
     2572                        radios[i].checked = false;
     2573                }
     2574
     2575                for (var _i9 = 0, _total7 = captions.length; _i9 < _total7; _i9++) {
     2576                        (0, _dom.removeClass)(captions[_i9], t.options.classPrefix + 'captions-selected');
     2577                }
     2578
     2579                track.checked = true;
     2580                var labels = (0, _dom.siblings)(track, function (el) {
     2581                        return (0, _dom.hasClass)(el, t.options.classPrefix + 'captions-selector-label');
     2582                });
     2583                for (var _i10 = 0, _total8 = labels.length; _i10 < _total8; _i10++) {
     2584                        (0, _dom.addClass)(labels[_i10], t.options.classPrefix + 'captions-selected');
     2585                }
     2586
     2587                if (trackId === 'none') {
     2588                        t.selectedTrack = null;
     2589                        (0, _dom.removeClass)(t.captionsButton, t.options.classPrefix + 'captions-enabled');
     2590                } else {
     2591                        for (var _i11 = 0, _total9 = t.tracks.length; _i11 < _total9; _i11++) {
     2592                                var _track = t.tracks[_i11];
     2593                                if (_track.trackId === trackId) {
     2594                                        if (t.selectedTrack === null) {
     2595                                                (0, _dom.addClass)(t.captionsButton, t.options.classPrefix + 'captions-enabled');
     2596                                        }
     2597                                        t.selectedTrack = _track;
     2598                                        t.captions.setAttribute('lang', t.selectedTrack.srclang);
     2599                                        t.displayCaptions();
     2600                                        break;
     2601                                }
     2602                        }
     2603                }
     2604
     2605                var event = (0, _general.createEvent)('captionschange', t.media);
     2606                event.detail.caption = t.selectedTrack;
     2607                t.media.dispatchEvent(event);
     2608        },
     2609
     2610
     2611        /**
     2612  *
     2613  */
     2614        loadNextTrack: function loadNextTrack() {
     2615                var t = this;
     2616
     2617                t.trackToLoad++;
     2618                if (t.trackToLoad < t.tracks.length) {
     2619                        t.isLoadingTrack = true;
     2620                        t.loadTrack(t.trackToLoad);
     2621                } else {
     2622                        // add done?
     2623                        t.isLoadingTrack = false;
     2624                        t.checkForTracks();
     2625                }
     2626        },
     2627
     2628
     2629        /**
     2630  *
     2631  * @param index
     2632  */
     2633        loadTrack: function loadTrack(index) {
     2634                var t = this,
     2635                    track = t.tracks[index];
     2636
     2637                if (track !== undefined && (track.src !== undefined || track.src !== "")) {
     2638                        (0, _dom.ajax)(track.src, 'text', function (d) {
     2639
     2640                                // parse the loaded file
     2641                                track.entries = typeof d === 'string' && /<tt\s+xml/ig.exec(d) ? _mejs2.default.TrackFormatParser.dfxp.parse(d) : _mejs2.default.TrackFormatParser.webvtt.parse(d);
     2642
     2643                                track.isLoaded = true;
     2644
     2645                                t.enableTrackButton(track);
     2646                                t.loadNextTrack();
     2647
     2648                                if (track.kind === 'slides') {
     2649                                        t.setupSlides(track);
     2650                                }
     2651                                // Load by default the first track with `chapters` kind
     2652                                else if (track.kind === 'chapters' && !t.hasChapters) {
     2653                                                t.drawChapters(track);
     2654                                                t.hasChapters = true;
     2655                                        }
     2656                        }, function () {
     2657                                t.removeTrackButton(track.trackId);
     2658                                t.loadNextTrack();
     2659                        });
     2660                }
     2661        },
     2662
     2663
     2664        /**
     2665  *
     2666  * @param {String} track - The language code
     2667  */
     2668        enableTrackButton: function enableTrackButton(track) {
     2669                var t = this,
     2670                    lang = track.srclang,
     2671                    target = _document2.default.getElementById('' + track.trackId);
     2672
     2673                if (!target) {
     2674                        return;
     2675                }
     2676
     2677                var label = track.label;
     2678
     2679                if (label === '') {
     2680                        label = _i18n2.default.t(_mejs2.default.language.codes[lang]) || lang;
     2681                }
     2682                target.disabled = false;
     2683                var targetSiblings = (0, _dom.siblings)(target, function (el) {
     2684                        return (0, _dom.hasClass)(el, t.options.classPrefix + 'captions-selector-label');
     2685                });
     2686                for (var i = 0, total = targetSiblings.length; i < total; i++) {
     2687                        targetSiblings[i].innerHTML = label;
     2688                }
     2689
     2690                // auto select
     2691                if (t.options.startLanguage === lang) {
     2692                        target.checked = true;
     2693                        var event = (0, _general.createEvent)('click', target);
     2694                        target.dispatchEvent(event);
     2695                }
     2696        },
     2697
     2698
     2699        /**
     2700  *
     2701  * @param {String} trackId
     2702  */
     2703        removeTrackButton: function removeTrackButton(trackId) {
     2704
     2705                var element = _document2.default.getElementById('' + trackId);
     2706
     2707                if (element) {
     2708                        var button = element.closest('li');
     2709                        if (button) {
     2710                                button.remove();
     2711                        }
     2712                }
     2713        },
     2714
     2715
     2716        /**
     2717  *
     2718  * @param {String} trackId
     2719  * @param {String} lang - The language code
     2720  * @param {String} label
     2721  */
     2722        addTrackButton: function addTrackButton(trackId, lang, label) {
     2723                var t = this;
     2724                if (label === '') {
     2725                        label = _i18n2.default.t(_mejs2.default.language.codes[lang]) || lang;
     2726                }
     2727
     2728                // trackId is used in the value, too, because the "none"
     2729                // caption option doesn't have a trackId but we need to be able
     2730                // to set it, too
     2731                t.captionsButton.querySelector('ul').innerHTML += '<li class="' + t.options.classPrefix + 'captions-selector-list-item">' + ('<input type="radio" class="' + t.options.classPrefix + 'captions-selector-input" ') + ('name="' + t.id + '_captions" id="' + trackId + '" value="' + trackId + '" disabled>') + ('<label class="' + t.options.classPrefix + 'captions-selector-label">' + label + ' (loading)</label>') + '</li>';
     2732        },
     2733
     2734
     2735        /**
     2736  *
     2737  */
     2738        checkForTracks: function checkForTracks() {
     2739                var t = this;
     2740
     2741                var hasSubtitles = false;
     2742
     2743                // check if any subtitles
     2744                if (t.options.hideCaptionsButtonWhenEmpty) {
     2745                        for (var i = 0, total = t.tracks.length; i < total; i++) {
     2746                                var kind = t.tracks[i].kind;
     2747                                if ((kind === 'subtitles' || kind === 'captions') && t.tracks[i].isLoaded) {
     2748                                        hasSubtitles = true;
     2749                                        break;
     2750                                }
     2751                        }
     2752
     2753                        t.captionsButton.style.display = hasSubtitles ? '' : 'none';
     2754                        t.setControlsSize();
     2755                }
     2756        },
     2757
     2758
     2759        /**
     2760  *
     2761  */
     2762        displayCaptions: function displayCaptions() {
     2763
     2764                if (this.tracks === undefined) {
     2765                        return;
     2766                }
     2767
     2768                var t = this,
     2769                    track = t.selectedTrack,
     2770                    sanitize = function sanitize(html) {
     2771
     2772                        var div = _document2.default.createElement('div');
     2773                        div.innerHTML = html;
     2774
     2775                        // Remove all `<script>` tags first
     2776                        var scripts = div.getElementsByTagName('script');
     2777                        var i = scripts.length;
     2778                        while (i--) {
     2779                                scripts[i].remove();
     2780                        }
     2781
     2782                        // Loop the elements and remove anything that contains value="javascript:" or an `on*` attribute
     2783                        // (`onerror`, `onclick`, etc.)
     2784                        var allElements = div.getElementsByTagName('*');
     2785                        for (var _i12 = 0, n = allElements.length; _i12 < n; _i12++) {
     2786                                var attributesObj = allElements[_i12].attributes,
     2787                                    attributes = Array.prototype.slice.call(attributesObj);
     2788
     2789                                for (var j = 0, total = attributes.length; j < total; j++) {
     2790                                        if (attributes[j].name.startsWith('on') || attributes[j].value.startsWith('javascript')) {
     2791                                                allElements[_i12].remove();
     2792                                        } else if (attributes[j].name === 'style') {
     2793                                                allElements[_i12].removeAttribute(attributes[j].name);
     2794                                        }
     2795                                }
     2796                        }
     2797                        return div.innerHTML;
     2798                };
     2799
     2800                if (track !== null && track.isLoaded) {
     2801                        var i = t.searchTrackPosition(track.entries, t.media.currentTime);
     2802                        if (i > -1) {
     2803                                // Set the line before the timecode as a class so the cue can be targeted if needed
     2804                                t.captionsText.innerHTML = sanitize(track.entries[i].text);
     2805                                t.captionsText.className = t.options.classPrefix + 'captions-text ' + (track.entries[i].identifier || '');
     2806                                t.captions.style.display = '';
     2807                                t.captions.style.height = '0px';
     2808                                return; // exit out if one is visible;
     2809                        }
     2810
     2811                        t.captions.style.display = 'none';
     2812                } else {
     2813                        t.captions.style.display = 'none';
     2814                }
     2815        },
     2816
     2817
     2818        /**
     2819  *
     2820  * @param {HTMLElement} track
     2821  */
     2822        setupSlides: function setupSlides(track) {
     2823                var t = this;
     2824
     2825                t.slides = track;
     2826                t.slides.entries.imgs = [t.slides.entries.length];
     2827                t.showSlide(0);
     2828        },
     2829
     2830
     2831        /**
     2832  *
     2833  * @param {Number} index
     2834  */
     2835        showSlide: function showSlide(index) {
     2836                var _this = this;
     2837
     2838                var t = this;
     2839
     2840                if (t.tracks === undefined || t.slidesContainer === undefined) {
     2841                        return;
     2842                }
     2843
     2844                var url = t.slides.entries[index].text;
     2845
     2846                var img = t.slides.entries[index].imgs;
     2847
     2848                if (img === undefined || img.fadeIn === undefined) {
     2849                        (function () {
     2850
     2851                                var image = _document2.default.createElement('img');
     2852                                image.src = url;
     2853                                image.addEventListener('load', function () {
     2854                                        var self = _this,
     2855                                            visible = (0, _dom.siblings)(self, function (el) {
     2856                                                return visible(el);
     2857                                        });
     2858                                        self.style.display = 'none';
     2859                                        t.slidesContainer.innerHTML += self.innerHTML;
     2860                                        (0, _dom.fadeIn)(t.slidesContainer.querySelector(image));
     2861                                        for (var i = 0, total = visible.length; i < total; i++) {
     2862                                                (0, _dom.fadeOut)(visible[i], 400);
     2863                                        }
     2864                                });
     2865                                t.slides.entries[index].imgs = img = image;
     2866                        })();
     2867                } else if (!(0, _dom.visible)(img)) {
     2868                        (function () {
     2869                                var visible = (0, _dom.siblings)(self, function (el) {
     2870                                        return visible(el);
     2871                                });
     2872                                (0, _dom.fadeIn)(t.slidesContainer.querySelector(img));
     2873                                for (var i = 0, total = visible.length; i < total; i++) {
     2874                                        (0, _dom.fadeOut)(visible[i]);
     2875                                }
     2876                        })();
     2877                }
     2878        },
     2879
     2880
     2881        /**
     2882  *
     2883  */
     2884        displaySlides: function displaySlides() {
     2885                var t = this;
     2886
     2887                if (this.slides === undefined) {
     2888                        return;
     2889                }
     2890
     2891                var slides = t.slides,
     2892                    i = t.searchTrackPosition(slides.entries, t.media.currentTime);
     2893
     2894                if (i > -1) {
     2895                        t.showSlide(i);
     2896                        return; // exit out if one is visible;
     2897                }
     2898        },
     2899
     2900
     2901        /**
     2902  *
     2903  * @param {Object} chapters
     2904  */
     2905        drawChapters: function drawChapters(chapters) {
     2906                var t = this,
     2907                    total = chapters.entries.length;
     2908
     2909                if (!total) {
     2910                        return;
     2911                }
     2912
     2913                t.chaptersButton.querySelector('ul').innerHTML = '';
     2914
     2915                for (var i = 0; i < total; i++) {
     2916                        t.chaptersButton.querySelector('ul').innerHTML += '<li class="' + t.options.classPrefix + 'chapters-selector-list-item" ' + 'role="menuitemcheckbox" aria-live="polite" aria-disabled="false" aria-checked="false">' + ('<input type="radio" class="' + t.options.classPrefix + 'captions-selector-input" ') + ('name="' + t.id + '_chapters" value="' + chapters.entries[i].start + '" disabled>') + ('<label class="' + t.options.classPrefix + 'chapters-selector-label">' + chapters.entries[i].text + '</label>') + '</li>';
     2917                }
     2918
     2919                var radios = t.chaptersButton.querySelectorAll('input[type="radio"]'),
     2920                    labels = t.chaptersButton.querySelectorAll('.' + t.options.classPrefix + 'chapters-selector-label');
     2921
     2922                for (var _i13 = 0, _total10 = radios.length; _i13 < _total10; _i13++) {
     2923                        radios[_i13].disabled = false;
     2924                        radios[_i13].checked = false;
     2925                        radios[_i13].addEventListener('click', function () {
     2926                                var self = this,
     2927                                    listItems = t.chaptersButton.querySelectorAll('li'),
     2928                                    label = (0, _dom.siblings)(self, function (el) {
     2929                                        return (0, _dom.hasClass)(el, t.options.classPrefix + 'chapters-selector-label');
     2930                                })[0];
     2931
     2932                                self.checked = true;
     2933                                self.parentNode.setAttribute('aria-checked', true);
     2934                                (0, _dom.addClass)(label, t.options.classPrefix + 'chapters-selected');
     2935                                (0, _dom.removeClass)(t.chaptersButton.querySelector('.' + t.options.classPrefix + 'chapters-selected'), t.options.classPrefix + 'chapters-selected');
     2936
     2937                                for (var _i14 = 0, _total11 = listItems.length; _i14 < _total11; _i14++) {
     2938                                        listItems[_i14].setAttribute('aria-checked', false);
     2939                                }
     2940
     2941                                t.media.setCurrentTime(parseFloat(self.value));
     2942                                if (t.media.paused) {
     2943                                        t.media.play();
     2944                                }
     2945                        });
     2946                }
     2947
     2948                for (var _i15 = 0, _total12 = labels.length; _i15 < _total12; _i15++) {
     2949                        labels[_i15].addEventListener('click', function () {
     2950                                var radio = (0, _dom.siblings)(this, function (el) {
     2951                                        return el.tagName === 'INPUT';
     2952                                })[0],
     2953                                    event = (0, _general.createEvent)('click', radio);
     2954                                radio.dispatchEvent(event);
     2955                        });
     2956                }
     2957        },
     2958
     2959        /**
     2960  * Perform binary search to look for proper track index
     2961  *
     2962  * @param {Object[]} tracks
     2963  * @param {Number} currentTime
     2964  * @return {Number}
     2965  */
     2966        searchTrackPosition: function searchTrackPosition(tracks, currentTime) {
     2967                var lo = 0,
     2968                    hi = tracks.length - 1,
     2969                    mid = void 0,
     2970                    start = void 0,
     2971                    stop = void 0;
     2972
     2973                while (lo <= hi) {
     2974                        mid = lo + hi >> 1;
     2975                        start = tracks[mid].start;
     2976                        stop = tracks[mid].stop;
     2977
     2978                        if (currentTime >= start && currentTime < stop) {
     2979                                return mid;
     2980                        } else if (start < currentTime) {
     2981                                lo = mid + 1;
     2982                        } else if (start > currentTime) {
     2983                                hi = mid - 1;
     2984                        }
     2985                }
     2986
     2987                return -1;
     2988        }
     2989});
     2990
     2991/**
     2992 * Map all possible languages with their respective code
     2993 *
     2994 * @constructor
     2995 */
     2996_mejs2.default.language = {
     2997        codes: {
     2998                af: 'mejs.afrikaans',
     2999                sq: 'mejs.albanian',
     3000                ar: 'mejs.arabic',
     3001                be: 'mejs.belarusian',
     3002                bg: 'mejs.bulgarian',
     3003                ca: 'mejs.catalan',
     3004                zh: 'mejs.chinese',
     3005                'zh-cn': 'mejs.chinese-simplified',
     3006                'zh-tw': 'mejs.chines-traditional',
     3007                hr: 'mejs.croatian',
     3008                cs: 'mejs.czech',
     3009                da: 'mejs.danish',
     3010                nl: 'mejs.dutch',
     3011                en: 'mejs.english',
     3012                et: 'mejs.estonian',
     3013                fl: 'mejs.filipino',
     3014                fi: 'mejs.finnish',
     3015                fr: 'mejs.french',
     3016                gl: 'mejs.galician',
     3017                de: 'mejs.german',
     3018                el: 'mejs.greek',
     3019                ht: 'mejs.haitian-creole',
     3020                iw: 'mejs.hebrew',
     3021                hi: 'mejs.hindi',
     3022                hu: 'mejs.hungarian',
     3023                is: 'mejs.icelandic',
     3024                id: 'mejs.indonesian',
     3025                ga: 'mejs.irish',
     3026                it: 'mejs.italian',
     3027                ja: 'mejs.japanese',
     3028                ko: 'mejs.korean',
     3029                lv: 'mejs.latvian',
     3030                lt: 'mejs.lithuanian',
     3031                mk: 'mejs.macedonian',
     3032                ms: 'mejs.malay',
     3033                mt: 'mejs.maltese',
     3034                no: 'mejs.norwegian',
     3035                fa: 'mejs.persian',
     3036                pl: 'mejs.polish',
     3037                pt: 'mejs.portuguese',
     3038                ro: 'mejs.romanian',
     3039                ru: 'mejs.russian',
     3040                sr: 'mejs.serbian',
     3041                sk: 'mejs.slovak',
     3042                sl: 'mejs.slovenian',
     3043                es: 'mejs.spanish',
     3044                sw: 'mejs.swahili',
     3045                sv: 'mejs.swedish',
     3046                tl: 'mejs.tagalog',
     3047                th: 'mejs.thai',
     3048                tr: 'mejs.turkish',
     3049                uk: 'mejs.ukrainian',
     3050                vi: 'mejs.vietnamese',
     3051                cy: 'mejs.welsh',
     3052                yi: 'mejs.yiddish'
     3053        }
     3054};
     3055
    413056/*
    42 Utility methods
    43 */
    44 mejs.Utility = {
    45         encodeUrl: function(url) {
    46                 return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
     3057 Parses WebVTT format which should be formatted as
     3058 ================================
     3059 WEBVTT
     3060
     3061 1
     3062 00:00:01,1 --> 00:00:05,000
     3063 A line of text
     3064
     3065 2
     3066 00:01:15,1 --> 00:02:05,000
     3067 A second line of text
     3068
     3069 ===============================
     3070
     3071 Adapted from: http://www.delphiki.com/html5/playr
     3072 */
     3073_mejs2.default.TrackFormatParser = {
     3074        webvtt: {
     3075                /**
     3076   * @type {String}
     3077   */
     3078                pattern: /^((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,
     3079
     3080                /**
     3081   *
     3082   * @param {String} trackText
     3083   * @returns {{text: Array, times: Array}}
     3084   */
     3085                parse: function parse(trackText) {
     3086                        var lines = trackText.split(/\r?\n/),
     3087                            entries = [];
     3088
     3089                        var timecode = void 0,
     3090                            text = void 0,
     3091                            identifier = void 0;
     3092
     3093                        for (var i = 0, total = lines.length; i < total; i++) {
     3094                                timecode = this.pattern.exec(lines[i]);
     3095
     3096                                if (timecode && i < lines.length) {
     3097                                        if (i - 1 >= 0 && lines[i - 1] !== '') {
     3098                                                identifier = lines[i - 1];
     3099                                        }
     3100                                        i++;
     3101                                        // grab all the (possibly multi-line) text that follows
     3102                                        text = lines[i];
     3103                                        i++;
     3104                                        while (lines[i] !== '' && i < lines.length) {
     3105                                                text = text + '\n' + lines[i];
     3106                                                i++;
     3107                                        }
     3108                                        text = text.trim().replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
     3109                                        entries.push({
     3110                                                identifier: identifier,
     3111                                                start: (0, _time.convertSMPTEtoSeconds)(timecode[1]) === 0 ? 0.200 : (0, _time.convertSMPTEtoSeconds)(timecode[1]),
     3112                                                stop: (0, _time.convertSMPTEtoSeconds)(timecode[3]),
     3113                                                text: text,
     3114                                                settings: timecode[5]
     3115                                        });
     3116                                }
     3117                                identifier = '';
     3118                        }
     3119                        return entries;
     3120                }
    473121        },
    48         escapeHTML: function(s) {
    49                 return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
     3122        // Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
     3123        dfxp: {
     3124                /**
     3125   *
     3126   * @param {String} trackText
     3127   * @returns {{text: Array, times: Array}}
     3128   */
     3129                parse: function parse(trackText) {
     3130                        trackText = $(trackText).filter('tt');
     3131                        var container = trackText.firstChild,
     3132                            lines = container.querySelectorAll('p'),
     3133                            styleNode = trackText.getElementById('' + container.attr('style')),
     3134                            entries = [];
     3135
     3136                        var styles = void 0;
     3137
     3138                        if (styleNode.length) {
     3139                                styleNode.removeAttribute('id');
     3140                                var attributes = styleNode.attributes;
     3141                                if (attributes.length) {
     3142                                        styles = {};
     3143                                        for (var i = 0, total = attributes.length; i < total; i++) {
     3144                                                styles[attributes[i].name.split(":")[1]] = attributes[i].value;
     3145                                        }
     3146                                }
     3147                        }
     3148
     3149                        for (var _i16 = 0, _total13 = lines.length; _i16 < _total13; _i16++) {
     3150                                var style = void 0,
     3151                                    _temp = {
     3152                                        start: null,
     3153                                        stop: null,
     3154                                        style: null,
     3155                                        text: null
     3156                                };
     3157
     3158                                if (lines.eq(_i16).attr('begin')) {
     3159                                        _temp.start = (0, _time.convertSMPTEtoSeconds)(lines.eq(_i16).attr('begin'));
     3160                                }
     3161                                if (!_temp.start && lines.eq(_i16 - 1).attr('end')) {
     3162                                        _temp.start = (0, _time.convertSMPTEtoSeconds)(lines.eq(_i16 - 1).attr('end'));
     3163                                }
     3164                                if (lines.eq(_i16).attr('end')) {
     3165                                        _temp.stop = (0, _time.convertSMPTEtoSeconds)(lines.eq(_i16).attr('end'));
     3166                                }
     3167                                if (!_temp.stop && lines.eq(_i16 + 1).attr('begin')) {
     3168                                        _temp.stop = (0, _time.convertSMPTEtoSeconds)(lines.eq(_i16 + 1).attr('begin'));
     3169                                }
     3170
     3171                                if (styles) {
     3172                                        style = '';
     3173                                        for (var _style in styles) {
     3174                                                style += _style + ':' + styles[_style] + ';';
     3175                                        }
     3176                                }
     3177                                if (style) {
     3178                                        _temp.style = style;
     3179                                }
     3180                                if (_temp.start === 0) {
     3181                                        _temp.start = 0.200;
     3182                                }
     3183                                _temp.text = lines.eq(_i16).innerHTML.trim().replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
     3184                                entries.push(_temp);
     3185                        }
     3186                        return entries;
     3187                }
     3188        }
     3189};
     3190
     3191},{"16":16,"2":2,"24":24,"25":25,"28":28,"4":4,"6":6}],13:[function(_dereq_,module,exports){
     3192'use strict';
     3193
     3194var _document = _dereq_(2);
     3195
     3196var _document2 = _interopRequireDefault(_document);
     3197
     3198var _player = _dereq_(16);
     3199
     3200var _player2 = _interopRequireDefault(_player);
     3201
     3202var _i18n = _dereq_(4);
     3203
     3204var _i18n2 = _interopRequireDefault(_i18n);
     3205
     3206var _constants = _dereq_(23);
     3207
     3208var _general = _dereq_(25);
     3209
     3210var _dom = _dereq_(24);
     3211
     3212function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     3213
     3214/**
     3215 * Volume button
     3216 *
     3217 * This feature enables the displaying of a Volume button in the control bar, and also contains logic to manipulate its
     3218 * events, such as sliding up/down (or left/right, if vertical), muting/unmuting media, etc.
     3219 */
     3220
     3221// Feature configuration
     3222Object.assign(_player.config, {
     3223        /**
     3224  * @type {?String}
     3225  */
     3226        muteText: null,
     3227        /**
     3228  * @type {?String}
     3229  */
     3230        unmuteText: null,
     3231        /**
     3232  * @type {?String}
     3233  */
     3234        allyVolumeControlText: null,
     3235        /**
     3236  * @type {Boolean}
     3237  */
     3238        hideVolumeOnTouchDevices: true,
     3239        /**
     3240  * @type {String}
     3241  */
     3242        audioVolume: 'horizontal',
     3243        /**
     3244  * @type {String}
     3245  */
     3246        videoVolume: 'vertical'
     3247});
     3248
     3249Object.assign(_player2.default.prototype, {
     3250
     3251        /**
     3252  * Feature constructor.
     3253  *
     3254  * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     3255  * @param {MediaElementPlayer} player
     3256  * @param {$} controls
     3257  * @param {$} layers
     3258  * @param {HTMLElement} media
     3259  * @public
     3260  */
     3261        buildvolume: function buildvolume(player, controls, layers, media) {
     3262
     3263                // Android and iOS don't support volume controls
     3264                if ((_constants.IS_ANDROID || _constants.IS_IOS) && this.options.hideVolumeOnTouchDevices) {
     3265                        return;
     3266                }
     3267
     3268                var t = this,
     3269                    mode = t.isVideo ? t.options.videoVolume : t.options.audioVolume,
     3270                    muteText = (0, _general.isString)(t.options.muteText) ? t.options.muteText : _i18n2.default.t('mejs.mute'),
     3271                    unmuteText = (0, _general.isString)(t.options.unmuteText) ? t.options.unmuteText : _i18n2.default.t('mejs.unmute'),
     3272                    volumeControlText = (0, _general.isString)(t.options.allyVolumeControlText) ? t.options.allyVolumeControlText : _i18n2.default.t('mejs.volume-help-text'),
     3273                    mute = _document2.default.createElement('div');
     3274
     3275                mute.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'volume-button ' + t.options.classPrefix + 'mute';
     3276                mute.innerHTML = mode === 'horizontal' ? '<button type="button" aria-controls="' + t.id + '" title="' + muteText + '" aria-label="' + muteText + '" tabindex="0"></button>' : '<button type="button" aria-controls="' + t.id + '" title="' + muteText + '" aria-label="' + muteText + '" tabindex="0"></button>' + ('<a href="javascript:void(0);" class="' + t.options.classPrefix + 'volume-slider">') + ('<span class="' + t.options.classPrefix + 'offscreen">' + volumeControlText + '</span>') + ('<div class="' + t.options.classPrefix + 'volume-total">') + ('<div class="' + t.options.classPrefix + 'volume-current"></div>') + ('<div class="' + t.options.classPrefix + 'volume-handle"></div>') + '</div>' + '</a>';
     3277
     3278                t.addControlElement(mute, 'volume');
     3279
     3280                // horizontal version
     3281                if (mode === 'horizontal') {
     3282                        var anchor = _document2.default.createElement('a');
     3283                        anchor.className = t.options.classPrefix + 'horizontal-volume-slider';
     3284                        anchor.href = 'javascript:void(0);';
     3285                        anchor.innerHTML += '<span class="' + t.options.classPrefix + 'offscreen">' + volumeControlText + '</span>' + ('<div class="' + t.options.classPrefix + 'horizontal-volume-total">') + ('<div class="' + t.options.classPrefix + 'horizontal-volume-current"></div>') + ('<div class="' + t.options.classPrefix + 'horizontal-volume-handle"></div>') + '</div>';
     3286                        mute.parentNode.insertBefore(anchor, mute.nextSibling);
     3287                }
     3288
     3289                var volumeSlider = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-slider') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-slider'),
     3290                    volumeTotal = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-total') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-total'),
     3291                    volumeCurrent = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-current') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-current'),
     3292                    volumeHandle = mode === 'vertical' ? t.container.querySelector('.' + t.options.classPrefix + 'volume-handle') : t.container.querySelector('.' + t.options.classPrefix + 'horizontal-volume-handle'),
     3293                    button = mute.firstElementChild,
     3294
     3295
     3296                /**
     3297   * @private
     3298   * @param {Number} volume
     3299   */
     3300                positionVolumeHandle = function positionVolumeHandle(volume) {
     3301
     3302                        // correct to 0-1
     3303                        volume = Math.max(0, volume);
     3304                        volume = Math.min(volume, 1);
     3305
     3306                        // adjust mute button style
     3307                        if (volume === 0) {
     3308                                (0, _dom.removeClass)(mute, t.options.classPrefix + 'mute');
     3309                                (0, _dom.addClass)(mute, t.options.classPrefix + 'unmute');
     3310                                var _button = mute.firstElementChild;
     3311                                _button.setAttribute('title', unmuteText);
     3312                                _button.setAttribute('aria-label', unmuteText);
     3313                        } else {
     3314                                (0, _dom.removeClass)(mute, t.options.classPrefix + 'unmute');
     3315                                (0, _dom.addClass)(mute, t.options.classPrefix + 'mute');
     3316                                var _button2 = mute.firstElementChild;
     3317                                _button2.setAttribute('title', muteText);
     3318                                _button2.setAttribute('aria-label', muteText);
     3319                        }
     3320
     3321                        var volumePercentage = volume * 100 + '%',
     3322                            volumeStyles = getComputedStyle(volumeHandle);
     3323
     3324                        // position slider
     3325                        if (mode === 'vertical') {
     3326                                volumeCurrent.style.bottom = 0;
     3327                                volumeCurrent.style.height = volumePercentage;
     3328                                volumeHandle.style.bottom = volumePercentage;
     3329                                volumeHandle.style.marginBottom = -parseFloat(volumeStyles.height) / 2 + 'px';
     3330                        } else {
     3331                                volumeCurrent.style.left = 0;
     3332                                volumeCurrent.style.width = volumePercentage;
     3333                                volumeHandle.style.left = volumePercentage;
     3334                                volumeHandle.style.marginLeft = -parseFloat(volumeStyles.width) / 2 + 'px';
     3335                        }
     3336                },
     3337
     3338                /**
     3339   * @private
     3340   */
     3341                handleVolumeMove = function handleVolumeMove(e) {
     3342
     3343                        var totalOffset = (0, _dom.offset)(volumeTotal),
     3344                            volumeStyles = getComputedStyle(volumeTotal);
     3345
     3346                        var volume = null;
     3347
     3348                        // calculate the new volume based on the most recent position
     3349                        if (mode === 'vertical') {
     3350
     3351                                var railHeight = parseFloat(volumeStyles.height),
     3352                                    newY = e.pageY - totalOffset.top;
     3353
     3354                                volume = (railHeight - newY) / railHeight;
     3355
     3356                                // the controls just hide themselves (usually when mouse moves too far up)
     3357                                if (totalOffset.top === 0 || totalOffset.left === 0) {
     3358                                        return;
     3359                                }
     3360                        } else {
     3361                                var railWidth = parseFloat(volumeStyles.width),
     3362                                    newX = e.pageX - totalOffset.left;
     3363
     3364                                volume = newX / railWidth;
     3365                        }
     3366
     3367                        // ensure the volume isn't outside 0-1
     3368                        volume = Math.max(0, volume);
     3369                        volume = Math.min(volume, 1);
     3370
     3371                        // position the slider and handle
     3372                        positionVolumeHandle(volume);
     3373
     3374                        // set the media object (this will trigger the `volumechanged` event)
     3375                        if (volume === 0) {
     3376                                media.setMuted(true);
     3377                        } else {
     3378                                media.setMuted(false);
     3379                        }
     3380                        media.setVolume(volume);
     3381
     3382                        e.preventDefault();
     3383                        e.stopPropagation();
     3384                };
     3385
     3386                mute.addEventListener('mouseenter', function (e) {
     3387                        if (e.target === mute) {
     3388                                volumeSlider.style.display = 'block';
     3389                                mouseIsOver = true;
     3390                                e.preventDefault();
     3391                                e.stopPropagation();
     3392                        }
     3393                });
     3394                mute.addEventListener('focusin', function () {
     3395                        volumeSlider.style.display = 'block';
     3396                        mouseIsOver = true;
     3397                });
     3398                mute.addEventListener('mouseleave', function () {
     3399                        mouseIsOver = false;
     3400                        if (!mouseIsDown && mode === 'vertical') {
     3401                                volumeSlider.style.display = 'none';
     3402                        }
     3403                });
     3404                mute.addEventListener('focusout', function () {
     3405                        mouseIsOver = false;
     3406                        if (!mouseIsDown && mode === 'vertical') {
     3407                                volumeSlider.style.display = 'none';
     3408                        }
     3409                });
     3410                mute.addEventListener('keydown', function (e) {
     3411
     3412                        if (t.options.keyActions.length) {
     3413                                var keyCode = e.which || e.keyCode || 0,
     3414                                    volume = media.volume;
     3415                                switch (keyCode) {
     3416                                        case 38:
     3417                                                // Up
     3418                                                volume = Math.min(volume + 0.1, 1);
     3419                                                break;
     3420                                        case 40:
     3421                                                // Down
     3422                                                volume = Math.max(0, volume - 0.1);
     3423                                                break;
     3424                                        default:
     3425                                                return true;
     3426                                }
     3427
     3428                                mouseIsDown = false;
     3429                                positionVolumeHandle(volume);
     3430                                media.setVolume(volume);
     3431
     3432                                e.preventDefault();
     3433                                e.stopPropagation();
     3434                        }
     3435                });
     3436
     3437                var mouseIsDown = false,
     3438                    mouseIsOver = false,
     3439
     3440
     3441                /**
     3442   * @private
     3443   */
     3444                updateVolumeSlider = function updateVolumeSlider() {
     3445                        var volume = Math.floor(media.volume * 100);
     3446                        volumeSlider.setAttribute('aria-label', _i18n2.default.t('mejs.volume-slider'));
     3447                        volumeSlider.setAttribute('aria-valuemin', 0);
     3448                        volumeSlider.setAttribute('aria-valuemax', 100);
     3449                        volumeSlider.setAttribute('aria-valuenow', volume);
     3450                        volumeSlider.setAttribute('aria-valuetext', volume + '%');
     3451                        volumeSlider.setAttribute('role', 'slider');
     3452                        volumeSlider.tabIndex = -1;
     3453                };
     3454
     3455                // Events
     3456                volumeSlider.addEventListener('dragstart', function () {
     3457                        return false;
     3458                });
     3459
     3460                volumeSlider.addEventListener('mouseover', function () {
     3461                        mouseIsOver = true;
     3462                });
     3463                volumeSlider.addEventListener('mousedown', function (e) {
     3464                        handleVolumeMove(e);
     3465                        t.globalBind('mousemove.vol', function (event) {
     3466                                var target = event.target;
     3467                                if (mouseIsDown && (target === volumeSlider || target.closest(mode === 'vertical' ? '.' + t.options.classPrefix + 'volume-slider' : '.' + t.options.classPrefix + 'horizontal-volume-slider'))) {
     3468                                        handleVolumeMove(event);
     3469                                }
     3470                        });
     3471                        t.globalBind('mouseup.vol', function () {
     3472                                mouseIsDown = false;
     3473                                t.globalUnbind('mousemove.vol mouseup.vol');
     3474
     3475                                if (!mouseIsOver && mode === 'vertical') {
     3476                                        volumeSlider.style.display = 'none';
     3477                                }
     3478                        });
     3479                        mouseIsDown = true;
     3480
     3481                        e.preventDefault();
     3482                        e.stopPropagation();
     3483                });
     3484
     3485                // MUTE button
     3486                button.addEventListener('click', function () {
     3487                        media.setMuted(!media.muted);
     3488                        var event = (0, _general.createEvent)('volumechange', media);
     3489                        media.dispatchEvent(event);
     3490                });
     3491                button.addEventListener('focus', function () {
     3492                        if (mode === 'vertical') {
     3493                                volumeSlider.style.display = 'block';
     3494                        }
     3495                });
     3496                button.addEventListener('blur', function () {
     3497                        if (mode === 'vertical') {
     3498                                volumeSlider.style.display = 'none';
     3499                        }
     3500                });
     3501
     3502                // listen for volume change events from other sources
     3503                media.addEventListener('volumechange', function (e) {
     3504                        if (!mouseIsDown) {
     3505                                if (media.muted) {
     3506                                        positionVolumeHandle(0);
     3507                                        (0, _dom.removeClass)(mute, t.options.classPrefix + 'mute');
     3508                                        (0, _dom.addClass)(mute, t.options.classPrefix + 'unmute');
     3509                                } else {
     3510                                        positionVolumeHandle(media.volume);
     3511                                        (0, _dom.removeClass)(mute, t.options.classPrefix + 'unmute');
     3512                                        (0, _dom.addClass)(mute, t.options.classPrefix + 'mute');
     3513                                }
     3514                        }
     3515                        updateVolumeSlider(e);
     3516                });
     3517
     3518                // mutes the media and sets the volume icon muted if the initial volume is set to 0
     3519                if (player.options.startVolume === 0) {
     3520                        media.setMuted(true);
     3521                }
     3522
     3523                // shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
     3524                var isNative = t.media.rendererName !== null && t.media.rendererName.match(/(native|html5)/) !== null;
     3525
     3526                if (isNative) {
     3527                        media.setVolume(player.options.startVolume);
     3528                }
     3529
     3530                t.container.addEventListener('controlsresize', function () {
     3531                        if (media.muted) {
     3532                                positionVolumeHandle(0);
     3533                                (0, _dom.removeClass)(mute, t.options.classPrefix + 'mute');
     3534                                (0, _dom.addClass)(mute, t.options.classPrefix + 'unmute');
     3535                        } else {
     3536                                positionVolumeHandle(media.volume);
     3537                                (0, _dom.removeClass)(mute, t.options.classPrefix + 'unmute');
     3538                                (0, _dom.addClass)(mute, t.options.classPrefix + 'mute');
     3539                        }
     3540                });
     3541        }
     3542});
     3543
     3544},{"16":16,"2":2,"23":23,"24":24,"25":25,"4":4}],14:[function(_dereq_,module,exports){
     3545'use strict';
     3546
     3547/*!
     3548 * This is a `i18n` language object.
     3549 *
     3550 * English; This can serve as a template for other languages to translate
     3551 *
     3552 * @author
     3553 *   TBD
     3554 *   Sascha Greuel (Twitter: @SoftCreatR)
     3555 *
     3556 * @see core/i18n.js
     3557 */
     3558
     3559Object.defineProperty(exports, "__esModule", {
     3560        value: true
     3561});
     3562var EN = exports.EN = {
     3563        "mejs.plural-form": 1,
     3564
     3565        // core/mediaelement.js
     3566        "mejs.download-file": "Download File",
     3567
     3568        // renderers/flash.js
     3569        "mejs.install-flash": "You are using a browser that does not have Flash player enabled or installed. Please turn on your Flash player plugin or download the latest version from https://get.adobe.com/flashplayer/",
     3570
     3571        // features/fullscreen.js
     3572        "mejs.fullscreen": "Fullscreen",
     3573
     3574        // features/playpause.js
     3575        "mejs.play": "Play",
     3576        "mejs.pause": "Pause",
     3577
     3578        // features/progress.js
     3579        "mejs.time-slider": "Time Slider",
     3580        "mejs.time-help-text": "Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.",
     3581        "mejs.live-broadcast": "Live Broadcast",
     3582
     3583        // features/volume.js
     3584        "mejs.volume-help-text": "Use Up/Down Arrow keys to increase or decrease volume.",
     3585        "mejs.unmute": "Unmute",
     3586        "mejs.mute": "Mute",
     3587        "mejs.volume-slider": "Volume Slider",
     3588
     3589        // core/player.js
     3590        "mejs.video-player": "Video Player",
     3591        "mejs.audio-player": "Audio Player",
     3592
     3593        // features/tracks.js
     3594        "mejs.captions-subtitles": "Captions/Subtitles",
     3595        "mejs.captions-chapters": "Chapters",
     3596        "mejs.none": "None",
     3597        "mejs.afrikaans": "Afrikaans",
     3598        "mejs.albanian": "Albanian",
     3599        "mejs.arabic": "Arabic",
     3600        "mejs.belarusian": "Belarusian",
     3601        "mejs.bulgarian": "Bulgarian",
     3602        "mejs.catalan": "Catalan",
     3603        "mejs.chinese": "Chinese",
     3604        "mejs.chinese-simplified": "Chinese (Simplified)",
     3605        "mejs.chinese-traditional": "Chinese (Traditional)",
     3606        "mejs.croatian": "Croatian",
     3607        "mejs.czech": "Czech",
     3608        "mejs.danish": "Danish",
     3609        "mejs.dutch": "Dutch",
     3610        "mejs.english": "English",
     3611        "mejs.estonian": "Estonian",
     3612        "mejs.filipino": "Filipino",
     3613        "mejs.finnish": "Finnish",
     3614        "mejs.french": "French",
     3615        "mejs.galician": "Galician",
     3616        "mejs.german": "German",
     3617        "mejs.greek": "Greek",
     3618        "mejs.haitian-creole": "Haitian Creole",
     3619        "mejs.hebrew": "Hebrew",
     3620        "mejs.hindi": "Hindi",
     3621        "mejs.hungarian": "Hungarian",
     3622        "mejs.icelandic": "Icelandic",
     3623        "mejs.indonesian": "Indonesian",
     3624        "mejs.irish": "Irish",
     3625        "mejs.italian": "Italian",
     3626        "mejs.japanese": "Japanese",
     3627        "mejs.korean": "Korean",
     3628        "mejs.latvian": "Latvian",
     3629        "mejs.lithuanian": "Lithuanian",
     3630        "mejs.macedonian": "Macedonian",
     3631        "mejs.malay": "Malay",
     3632        "mejs.maltese": "Maltese",
     3633        "mejs.norwegian": "Norwegian",
     3634        "mejs.persian": "Persian",
     3635        "mejs.polish": "Polish",
     3636        "mejs.portuguese": "Portuguese",
     3637        "mejs.romanian": "Romanian",
     3638        "mejs.russian": "Russian",
     3639        "mejs.serbian": "Serbian",
     3640        "mejs.slovak": "Slovak",
     3641        "mejs.slovenian": "Slovenian",
     3642        "mejs.spanish": "Spanish",
     3643        "mejs.swahili": "Swahili",
     3644        "mejs.swedish": "Swedish",
     3645        "mejs.tagalog": "Tagalog",
     3646        "mejs.thai": "Thai",
     3647        "mejs.turkish": "Turkish",
     3648        "mejs.ukrainian": "Ukrainian",
     3649        "mejs.vietnamese": "Vietnamese",
     3650        "mejs.welsh": "Welsh",
     3651        "mejs.yiddish": "Yiddish"
     3652};
     3653
     3654},{}],15:[function(_dereq_,module,exports){
     3655'use strict';
     3656
     3657var _window = _dereq_(3);
     3658
     3659var _window2 = _interopRequireDefault(_window);
     3660
     3661var _mejs = _dereq_(6);
     3662
     3663var _mejs2 = _interopRequireDefault(_mejs);
     3664
     3665function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     3666
     3667if (typeof jQuery !== 'undefined') {
     3668        _mejs2.default.$ = _window2.default.jQuery = _window2.default.$ = jQuery;
     3669} else if (typeof Zepto !== 'undefined') {
     3670        _mejs2.default.$ = _window2.default.Zepto = _window2.default.$ = Zepto;
     3671} else if (typeof ender !== 'undefined') {
     3672        _mejs2.default.$ = _window2.default.ender = _window2.default.$ = ender;
     3673}
     3674
     3675},{"3":3,"6":6}],16:[function(_dereq_,module,exports){
     3676'use strict';
     3677
     3678Object.defineProperty(exports, "__esModule", {
     3679        value: true
     3680});
     3681exports.config = undefined;
     3682
     3683var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
     3684
     3685var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
     3686
     3687var _window = _dereq_(3);
     3688
     3689var _window2 = _interopRequireDefault(_window);
     3690
     3691var _document = _dereq_(2);
     3692
     3693var _document2 = _interopRequireDefault(_document);
     3694
     3695var _mejs = _dereq_(6);
     3696
     3697var _mejs2 = _interopRequireDefault(_mejs);
     3698
     3699var _mediaelement = _dereq_(5);
     3700
     3701var _mediaelement2 = _interopRequireDefault(_mediaelement);
     3702
     3703var _i18n = _dereq_(4);
     3704
     3705var _i18n2 = _interopRequireDefault(_i18n);
     3706
     3707var _constants = _dereq_(23);
     3708
     3709var _general = _dereq_(25);
     3710
     3711var _time = _dereq_(28);
     3712
     3713var _media = _dereq_(26);
     3714
     3715var _dom = _dereq_(24);
     3716
     3717var dom = _interopRequireWildcard(_dom);
     3718
     3719function _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; } }
     3720
     3721function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     3722
     3723function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
     3724
     3725_mejs2.default.mepIndex = 0;
     3726
     3727_mejs2.default.players = {};
     3728
     3729// default player values
     3730var config = exports.config = {
     3731        // url to poster (to fix iOS 3.x)
     3732        poster: '',
     3733        // When the video is ended, show the poster.
     3734        showPosterWhenEnded: false,
     3735        // When the video is paused, show the poster.
     3736        showPosterWhenPaused: false,
     3737        // Default if the <video width> is not specified
     3738        defaultVideoWidth: 480,
     3739        // Default if the <video height> is not specified
     3740        defaultVideoHeight: 270,
     3741        // If set, overrides <video width>
     3742        videoWidth: -1,
     3743        // If set, overrides <video height>
     3744        videoHeight: -1,
     3745        // Default if the user doesn't specify
     3746        defaultAudioWidth: 400,
     3747        // Default if the user doesn't specify
     3748        defaultAudioHeight: 40,
     3749        // Default amount to move back when back key is pressed
     3750        defaultSeekBackwardInterval: function defaultSeekBackwardInterval(media) {
     3751                return media.duration * 0.05;
    503752        },
    51         absolutizeUrl: function(url) {
    52                 var el = document.createElement('div');
    53                 el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
    54                 return el.firstChild.href;
     3753        // Default amount to move forward when forward key is pressed
     3754        defaultSeekForwardInterval: function defaultSeekForwardInterval(media) {
     3755                return media.duration * 0.05;
    553756        },
    56         getScriptPath: function(scriptNames) {
    57                 var
    58                         i = 0,
    59                         j,
    60                         codePath = '',
    61                         testname = '',
    62                         slashPos,
    63                         filenamePos,
    64                         scriptUrl,
    65                         scriptPath,                     
    66                         scriptFilename,
    67                         scripts = document.getElementsByTagName('script'),
    68                         il = scripts.length,
    69                         jl = scriptNames.length;
    70                        
    71                 // go through all <script> tags
    72                 for (; i < il; i++) {
    73                         scriptUrl = scripts[i].src;
    74                         slashPos = scriptUrl.lastIndexOf('/');
    75                         if (slashPos > -1) {
    76                                 scriptFilename = scriptUrl.substring(slashPos + 1);
    77                                 scriptPath = scriptUrl.substring(0, slashPos + 1);
     3757        // Set dimensions via JS instead of CSS
     3758        setDimensions: true,
     3759        // Width of audio player
     3760        audioWidth: -1,
     3761        // Height of audio player
     3762        audioHeight: -1,
     3763        // Initial volume when the player starts (overridden by user cookie)
     3764        startVolume: 0.8,
     3765        // Useful for <audio> player loops
     3766        loop: false,
     3767        // Rewind to beginning when media ends
     3768        autoRewind: true,
     3769        // Resize to media dimensions
     3770        enableAutosize: true,
     3771        /*
     3772  * Time format to use. Default: 'mm:ss'
     3773  * Supported units:
     3774  *   h: hour
     3775  *   m: minute
     3776  *   s: second
     3777  *   f: frame count
     3778  * When using 'hh', 'mm', 'ss' or 'ff' we always display 2 digits.
     3779  * If you use 'h', 'm', 's' or 'f' we display 1 digit if possible.
     3780  *
     3781  * Example to display 75 seconds:
     3782  * Format 'mm:ss': 01:15
     3783  * Format 'm:ss': 1:15
     3784  * Format 'm:s': 1:15
     3785  */
     3786        timeFormat: '',
     3787        // Force the hour marker (##:00:00)
     3788        alwaysShowHours: false,
     3789        // Show framecount in timecode (##:00:00:00)
     3790        showTimecodeFrameCount: false,
     3791        // Used when showTimecodeFrameCount is set to true
     3792        framesPerSecond: 25,
     3793        // Hide controls when playing and mouse is not over the video
     3794        alwaysShowControls: false,
     3795        // Display the video control when media is loading
     3796        hideVideoControlsOnLoad: false,
     3797        // Display the video controls when media is paused
     3798        hideVideoControlsOnPause: false,
     3799        // Enable click video element to toggle play/pause
     3800        clickToPlayPause: true,
     3801        // Time in ms to hide controls
     3802        controlsTimeoutDefault: 1500,
     3803        // Time in ms to trigger the timer when mouse moves
     3804        controlsTimeoutMouseEnter: 2500,
     3805        // Time in ms to trigger the timer when mouse leaves
     3806        controlsTimeoutMouseLeave: 1000,
     3807        // Force iPad's native controls
     3808        iPadUseNativeControls: false,
     3809        // Force iPhone's native controls
     3810        iPhoneUseNativeControls: false,
     3811        // Force Android's native controls
     3812        AndroidUseNativeControls: false,
     3813        // Features to show
     3814        features: ['playpause', 'current', 'progress', 'duration', 'tracks', 'volume', 'fullscreen'],
     3815        // Only for dynamic
     3816        isVideo: true,
     3817        // Stretching modes (auto, fill, responsive, none)
     3818        stretching: 'auto',
     3819        // Prefix class names on elements
     3820        classPrefix: 'mejs__',
     3821        // Turn keyboard support on and off for this instance
     3822        enableKeyboard: true,
     3823        // When this player starts, it will pause other players
     3824        pauseOtherPlayers: true,
     3825        // Number of decimal places to show if frames are shown
     3826        secondsDecimalLength: 0,
     3827        // Array of keyboard actions such as play/pause
     3828        keyActions: [{
     3829                keys: [32, // SPACE
     3830                179 // GOOGLE play/pause button
     3831                ],
     3832                action: function action(player, media) {
     3833
     3834                        if (!_constants.IS_FIREFOX) {
     3835                                if (media.paused || media.ended) {
     3836                                        media.play();
     3837                                } else {
     3838                                        media.pause();
     3839                                }
     3840                        }
     3841                }
     3842        }, {
     3843                keys: [38], // UP
     3844                action: function action(player, media) {
     3845
     3846                        if (player.container.querySelector('.' + config.classPrefix + 'volume-button>button').matches(':focus') || player.container.querySelector('.' + config.classPrefix + 'volume-slider').matches(':focus')) {
     3847                                player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
     3848                        }
     3849                        if (player.isVideo) {
     3850                                player.showControls();
     3851                                player.startControlsTimer();
     3852                        }
     3853
     3854                        var newVolume = Math.min(media.volume + 0.1, 1);
     3855                        media.setVolume(newVolume);
     3856                        if (newVolume > 0) {
     3857                                media.setMuted(false);
     3858                        }
     3859                }
     3860        }, {
     3861                keys: [40], // DOWN
     3862                action: function action(player, media) {
     3863
     3864                        if (player.container.querySelector('.' + config.classPrefix + 'volume-button>button').matches(':focus') || player.container.querySelector('.' + config.classPrefix + 'volume-slider').matches(':focus')) {
     3865                                player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
     3866                        }
     3867
     3868                        if (player.isVideo) {
     3869                                player.showControls();
     3870                                player.startControlsTimer();
     3871                        }
     3872
     3873                        var newVolume = Math.max(media.volume - 0.1, 0);
     3874                        media.setVolume(newVolume);
     3875
     3876                        if (newVolume <= 0.1) {
     3877                                media.setMuted(true);
     3878                        }
     3879                }
     3880        }, {
     3881                keys: [37, // LEFT
     3882                227 // Google TV rewind
     3883                ],
     3884                action: function action(player, media) {
     3885                        if (!isNaN(media.duration) && media.duration > 0) {
     3886                                if (player.isVideo) {
     3887                                        player.showControls();
     3888                                        player.startControlsTimer();
     3889                                }
     3890
     3891                                // 5%
     3892                                var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
     3893                                media.setCurrentTime(newTime);
     3894                        }
     3895                }
     3896        }, {
     3897                keys: [39, // RIGHT
     3898                228 // Google TV forward
     3899                ],
     3900                action: function action(player, media) {
     3901
     3902                        if (!isNaN(media.duration) && media.duration > 0) {
     3903                                if (player.isVideo) {
     3904                                        player.showControls();
     3905                                        player.startControlsTimer();
     3906                                }
     3907
     3908                                // 5%
     3909                                var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
     3910                                media.setCurrentTime(newTime);
     3911                        }
     3912                }
     3913        }, {
     3914                keys: [70], // F
     3915                action: function action(player, media, key, event) {
     3916                        if (!event.ctrlKey) {
     3917                                if (typeof player.enterFullScreen !== 'undefined') {
     3918                                        if (player.isFullScreen) {
     3919                                                player.exitFullScreen();
     3920                                        } else {
     3921                                                player.enterFullScreen();
     3922                                        }
     3923                                }
     3924                        }
     3925                }
     3926        }, {
     3927                keys: [77], // M
     3928                action: function action(player) {
     3929
     3930                        player.container.querySelector('.' + config.classPrefix + 'volume-slider').style.display = '';
     3931                        if (player.isVideo) {
     3932                                player.showControls();
     3933                                player.startControlsTimer();
     3934                        }
     3935                        if (player.media.muted) {
     3936                                player.setMuted(false);
    783937                        } else {
    79                                 scriptFilename = scriptUrl;
    80                                 scriptPath = '';                       
    81                         }
    82                        
    83                         // see if any <script> tags have a file name that matches the
    84                         for (j = 0; j < jl; j++) {
    85                                 testname = scriptNames[j];
    86                                 filenamePos = scriptFilename.indexOf(testname);
    87                                 if (filenamePos > -1) {
    88                                         codePath = scriptPath;
    89                                         break;
    90                                 }
    91                         }
    92                        
    93                         // if we found a path, then break and return it
    94                         if (codePath !== '') {
    95                                 break;
    96                         }
    97                 }
    98                
    99                 // send the best path back
    100                 return codePath;
    101         },
    102         secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
    103                 //add framecount
    104                 if (typeof showFrameCount == 'undefined') {
    105                     showFrameCount=false;
    106                 } else if(typeof fps == 'undefined') {
    107                     fps = 25;
    108                 }
    109        
    110                 var hours = Math.floor(time / 3600) % 24,
    111                         minutes = Math.floor(time / 60) % 60,
    112                         seconds = Math.floor(time % 60),
    113                         frames = Math.floor(((time % 1)*fps).toFixed(3)),
    114                         result =
    115                                         ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
    116                                                 + (minutes < 10 ? '0' + minutes : minutes) + ':'
    117                                                 + (seconds < 10 ? '0' + seconds : seconds)
    118                                                 + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
    119        
    120                 return result;
    121         },
    122        
    123         timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
    124                 if (typeof showFrameCount == 'undefined') {
    125                     showFrameCount=false;
    126                 } else if(typeof fps == 'undefined') {
    127                     fps = 25;
    128                 }
    129        
    130                 var tc_array = hh_mm_ss_ff.split(":"),
    131                         tc_hh = parseInt(tc_array[0], 10),
    132                         tc_mm = parseInt(tc_array[1], 10),
    133                         tc_ss = parseInt(tc_array[2], 10),
    134                         tc_ff = 0,
    135                         tc_in_seconds = 0;
    136                
    137                 if (showFrameCount) {
    138                     tc_ff = parseInt(tc_array[3])/fps;
    139                 }
    140                
    141                 tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
    142                
    143                 return tc_in_seconds;
    144         },
    145        
    146 
    147         convertSMPTEtoSeconds: function (SMPTE) {
    148                 if (typeof SMPTE != 'string')
    149                         return false;
    150 
    151                 SMPTE = SMPTE.replace(',', '.');
    152                
    153                 var secs = 0,
    154                         decimalLen = (SMPTE.indexOf('.') != -1) ? SMPTE.split('.')[1].length : 0,
    155                         multiplier = 1;
    156                
    157                 SMPTE = SMPTE.split(':').reverse();
    158                
    159                 for (var i = 0; i < SMPTE.length; i++) {
    160                         multiplier = 1;
    161                         if (i > 0) {
    162                                 multiplier = Math.pow(60, i);
    163                         }
    164                         secs += Number(SMPTE[i]) * multiplier;
    165                 }
    166                 return Number(secs.toFixed(decimalLen));
    167         },     
    168        
    169         /* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
    170         removeSwf: function(id) {
    171                 var obj = document.getElementById(id);
    172                 if (obj && /object|embed/i.test(obj.nodeName)) {
    173                         if (mejs.MediaFeatures.isIE) {
    174                                 obj.style.display = "none";
    175                                 (function(){
    176                                         if (obj.readyState == 4) {
    177                                                 mejs.Utility.removeObjectInIE(id);
    178                                         } else {
    179                                                 setTimeout(arguments.callee, 10);
     3938                                player.setMuted(true);
     3939                        }
     3940                }
     3941        }]
     3942};
     3943
     3944_mejs2.default.MepDefaults = config;
     3945
     3946/**
     3947 * Wrap a MediaElement object in player controls
     3948 *
     3949 * @constructor
     3950 * @param {HTMLElement|String} node
     3951 * @param {Object} o
     3952 * @return {?MediaElementPlayer}
     3953 */
     3954
     3955var MediaElementPlayer = function () {
     3956        function MediaElementPlayer(node, o) {
     3957                _classCallCheck(this, MediaElementPlayer);
     3958
     3959                var t = this,
     3960                    element = typeof node === 'string' ? _document2.default.getElementById(node) : node;
     3961
     3962                t.hasFocus = false;
     3963
     3964                t.controlsAreVisible = true;
     3965
     3966                t.controlsEnabled = true;
     3967
     3968                t.controlsTimer = null;
     3969
     3970                // enforce object, even without "new" (via John Resig)
     3971                if (!(t instanceof MediaElementPlayer)) {
     3972                        return new MediaElementPlayer(element, o);
     3973                }
     3974
     3975                // these will be reset after the MediaElement.success fires
     3976                // t.media will be the fake node to emulate all HTML5 events, methods, etc
     3977                // t.node will be the node to be restored
     3978                t.node = t.media = element;
     3979
     3980                if (!t.node) {
     3981                        return;
     3982                }
     3983
     3984                // check for existing player
     3985                if (t.media.player !== undefined) {
     3986                        return t.media.player;
     3987                }
     3988
     3989                // try to get options from data-mejsoptions
     3990                if (o === undefined) {
     3991                        o = t.node.getAttribute('data-mejsoptions');
     3992                }
     3993
     3994                // extend default options
     3995                t.options = Object.assign({}, config, o);
     3996
     3997                if (!t.options.timeFormat) {
     3998                        // Generate the time format according to options
     3999                        t.options.timeFormat = 'mm:ss';
     4000                        if (t.options.alwaysShowHours) {
     4001                                t.options.timeFormat = 'hh:mm:ss';
     4002                        }
     4003                        if (t.options.showTimecodeFrameCount) {
     4004                                t.options.timeFormat += ':ff';
     4005                        }
     4006                }
     4007
     4008                (0, _time.calculateTimeFormat)(0, t.options, t.options.framesPerSecond || 25);
     4009
     4010                // unique ID
     4011                t.id = 'mep_' + _mejs2.default.mepIndex++;
     4012
     4013                // add to player array (for focus events)
     4014                _mejs2.default.players[t.id] = t;
     4015
     4016                // start up
     4017                var meOptions = Object.assign({}, t.options, {
     4018                        success: function success(media, domNode) {
     4019                                t._meReady(media, domNode);
     4020                        },
     4021                        error: function error(e) {
     4022                                t._handleError(e);
     4023                        }
     4024                }),
     4025                    tagName = t.node.tagName.toLowerCase();
     4026
     4027                // get video from src or href?
     4028                t.isDynamic = tagName !== 'audio' && tagName !== 'video';
     4029                t.isVideo = t.isDynamic ? t.options.isVideo : tagName !== 'audio' && t.options.isVideo;
     4030
     4031                // use native controls in iPad, iPhone, and Android
     4032                if (_constants.IS_IPAD && t.options.iPadUseNativeControls || _constants.IS_IPHONE && t.options.iPhoneUseNativeControls) {
     4033
     4034                        // add controls and stop
     4035                        t.node.setAttribute('controls', true);
     4036
     4037                        // override Apple's autoplay override for iPads
     4038                        if (_constants.IS_IPAD && t.node.getAttribute('autoplay')) {
     4039                                t.play();
     4040                        }
     4041                } else if ((t.isVideo || !t.isVideo && t.options.features.length) && !(_constants.IS_ANDROID && t.options.AndroidUseNativeControls)) {
     4042
     4043                        // DESKTOP: use MediaElementPlayer controls
     4044
     4045                        // remove native controls
     4046                        t.node.removeAttribute('controls');
     4047                        var videoPlayerTitle = t.isVideo ? _i18n2.default.t('mejs.video-player') : _i18n2.default.t('mejs.audio-player');
     4048                        // insert description for screen readers
     4049                        var offscreen = _document2.default.createElement('span');
     4050                        offscreen.className = t.options.classPrefix + 'offscreen';
     4051                        offscreen.innerText = videoPlayerTitle;
     4052                        t.media.parentNode.insertBefore(offscreen, t.media);
     4053
     4054                        // build container
     4055                        t.container = _document2.default.createElement('div');
     4056                        t.container.id = t.id;
     4057                        t.container.className = t.options.classPrefix + 'container ' + t.options.classPrefix + 'container-keyboard-inactive ' + t.media.className;
     4058                        t.container.tabIndex = 0;
     4059                        t.container.setAttribute('role', 'application');
     4060                        t.container.setAttribute('aria-label', videoPlayerTitle);
     4061                        t.container.innerHTML = '<div class="' + t.options.classPrefix + 'inner">' + ('<div class="' + t.options.classPrefix + 'layers"></div>') + ('<div class="' + t.options.classPrefix + 'controls"></div>') + ('<div class="' + t.options.classPrefix + 'mediaelement"></div>') + ('<div class="' + t.options.classPrefix + 'clear"></div>') + '</div>';
     4062                        t.container.addEventListener('focus', function (e) {
     4063                                if (!t.controlsAreVisible && !t.hasFocus && t.controlsEnabled) {
     4064                                        t.showControls(true);
     4065                                        // In versions older than IE11, the focus causes the playbar to be displayed
     4066                                        // if user clicks on the Play/Pause button in the control bar once it attempts
     4067                                        // to hide it
     4068                                        if (!_constants.HAS_MS_NATIVE_FULLSCREEN) {
     4069                                                // If e.relatedTarget appears before container, send focus to play button,
     4070                                                // else send focus to last control button.
     4071                                                var btnSelector = (0, _general.isNodeAfter)(e.relatedTarget, t.container) ? '.' + t.options.classPrefix + 'controls .' + t.options.classPrefix + 'button:last-child > button' : '.' + t.options.classPrefix + 'playpause-button > button',
     4072                                                    button = t.container.querySelector(btnSelector);
     4073
     4074                                                button.focus();
     4075                                        }
     4076                                }
     4077                        });
     4078                        t.node.parentNode.insertBefore(t.container, t.node);
     4079
     4080                        // When no elements in controls, hide bar completely
     4081                        if (!t.options.features.length) {
     4082                                t.container.style.background = 'transparent';
     4083                                t.container.querySelector('.' + t.options.classPrefix + 'controls').style.display = 'none';
     4084                        }
     4085
     4086                        if (t.isVideo && t.options.stretching === 'fill' && !dom.hasClass(t.container.parentNode, t.options.classPrefix + 'fill-container')) {
     4087                                // outer container
     4088                                t.outerContainer = t.media.parentNode;
     4089
     4090                                var wrapper = _document2.default.createElement('div');
     4091                                wrapper.className = t.options.classPrefix + 'fill-container';
     4092                                t.container.parentNode.insertBefore(wrapper, t.container);
     4093                                wrapper.appendChild(t.container);
     4094                        }
     4095
     4096                        // add classes for user and content
     4097                        if (_constants.IS_ANDROID) {
     4098                                dom.addClass(t.container, t.options.classPrefix + 'android');
     4099                        }
     4100                        if (_constants.IS_IOS) {
     4101                                dom.addClass(t.container, t.options.classPrefix + 'ios');
     4102                        }
     4103                        if (_constants.IS_IPAD) {
     4104                                dom.addClass(t.container, t.options.classPrefix + 'ipad');
     4105                        }
     4106                        if (_constants.IS_IPHONE) {
     4107                                dom.addClass(t.container, t.options.classPrefix + 'iphone');
     4108                        }
     4109                        dom.addClass(t.container, t.isVideo ? t.options.classPrefix + 'video' : t.options.classPrefix + 'audio');
     4110
     4111                        // move the <video/video> tag into the right spot
     4112                        t.container.querySelector('.' + t.options.classPrefix + 'mediaelement').appendChild(t.node);
     4113
     4114                        // needs to be assigned here, after iOS remap
     4115                        t.media.player = t;
     4116
     4117                        // find parts
     4118                        t.controls = t.container.querySelector('.' + t.options.classPrefix + 'controls');
     4119                        t.layers = t.container.querySelector('.' + t.options.classPrefix + 'layers');
     4120
     4121                        // determine the size
     4122
     4123                        /* size priority:
     4124    (1) videoWidth (forced),
     4125    (2) style="width;height;"
     4126    (3) width attribute,
     4127    (4) defaultVideoWidth (for unspecified cases)
     4128    */
     4129
     4130                        var tagType = t.isVideo ? 'video' : 'audio',
     4131                            capsTagName = tagType.substring(0, 1).toUpperCase() + tagType.substring(1);
     4132
     4133                        if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
     4134                                t.width = t.options[tagType + 'Width'];
     4135                        } else if (t.node.style.width !== '' && t.node.style.width !== null) {
     4136                                t.width = t.node.style.width;
     4137                        } else if (t.node.getAttribute('width')) {
     4138                                t.width = t.node.getAttribute('width');
     4139                        } else {
     4140                                t.width = t.options['default' + capsTagName + 'Width'];
     4141                        }
     4142
     4143                        if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
     4144                                t.height = t.options[tagType + 'Height'];
     4145                        } else if (t.node.style.height !== '' && t.node.style.height !== null) {
     4146                                t.height = t.node.style.height;
     4147                        } else if (t.node.getAttribute('height')) {
     4148                                t.height = t.node.getAttribute('height');
     4149                        } else {
     4150                                t.height = t.options['default' + capsTagName + 'Height'];
     4151                        }
     4152
     4153                        t.initialAspectRatio = t.height >= t.width ? t.width / t.height : t.height / t.width;
     4154
     4155                        // set the size, while we wait for the plugins to load below
     4156                        t.setPlayerSize(t.width, t.height);
     4157
     4158                        // create MediaElementShim
     4159                        meOptions.pluginWidth = t.width;
     4160                        meOptions.pluginHeight = t.height;
     4161                }
     4162                // Hide media completely for audio that doesn't have any features
     4163                else if (!t.isVideo && !t.options.features.length) {
     4164                                t.node.style.display = 'none';
     4165                        }
     4166
     4167                // create MediaElement shim
     4168                new _mediaelement2.default(t.media, meOptions);
     4169
     4170                if (t.container !== undefined && t.options.features.length && t.controlsAreVisible && !t.options.hideVideoControlsOnLoad) {
     4171                        // controls are shown when loaded
     4172                        var event = (0, _general.createEvent)('controlsshown', t.container);
     4173                        t.container.dispatchEvent(event);
     4174                }
     4175
     4176                return t;
     4177        }
     4178
     4179        _createClass(MediaElementPlayer, [{
     4180                key: 'showControls',
     4181                value: function showControls(doAnimation) {
     4182                        var t = this;
     4183
     4184                        doAnimation = doAnimation === undefined || doAnimation;
     4185
     4186                        if (t.controlsAreVisible) {
     4187                                return;
     4188                        }
     4189
     4190                        if (doAnimation) {
     4191                                (function () {
     4192                                        dom.removeClass(t.controls, t.options.classPrefix + 'offscreen');
     4193                                        dom.fadeIn(t.controls, 200, function () {
     4194                                                var event = (0, _general.createEvent)('controlsshown', t.container);
     4195                                                t.container.dispatchEvent(event);
     4196                                        });
     4197
     4198                                        // any additional controls people might add and want to hide
     4199                                        var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
     4200
     4201                                        var _loop = function _loop(i, total) {
     4202                                                dom.fadeIn(controls[i], 200, function () {
     4203                                                        dom.removeClass(controls[i], t.options.classPrefix + 'offscreen');
     4204                                                });
     4205                                        };
     4206
     4207                                        for (var i = 0, total = controls.length; i < total; i++) {
     4208                                                _loop(i, total);
    1804209                                        }
    1814210                                })();
    1824211                        } else {
    183                                 obj.parentNode.removeChild(obj);
    184                         }
    185                 }
    186         },
    187         removeObjectInIE: function(id) {
    188                 var obj = document.getElementById(id);
    189                 if (obj) {
    190                         for (var i in obj) {
    191                                 if (typeof obj[i] == "function") {
    192                                         obj[i] = null;
    193                                 }
    194                         }
    195                         obj.parentNode.removeChild(obj);
    196                 }               
    197         }
    198 };
    199 
    200 
    201 // Core detector, plugins are added below
    202 mejs.PluginDetector = {
    203 
    204         // main public function to test a plug version number PluginDetector.hasPluginVersion('flash',[9,0,125]);
    205         hasPluginVersion: function(plugin, v) {
    206                 var pv = this.plugins[plugin];
    207                 v[1] = v[1] || 0;
    208                 v[2] = v[2] || 0;
    209                 return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
    210         },
    211 
    212         // cached values
    213         nav: window.navigator,
    214         ua: window.navigator.userAgent.toLowerCase(),
    215 
    216         // stored version numbers
    217         plugins: [],
    218 
    219         // runs detectPlugin() and stores the version number
    220         addPlugin: function(p, pluginName, mimeType, activeX, axDetect) {
    221                 this.plugins[p] = this.detectPlugin(pluginName, mimeType, activeX, axDetect);
    222         },
    223 
    224         // get the version number from the mimetype (all but IE) or ActiveX (IE)
    225         detectPlugin: function(pluginName, mimeType, activeX, axDetect) {
    226 
    227                 var version = [0,0,0],
    228                         description,
    229                         i,
    230                         ax;
    231 
    232                 // Firefox, Webkit, Opera
    233                 if (typeof(this.nav.plugins) != 'undefined' && typeof this.nav.plugins[pluginName] == 'object') {
    234                         description = this.nav.plugins[pluginName].description;
    235                         if (description && !(typeof this.nav.mimeTypes != 'undefined' && this.nav.mimeTypes[mimeType] && !this.nav.mimeTypes[mimeType].enabledPlugin)) {
    236                                 version = description.replace(pluginName, '').replace(/^\s+/,'').replace(/\sr/gi,'.').split('.');
    237                                 for (i=0; i<version.length; i++) {
    238                                         version[i] = parseInt(version[i].match(/\d+/), 10);
    239                                 }
    240                         }
    241                 // Internet Explorer / ActiveX
    242                 } else if (typeof(window.ActiveXObject) != 'undefined') {
    243                         try {
    244                                 ax = new ActiveXObject(activeX);
    245                                 if (ax) {
    246                                         version = axDetect(ax);
    247                                 }
    248                         }
    249                         catch (e) { }
    250                 }
    251                 return version;
    252         }
    253 };
    254 
    255 // Add Flash detection
    256 mejs.PluginDetector.addPlugin('flash','Shockwave Flash','application/x-shockwave-flash','ShockwaveFlash.ShockwaveFlash', function(ax) {
    257         // adapted from SWFObject
    258         var version = [],
    259                 d = ax.GetVariable("$version");
    260         if (d) {
    261                 d = d.split(" ")[1].split(",");
    262                 version = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
    263         }
    264         return version;
    265 });
    266 
    267 // Add Silverlight detection
    268 mejs.PluginDetector.addPlugin('silverlight','Silverlight Plug-In','application/x-silverlight-2','AgControl.AgControl', function (ax) {
    269         // Silverlight cannot report its version number to IE
    270         // but it does have a isVersionSupported function, so we have to loop through it to get a version number.
    271         // adapted from http://www.silverlightversion.com/
    272         var v = [0,0,0,0],
    273                 loopMatch = function(ax, v, i, n) {
    274                         while(ax.isVersionSupported(v[0]+ "."+ v[1] + "." + v[2] + "." + v[3])){
    275                                 v[i]+=n;
    276                         }
    277                         v[i] -= n;
    278                 };
    279         loopMatch(ax, v, 0, 1);
    280         loopMatch(ax, v, 1, 1);
    281         loopMatch(ax, v, 2, 10000); // the third place in the version number is usually 5 digits (4.0.xxxxx)
    282         loopMatch(ax, v, 2, 1000);
    283         loopMatch(ax, v, 2, 100);
    284         loopMatch(ax, v, 2, 10);
    285         loopMatch(ax, v, 2, 1);
    286         loopMatch(ax, v, 3, 1);
    287 
    288         return v;
    289 });
    290 // add adobe acrobat
    291 /*
    292 PluginDetector.addPlugin('acrobat','Adobe Acrobat','application/pdf','AcroPDF.PDF', function (ax) {
    293         var version = [],
    294                 d = ax.GetVersions().split(',')[0].split('=')[1].split('.');
    295 
    296         if (d) {
    297                 version = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
    298         }
    299         return version;
    300 });
    301 */
    302 // necessary detection (fixes for <IE9)
    303 mejs.MediaFeatures = {
    304         init: function() {
    305                 var
    306                         t = this,
    307                         d = document,
    308                         nav = mejs.PluginDetector.nav,
    309                         ua = mejs.PluginDetector.ua.toLowerCase(),
    310                         i,
    311                         v,
    312                         html5Elements = ['source','track','audio','video'];
    313 
    314                 // detect browsers (only the ones that have some kind of quirk we need to work around)
    315                 t.isiPad = (ua.match(/ipad/i) !== null);
    316                 t.isiPhone = (ua.match(/iphone/i) !== null);
    317                 t.isiOS = t.isiPhone || t.isiPad;
    318                 t.isAndroid = (ua.match(/android/i) !== null);
    319                 t.isBustedAndroid = (ua.match(/android 2\.[12]/) !== null);
    320                 t.isBustedNativeHTTPS = (location.protocol === 'https:' && (ua.match(/android [12]\./) !== null || ua.match(/macintosh.* version.* safari/) !== null));
    321                 t.isIE = (nav.appName.toLowerCase().indexOf("microsoft") != -1 || nav.appName.toLowerCase().match(/trident/gi) !== null);
    322                 t.isChrome = (ua.match(/chrome/gi) !== null);
    323                 t.isChromium = (ua.match(/chromium/gi) !== null);
    324                 t.isFirefox = (ua.match(/firefox/gi) !== null);
    325                 t.isWebkit = (ua.match(/webkit/gi) !== null);
    326                 t.isGecko = (ua.match(/gecko/gi) !== null) && !t.isWebkit && !t.isIE;
    327                 t.isOpera = (ua.match(/opera/gi) !== null);
    328                 t.hasTouch = ('ontouchstart' in window); //  && window.ontouchstart != null); // this breaks iOS 7
    329                
    330                 // borrowed from Modernizr
    331                 t.svg = !! document.createElementNS &&
    332                                 !! document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect;
    333 
    334                 // create HTML5 media elements for IE before 9, get a <video> element for fullscreen detection
    335                 for (i=0; i<html5Elements.length; i++) {
    336                         v = document.createElement(html5Elements[i]);
    337                 }
    338                
    339                 t.supportsMediaTag = (typeof v.canPlayType !== 'undefined' || t.isBustedAndroid);
    340 
    341                 // Fix for IE9 on Windows 7N / Windows 7KN (Media Player not installer)
    342                 try{
    343                         v.canPlayType("video/mp4");
    344                 }catch(e){
    345                         t.supportsMediaTag = false;
    346                 }
    347 
    348                 // detect native JavaScript fullscreen (Safari/Firefox only, Chrome still fails)
    349                
    350                 // iOS
    351                 t.hasSemiNativeFullScreen = (typeof v.webkitEnterFullscreen !== 'undefined');
    352                
    353                 // W3C
    354                 t.hasNativeFullscreen = (typeof v.requestFullscreen !== 'undefined');
    355                
    356                 // webkit/firefox/IE11+
    357                 t.hasWebkitNativeFullScreen = (typeof v.webkitRequestFullScreen !== 'undefined');
    358                 t.hasMozNativeFullScreen = (typeof v.mozRequestFullScreen !== 'undefined');
    359                 t.hasMsNativeFullScreen = (typeof v.msRequestFullscreen !== 'undefined');
    360                
    361                 t.hasTrueNativeFullScreen = (t.hasWebkitNativeFullScreen || t.hasMozNativeFullScreen || t.hasMsNativeFullScreen);
    362                 t.nativeFullScreenEnabled = t.hasTrueNativeFullScreen;
    363                
    364                 // Enabled?
    365                 if (t.hasMozNativeFullScreen) {
    366                         t.nativeFullScreenEnabled = document.mozFullScreenEnabled;
    367                 } else if (t.hasMsNativeFullScreen) {
    368                         t.nativeFullScreenEnabled = document.msFullscreenEnabled;               
    369                 }
    370                
    371                 if (t.isChrome) {
    372                         t.hasSemiNativeFullScreen = false;
    373                 }
    374                
    375                 if (t.hasTrueNativeFullScreen) {
    376                        
    377                         t.fullScreenEventName = '';
    378                         if (t.hasWebkitNativeFullScreen) {
    379                                 t.fullScreenEventName = 'webkitfullscreenchange';
    380                                
    381                         } else if (t.hasMozNativeFullScreen) {
    382                                 t.fullScreenEventName = 'mozfullscreenchange';
    383                                
    384                         } else if (t.hasMsNativeFullScreen) {
    385                                 t.fullScreenEventName = 'MSFullscreenChange';
    386                         }
    387                        
    388                         t.isFullScreen = function() {
    389                                 if (t.hasMozNativeFullScreen) {
    390                                         return d.mozFullScreen;
    391                                
    392                                 } else if (t.hasWebkitNativeFullScreen) {
    393                                         return d.webkitIsFullScreen;
    394                                
    395                                 } else if (t.hasMsNativeFullScreen) {
    396                                         return d.msFullscreenElement !== null;
    397                                 }
    398                         }
    399                                        
    400                         t.requestFullScreen = function(el) {
    401                
    402                                 if (t.hasWebkitNativeFullScreen) {
    403                                         el.webkitRequestFullScreen();
    404                                        
    405                                 } else if (t.hasMozNativeFullScreen) {
    406                                         el.mozRequestFullScreen();
    407 
    408                                 } else if (t.hasMsNativeFullScreen) {
    409                                         el.msRequestFullscreen();
    410 
    411                                 }
    412                         }
    413                        
    414                         t.cancelFullScreen = function() {                               
    415                                 if (t.hasWebkitNativeFullScreen) {
    416                                         document.webkitCancelFullScreen();
    417                                        
    418                                 } else if (t.hasMozNativeFullScreen) {
    419                                         document.mozCancelFullScreen();
    420                                        
    421                                 } else if (t.hasMsNativeFullScreen) {
    422                                         document.msExitFullscreen();
    423                                        
    424                                 }
    425                         }       
    426                        
    427                 }
    428                
    429                
    430                 // OS X 10.5 can't do this even if it says it can :(
    431                 if (t.hasSemiNativeFullScreen && ua.match(/mac os x 10_5/i)) {
    432                         t.hasNativeFullScreen = false;
    433                         t.hasSemiNativeFullScreen = false;
    434                 }
    435                
    436         }
    437 };
    438 mejs.MediaFeatures.init();
    439 
    440 /*
    441 extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below)
    442 */
    443 mejs.HtmlMediaElement = {
    444         pluginType: 'native',
    445         isFullScreen: false,
    446 
    447         setCurrentTime: function (time) {
    448                 this.currentTime = time;
    449         },
    450 
    451         setMuted: function (muted) {
    452                 this.muted = muted;
    453         },
    454 
    455         setVolume: function (volume) {
    456                 this.volume = volume;
    457         },
    458 
    459         // for parity with the plugin versions
    460         stop: function () {
    461                 this.pause();
    462         },
    463 
    464         // This can be a url string
    465         // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    466         setSrc: function (url) {
    467                
    468                 // Fix for IE9 which can't set .src when there are <source> elements. Awesome, right?
    469                 var
    470                         existingSources = this.getElementsByTagName('source');
    471                 while (existingSources.length > 0){
    472                         this.removeChild(existingSources[0]);
    473                 }
    474        
    475                 if (typeof url == 'string') {
    476                         this.src = url;
    477                 } else {
    478                         var i, media;
    479 
    480                         for (i=0; i<url.length; i++) {
    481                                 media = url[i];
    482                                 if (this.canPlayType(media.type)) {
    483                                         this.src = media.src;
    484                                         break;
    485                                 }
    486                         }
    487                 }
    488         },
    489 
    490         setVideoSize: function (width, height) {
    491                 this.width = width;
    492                 this.height = height;
    493         }
    494 };
    495 
    496 /*
    497 Mimics the <video/audio> element by calling Flash's External Interface or Silverlights [ScriptableMember]
    498 */
    499 mejs.PluginMediaElement = function (pluginid, pluginType, mediaUrl) {
    500         this.id = pluginid;
    501         this.pluginType = pluginType;
    502         this.src = mediaUrl;
    503         this.events = {};
    504         this.attributes = {};
    505 };
    506 
    507 // JavaScript values and ExternalInterface methods that match HTML5 video properties methods
    508 // http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/fl/video/FLVPlayback.html
    509 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
    510 mejs.PluginMediaElement.prototype = {
    511 
    512         // special
    513         pluginElement: null,
    514         pluginType: '',
    515         isFullScreen: false,
    516 
    517         // not implemented :(
    518         playbackRate: -1,
    519         defaultPlaybackRate: -1,
    520         seekable: [],
    521         played: [],
    522 
    523         // HTML5 read-only properties
    524         paused: true,
    525         ended: false,
    526         seeking: false,
    527         duration: 0,
    528         error: null,
    529         tagName: '',
    530 
    531         // HTML5 get/set properties, but only set (updated by event handlers)
    532         muted: false,
    533         volume: 1,
    534         currentTime: 0,
    535 
    536         // HTML5 methods
    537         play: function () {
    538                 if (this.pluginApi != null) {
    539                         if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
    540                                 this.pluginApi.playVideo();
     4212                                dom.removeClass(t.controls, t.options.classPrefix + 'offscreen');
     4213                                t.controls.style.display = '';
     4214
     4215                                // any additional controls people might add and want to hide
     4216                                var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
     4217                                for (var i = 0, total = controls.length; i < total; i++) {
     4218                                        dom.removeClass(controls[i], t.options.classPrefix + 'offscreen');
     4219                                        controls[i].style.display = '';
     4220                                }
     4221
     4222                                var event = (0, _general.createEvent)('controlsshown', t.container);
     4223                                t.container.dispatchEvent(event);
     4224                        }
     4225
     4226                        t.controlsAreVisible = true;
     4227                        t.setControlsSize();
     4228                }
     4229        }, {
     4230                key: 'hideControls',
     4231                value: function hideControls(doAnimation, forceHide) {
     4232                        var t = this;
     4233
     4234                        doAnimation = doAnimation === undefined || doAnimation;
     4235
     4236                        if (forceHide !== true && (!t.controlsAreVisible || t.options.alwaysShowControls || t.keyboardAction || t.media.paused && t.media.readyState === 4 && (!t.options.hideVideoControlsOnLoad && t.media.currentTime <= 0 || !t.options.hideVideoControlsOnPause && t.media.currentTime > 0) || t.isVideo && !t.options.hideVideoControlsOnLoad && !t.media.readyState || t.media.ended)) {
     4237                                return;
     4238                        }
     4239
     4240                        if (doAnimation) {
     4241                                (function () {
     4242                                        // fade out main controls
     4243                                        dom.fadeOut(t.controls, 200, function () {
     4244                                                dom.addClass(t.controls, t.options.classPrefix + 'offscreen');
     4245                                                t.controls.style.display = '';
     4246                                                var event = (0, _general.createEvent)('controlshidden', t.container);
     4247                                                t.container.dispatchEvent(event);
     4248                                        });
     4249
     4250                                        // any additional controls people might add and want to hide
     4251                                        var controls = t.container.querySelectorAll('.' + t.options.classPrefix + 'control');
     4252
     4253                                        var _loop2 = function _loop2(i, total) {
     4254                                                dom.fadeOut(controls[i], 200, function () {
     4255                                                        dom.addClass(controls[i], t.options.classPrefix + 'offscreen');
     4256                                                        controls[i].style.display = '';
     4257                                                });
     4258                                        };
     4259
     4260                                        for (var i = 0, total = controls.length; i < total; i++) {
     4261                                                _loop2(i, total);
     4262                                        }
     4263                                })();
    5414264                        } else {
    542                                 this.pluginApi.playMedia();
    543                         }
    544                         this.paused = false;
    545                 }
    546         },
    547         load: function () {
    548                 if (this.pluginApi != null) {
    549                         if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
    550                         } else {
    551                                 this.pluginApi.loadMedia();
    552                         }
    553                        
    554                         this.paused = false;
    555                 }
    556         },
    557         pause: function () {
    558                 if (this.pluginApi != null) {
    559                         if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
    560                                 this.pluginApi.pauseVideo();
    561                         } else {
    562                                 this.pluginApi.pauseMedia();
    563                         }                       
    564                        
    565                        
    566                         this.paused = true;
    567                 }
    568         },
    569         stop: function () {
    570                 if (this.pluginApi != null) {
    571                         if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
    572                                 this.pluginApi.stopVideo();
    573                         } else {
    574                                 this.pluginApi.stopMedia();
    575                         }       
    576                         this.paused = true;
    577                 }
    578         },
    579         canPlayType: function(type) {
    580                 var i,
    581                         j,
    582                         pluginInfo,
    583                         pluginVersions = mejs.plugins[this.pluginType];
    584 
    585                 for (i=0; i<pluginVersions.length; i++) {
    586                         pluginInfo = pluginVersions[i];
    587 
    588                         // test if user has the correct plugin version
    589                         if (mejs.PluginDetector.hasPluginVersion(this.pluginType, pluginInfo.version)) {
    590 
    591                                 // test for plugin playback types
    592                                 for (j=0; j<pluginInfo.types.length; j++) {
    593                                         // find plugin that can play the type
    594                                         if (type == pluginInfo.types[j]) {
    595                                                 return 'probably';
    596                                         }
    597                                 }
    598                         }
    599                 }
    600 
    601                 return '';
    602         },
    603        
    604         positionFullscreenButton: function(x,y,visibleAndAbove) {
    605                 if (this.pluginApi != null && this.pluginApi.positionFullscreenButton) {
    606                         this.pluginApi.positionFullscreenButton(Math.floor(x),Math.floor(y),visibleAndAbove);
    607                 }
    608         },
    609        
    610         hideFullscreenButton: function() {
    611                 if (this.pluginApi != null && this.pluginApi.hideFullscreenButton) {
    612                         this.pluginApi.hideFullscreenButton();
    613                 }               
    614         },     
    615        
    616 
    617         // custom methods since not all JavaScript implementations support get/set
    618 
    619         // This can be a url string
    620         // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    621         setSrc: function (url) {
    622                 if (typeof url == 'string') {
    623                         this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));
    624                         this.src = mejs.Utility.absolutizeUrl(url);
    625                 } else {
    626                         var i, media;
    627 
    628                         for (i=0; i<url.length; i++) {
    629                                 media = url[i];
    630                                 if (this.canPlayType(media.type)) {
    631                                         this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(media.src));
    632                                         this.src = mejs.Utility.absolutizeUrl(url);
    633                                         break;
    634                                 }
    635                         }
    636                 }
    637 
    638         },
    639         setCurrentTime: function (time) {
    640                 if (this.pluginApi != null) {
    641                         if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
    642                                 this.pluginApi.seekTo(time);
    643                         } else {
    644                                 this.pluginApi.setCurrentTime(time);
    645                         }                               
    646                        
    647                        
    648                        
    649                         this.currentTime = time;
    650                 }
    651         },
    652         setVolume: function (volume) {
    653                 if (this.pluginApi != null) {
    654                         // same on YouTube and MEjs
    655                         if (this.pluginType == 'youtube') {
    656                                 this.pluginApi.setVolume(volume * 100);
    657                         } else {
    658                                 this.pluginApi.setVolume(volume);
    659                         }
    660                         this.volume = volume;
    661                 }
    662         },
    663         setMuted: function (muted) {
    664                 if (this.pluginApi != null) {
    665                         if (this.pluginType == 'youtube') {
    666                                 if (muted) {
    667                                         this.pluginApi.mute();
    668                                 } else {
    669                                         this.pluginApi.unMute();
    670                                 }
    671                                 this.muted = muted;
    672                                 this.dispatchEvent('volumechange');
    673                         } else {
    674                                 this.pluginApi.setMuted(muted);
    675                         }
    676                         this.muted = muted;
    677                 }
    678         },
    679 
    680         // additional non-HTML5 methods
    681         setVideoSize: function (width, height) {
    682                
    683                 //if (this.pluginType == 'flash' || this.pluginType == 'silverlight') {
    684                         if (this.pluginElement && this.pluginElement.style) {
    685                                 this.pluginElement.style.width = width + 'px';
    686                                 this.pluginElement.style.height = height + 'px';
    687                         }
    688                         if (this.pluginApi != null && this.pluginApi.setVideoSize) {
    689                                 this.pluginApi.setVideoSize(width, height);
    690                         }
    691                 //}
    692         },
    693 
    694         setFullscreen: function (fullscreen) {
    695                 if (this.pluginApi != null && this.pluginApi.setFullscreen) {
    696                         this.pluginApi.setFullscreen(fullscreen);
    697                 }
    698         },
    699        
    700         enterFullScreen: function() {
    701                 if (this.pluginApi != null && this.pluginApi.setFullscreen) {
    702                         this.setFullscreen(true);
    703                 }               
    704                
    705         },
    706        
    707         exitFullScreen: function() {
    708                 if (this.pluginApi != null && this.pluginApi.setFullscreen) {
    709                         this.setFullscreen(false);
    710                 }
    711         },     
    712 
    713         // start: fake events
    714         addEventListener: function (eventName, callback, bubble) {
    715                 this.events[eventName] = this.events[eventName] || [];
    716                 this.events[eventName].push(callback);
    717         },
    718         removeEventListener: function (eventName, callback) {
    719                 if (!eventName) { this.events = {}; return true; }
    720                 var callbacks = this.events[eventName];
    721                 if (!callbacks) return true;
    722                 if (!callback) { this.events[eventName] = []; return true; }
    723                 for (var i = 0; i < callbacks.length; i++) {
    724                         if (callbacks[i] === callback) {
    725                                 this.events[eventName].splice(i, 1);
    726                                 return true;
    727                         }
    728                 }
    729                 return false;
    730         },     
    731         dispatchEvent: function (eventName) {
    732                 var i,
    733                         args,
    734                         callbacks = this.events[eventName];
    735 
    736                 if (callbacks) {
    737                         args = Array.prototype.slice.call(arguments, 1);
    738                         for (i = 0; i < callbacks.length; i++) {
    739                                 callbacks[i].apply(null, args);
    740                         }
    741                 }
    742         },
    743         // end: fake events
    744        
    745         // fake DOM attribute methods
    746         hasAttribute: function(name){
    747                 return (name in this.attributes); 
    748         },
    749         removeAttribute: function(name){
    750                 delete this.attributes[name];
    751         },
    752         getAttribute: function(name){
    753                 if (this.hasAttribute(name)) {
    754                         return this.attributes[name];
    755                 }
    756                 return '';
    757         },
    758         setAttribute: function(name, value){
    759                 this.attributes[name] = value;
    760         },
    761 
    762         remove: function() {
    763                 mejs.Utility.removeSwf(this.pluginElement.id);
    764                 mejs.MediaPluginBridge.unregisterPluginElement(this.pluginElement.id);
    765         }
    766 };
    767 
    768 // Handles calls from Flash/Silverlight and reports them as native <video/audio> events and properties
    769 mejs.MediaPluginBridge = {
    770 
    771         pluginMediaElements:{},
    772         htmlMediaElements:{},
    773 
    774         registerPluginElement: function (id, pluginMediaElement, htmlMediaElement) {
    775                 this.pluginMediaElements[id] = pluginMediaElement;
    776                 this.htmlMediaElements[id] = htmlMediaElement;
    777         },
    778 
    779         unregisterPluginElement: function (id) {
    780                 delete this.pluginMediaElements[id];
    781                 delete this.htmlMediaElements[id];
    782         },
    783 
    784         // when Flash/Silverlight is ready, it calls out to this method
    785         initPlugin: function (id) {
    786 
    787                 var pluginMediaElement = this.pluginMediaElements[id],
    788                         htmlMediaElement = this.htmlMediaElements[id];
    789 
    790                 if (pluginMediaElement) {
    791                         // find the javascript bridge
    792                         switch (pluginMediaElement.pluginType) {
    793                                 case "flash":
    794                                         pluginMediaElement.pluginElement = pluginMediaElement.pluginApi = document.getElementById(id);
    795                                         break;
    796                                 case "silverlight":
    797                                         pluginMediaElement.pluginElement = document.getElementById(pluginMediaElement.id);
    798                                         pluginMediaElement.pluginApi = pluginMediaElement.pluginElement.Content.MediaElementJS;
    799                                         break;
    800                         }
    801        
    802                         if (pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
    803                                 pluginMediaElement.success(pluginMediaElement, htmlMediaElement);
    804                         }
    805                 }
    806         },
    807 
    808         // receives events from Flash/Silverlight and sends them out as HTML5 media events
    809         // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
    810         fireEvent: function (id, eventName, values) {
    811 
    812                 var
    813                         e,
    814                         i,
    815                         bufferedTime,
    816                         pluginMediaElement = this.pluginMediaElements[id];
    817 
    818                 if(!pluginMediaElement){
    819             return;
    820         }
    821        
    822                 // fake event object to mimic real HTML media event.
    823                 e = {
    824                         type: eventName,
    825                         target: pluginMediaElement
    826                 };
    827 
    828                 // attach all values to element and event object
    829                 for (i in values) {
    830                         pluginMediaElement[i] = values[i];
    831                         e[i] = values[i];
    832                 }
    833 
    834                 // fake the newer W3C buffered TimeRange (loaded and total have been removed)
    835                 bufferedTime = values.bufferedTime || 0;
    836 
    837                 e.target.buffered = e.buffered = {
    838                         start: function(index) {
    839                                 return 0;
    840                         },
    841                         end: function (index) {
    842                                 return bufferedTime;
    843                         },
    844                         length: 1
    845                 };
    846 
    847                 pluginMediaElement.dispatchEvent(e.type, e);
    848         }
    849 };
    850 
    851 /*
    852 Default options
    853 */
    854 mejs.MediaElementDefaults = {
    855         // allows testing on HTML5, flash, silverlight
    856         // auto: attempts to detect what the browser can do
    857         // auto_plugin: prefer plugins and then attempt native HTML5
    858         // native: forces HTML5 playback
    859         // shim: disallows HTML5, will attempt either Flash or Silverlight
    860         // none: forces fallback view
    861         mode: 'auto',
    862         // remove or reorder to change plugin priority and availability
    863         plugins: ['flash','silverlight','youtube','vimeo'],
    864         // shows debug errors on screen
    865         enablePluginDebug: false,
    866         // use plugin for browsers that have trouble with Basic Authentication on HTTPS sites
    867         httpsBasicAuthSite: false,
    868         // overrides the type specified, useful for dynamic instantiation
    869         type: '',
    870         // path to Flash and Silverlight plugins
    871         pluginPath: mejs.Utility.getScriptPath(['mediaelement.js','mediaelement.min.js','mediaelement-and-player.js','mediaelement-and-player.min.js']),
    872         // name of flash file
    873         flashName: 'flashmediaelement.swf',
    874         // streamer for RTMP streaming
    875         flashStreamer: '',
    876         // turns on the smoothing filter in Flash
    877         enablePluginSmoothing: false,
    878         // enabled pseudo-streaming (seek) on .mp4 files
    879         enablePseudoStreaming: false,
    880         // start query parameter sent to server for pseudo-streaming
    881         pseudoStreamingStartQueryParam: 'start',
    882         // name of silverlight file
    883         silverlightName: 'silverlightmediaelement.xap',
    884         // default if the <video width> is not specified
    885         defaultVideoWidth: 480,
    886         // default if the <video height> is not specified
    887         defaultVideoHeight: 270,
    888         // overrides <video width>
    889         pluginWidth: -1,
    890         // overrides <video height>
    891         pluginHeight: -1,
    892         // additional plugin variables in 'key=value' form
    893         pluginVars: [],
    894         // rate in milliseconds for Flash and Silverlight to fire the timeupdate event
    895         // larger number is less accurate, but less strain on plugin->JavaScript bridge
    896         timerRate: 250,
    897         // initial volume for player
    898         startVolume: 0.8,
    899         success: function () { },
    900         error: function () { }
    901 };
    902 
    903 /*
    904 Determines if a browser supports the <video> or <audio> element
    905 and returns either the native element or a Flash/Silverlight version that
    906 mimics HTML5 MediaElement
    907 */
    908 mejs.MediaElement = function (el, o) {
    909         return mejs.HtmlMediaElementShim.create(el,o);
    910 };
    911 
    912 mejs.HtmlMediaElementShim = {
    913 
    914         create: function(el, o) {
    915                 var
    916                         options = mejs.MediaElementDefaults,
    917                         htmlMediaElement = (typeof(el) == 'string') ? document.getElementById(el) : el,
    918                         tagName = htmlMediaElement.tagName.toLowerCase(),
    919                         isMediaTag = (tagName === 'audio' || tagName === 'video'),
    920                         src = (isMediaTag) ? htmlMediaElement.getAttribute('src') : htmlMediaElement.getAttribute('href'),
    921                         poster = htmlMediaElement.getAttribute('poster'),
    922                         autoplay =  htmlMediaElement.getAttribute('autoplay'),
    923                         preload =  htmlMediaElement.getAttribute('preload'),
    924                         controls =  htmlMediaElement.getAttribute('controls'),
    925                         playback,
    926                         prop;
    927 
    928                 // extend options
    929                 for (prop in o) {
    930                         options[prop] = o[prop];
    931                 }
    932 
    933                 // clean up attributes
    934                 src =           (typeof src == 'undefined'      || src === null || src == '') ? null : src;             
    935                 poster =        (typeof poster == 'undefined'   || poster === null) ? '' : poster;
    936                 preload =       (typeof preload == 'undefined'  || preload === null || preload === 'false') ? 'none' : preload;
    937                 autoplay =      !(typeof autoplay == 'undefined' || autoplay === null || autoplay === 'false');
    938                 controls =      !(typeof controls == 'undefined' || controls === null || controls === 'false');
    939 
    940                 // test for HTML5 and plugin capabilities
    941                 playback = this.determinePlayback(htmlMediaElement, options, mejs.MediaFeatures.supportsMediaTag, isMediaTag, src);
    942                 playback.url = (playback.url !== null) ? mejs.Utility.absolutizeUrl(playback.url) : '';
    943 
    944                 if (playback.method == 'native') {
    945                         // second fix for android
    946                         if (mejs.MediaFeatures.isBustedAndroid) {
    947                                 htmlMediaElement.src = playback.url;
    948                                 htmlMediaElement.addEventListener('click', function() {
    949                                         htmlMediaElement.play();
    950                                 }, false);
    951                         }
    952                
    953                         // add methods to native HTMLMediaElement
    954                         return this.updateNative(playback, options, autoplay, preload);
    955                 } else if (playback.method !== '') {
    956                         // create plugin to mimic HTMLMediaElement
    957                        
    958                         return this.createPlugin( playback,  options, poster, autoplay, preload, controls);
    959                 } else {
    960                         // boo, no HTML5, no Flash, no Silverlight.<