| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089 | 
							- // ==========================================================================
 
- // Plyr
 
- // plyr.js v1.3.6
 
- // https://github.com/selz/plyr
 
- // License: The MIT License (MIT)
 
- // ==========================================================================
 
- // Credits: http://paypal.github.io/accessible-html5-video-player/
 
- // ==========================================================================
 
- (function (api) {
 
-     'use strict';
 
-     /*global YT*/
 
-     // Globals
 
-     var fullscreen, config, callbacks = {
 
-         youtube: []
 
-     };
 
-     // Default config
 
-     var defaults = {
 
-         enabled: true,
 
-         debug: false,
 
-         seekTime: 10,
 
-         volume: 5,
 
-         click: true,
 
-         tooltips: true,
 
-         displayDuration: true,
 
-         iconPrefix: 'icon',
 
-         selectors: {
 
-             container: '.player',
 
-             controls: '.player-controls',
 
-             labels: '[data-player] .sr-only, label .sr-only',
 
-             buttons: {
 
-                 seek: '[data-player="seek"]',
 
-                 play: '[data-player="play"]',
 
-                 pause: '[data-player="pause"]',
 
-                 restart: '[data-player="restart"]',
 
-                 rewind: '[data-player="rewind"]',
 
-                 forward: '[data-player="fast-forward"]',
 
-                 mute: '[data-player="mute"]',
 
-                 volume: '[data-player="volume"]',
 
-                 captions: '[data-player="captions"]',
 
-                 fullscreen: '[data-player="fullscreen"]'
 
-             },
 
-             progress: {
 
-                 container: '.player-progress',
 
-                 buffer: '.player-progress-buffer',
 
-                 played: '.player-progress-played'
 
-             },
 
-             captions: '.player-captions',
 
-             currentTime: '.player-current-time',
 
-             duration: '.player-duration'
 
-         },
 
-         classes: {
 
-             videoWrapper: 'player-video-wrapper',
 
-             embedWrapper: 'player-video-embed',
 
-             type: 'player-{0}',
 
-             stopped: 'stopped',
 
-             playing: 'playing',
 
-             muted: 'muted',
 
-             loading: 'loading',
 
-             tooltip: 'player-tooltip',
 
-             hidden: 'sr-only',
 
-             hover: 'player-hover',
 
-             captions: {
 
-                 enabled: 'captions-enabled',
 
-                 active: 'captions-active'
 
-             },
 
-             fullscreen: {
 
-                 enabled: 'fullscreen-enabled',
 
-                 active: 'fullscreen-active',
 
-                 hideControls: 'fullscreen-hide-controls'
 
-             }
 
-         },
 
-         captions: {
 
-             defaultActive: false
 
-         },
 
-         fullscreen: {
 
-             enabled: true,
 
-             fallback: true,
 
-             hideControls: true
 
-         },
 
-         storage: {
 
-             enabled: true,
 
-             key: 'plyr_volume'
 
-         },
 
-         controls: ['restart', 'rewind', 'play', 'fast-forward', 'current-time', 'duration', 'mute', 'volume', /*'captions',*/ 'fullscreen'],
 
-         i18n: {
 
-             restart: '重新播放',
 
-             rewind: '后退{seektime}秒',
 
-             play: '播放',
 
-             pause: '暂停',
 
-             forward: '快进{seektime}秒',
 
-             played: '播放中',
 
-             buffered: '缓冲中',
 
-             currentTime: '当前时间',
 
-             duration: '持续时间',
 
-             volume: '音量',
 
-             toggleMute: '静音',
 
-             toggleCaptions: '字幕',
 
-             toggleFullscreen: '全屏'
 
-         }
 
-     };
 
-     // Build the default HTML
 
-     function _buildControls() {
 
-         // Open and add the progress and seek elements
 
-         var html = [
 
-         '<div class="player-controls">',
 
-             '<div class="player-progress">',
 
-                 '<label for="seek{id}" class="sr-only">Seek</label>',
 
-                 '<input id="seek{id}" class="player-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-player="seek">',
 
-                 '<progress class="player-progress-played" max="100" value="0">',
 
-                     '<span>0</span>% ' + config.i18n.played,
 
-                 '</progress>',
 
-                 '<progress class="player-progress-buffer" max="100" value="0">',
 
-                     '<span>0</span>% ' + config.i18n.buffered,
 
-                 '</progress>',
 
-             '</div>',
 
-             '<span class="player-controls-left">'];
 
-         // Restart button
 
-         if (_inArray(config.controls, 'restart')) {
 
-             html.push(
 
-                 '<button type="button" data-player="restart">',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-restart" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.restart + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Rewind button
 
-         if (_inArray(config.controls, 'rewind')) {
 
-             html.push(
 
-                 '<button type="button" data-player="rewind">',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-rewind" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.rewind + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Play/pause button
 
-         if (_inArray(config.controls, 'play')) {
 
-             html.push(
 
-                 '<button type="button" data-player="play">',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-play" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.play + '</span>',
 
-                 '</button>',
 
-                 '<button type="button" data-player="pause">',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-pause" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.pause + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Fast forward button
 
-         if (_inArray(config.controls, 'fast-forward')) {
 
-             html.push(
 
-                 '<button type="button" data-player="fast-forward">',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-fast-forward" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.forward + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Media current time display
 
-         if (_inArray(config.controls, 'current-time')) {
 
-             html.push(
 
-                 '<span class="player-time">',
 
-                 '<span class="sr-only">' + config.i18n.currentTime + '</span>',
 
-                 '<span class="player-current-time">00:00</span>',
 
-                 '</span>'
 
-             );
 
-         }
 
-         // Media duration display
 
-         if (_inArray(config.controls, 'duration')) {
 
-             html.push(
 
-                 '<span class="player-time">',
 
-                 '<span class="sr-only">' + config.i18n.duration + '</span>',
 
-                 '<span class="player-duration">00:00</span>',
 
-                 '</span>'
 
-             );
 
-         }
 
-         // Close left controls
 
-         html.push(
 
-             '</span>',
 
-             '<span class="player-controls-right">'
 
-         );
 
-         // Toggle mute button
 
-         if (_inArray(config.controls, 'mute')) {
 
-             html.push(
 
-                 '<button type="button" data-player="mute">',
 
-                 '<svg class="icon-muted"><use xlink:href="#' + config.iconPrefix + '-muted" /></svg>',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-volume" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.toggleMute + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Volume range control
 
-         if (_inArray(config.controls, 'volume')) {
 
-             html.push(
 
-                 '<label for="volume{id}" class="sr-only">' + config.i18n.volume + '</label>',
 
-                 '<input id="volume{id}" class="player-volume" type="range" min="0" max="10" value="5" data-player="volume">'
 
-             );
 
-         }
 
-         // Toggle captions button
 
-         if (_inArray(config.controls, 'captions')) {
 
-             html.push(
 
-                 '<button type="button" data-player="captions">',
 
-                 '<svg class="icon-captions-on"><use xlink:href="#' + config.iconPrefix + '-captions-on" /></svg>',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-captions-off" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.toggleCaptions + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Toggle fullscreen button
 
-         if (_inArray(config.controls, 'fullscreen')) {
 
-             html.push(
 
-                 '<button type="button" data-player="fullscreen">',
 
-                 '<svg class="icon-exit-fullscreen"><use xlink:href="#' + config.iconPrefix + '-exit-fullscreen" /></svg>',
 
-                 '<svg><use xlink:href="#' + config.iconPrefix + '-enter-fullscreen" /></svg>',
 
-                 '<span class="sr-only">' + config.i18n.toggleFullscreen + '</span>',
 
-                 '</button>'
 
-             );
 
-         }
 
-         // Close everything
 
-         html.push(
 
-             '</span>',
 
-             '</div>'
 
-         );
 
-         return html.join('');
 
-     }
 
-     // Debugging
 
-     function _log(text, error) {
 
-         if (config.debug && window.console) {
 
-             console[(error ? 'error' : 'log')](text);
 
-         }
 
-     }
 
-     // Credits: http://paypal.github.io/accessible-html5-video-player/
 
-     // Unfortunately, due to mixed support, UA sniffing is required
 
-     function _browserSniff() {
 
-         var nAgt = navigator.userAgent,
 
-             name = navigator.appName,
 
-             fullVersion = '' + parseFloat(navigator.appVersion),
 
-             majorVersion = parseInt(navigator.appVersion, 10),
 
-             nameOffset,
 
-             verOffset,
 
-             ix;
 
-         // MSIE 11
 
-         if ((navigator.appVersion.indexOf('Windows NT') !== -1) && (navigator.appVersion.indexOf('rv:11') !== -1)) {
 
-             name = 'IE';
 
-             fullVersion = '11;';
 
-         }
 
-         // MSIE
 
-         else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) {
 
-             name = 'IE';
 
-             fullVersion = nAgt.substring(verOffset + 5);
 
-         }
 
-         // Chrome
 
-         else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) {
 
-             name = 'Chrome';
 
-             fullVersion = nAgt.substring(verOffset + 7);
 
-         }
 
-         // Safari
 
-         else if ((verOffset = nAgt.indexOf('Safari')) !== -1) {
 
-             name = 'Safari';
 
-             fullVersion = nAgt.substring(verOffset + 7);
 
-             if ((verOffset = nAgt.indexOf('Version')) !== -1) {
 
-                 fullVersion = nAgt.substring(verOffset + 8);
 
-             }
 
-         }
 
-         // Firefox
 
-         else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) {
 
-             name = 'Firefox';
 
-             fullVersion = nAgt.substring(verOffset + 8);
 
-         }
 
-         // In most other browsers, 'name/version' is at the end of userAgent
 
-         else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
 
-             name = nAgt.substring(nameOffset, verOffset);
 
-             fullVersion = nAgt.substring(verOffset + 1);
 
-             if (name.toLowerCase() == name.toUpperCase()) {
 
-                 name = navigator.appName;
 
-             }
 
-         }
 
-         // Trim the fullVersion string at semicolon/space if present
 
-         if ((ix = fullVersion.indexOf(';')) !== -1) {
 
-             fullVersion = fullVersion.substring(0, ix);
 
-         }
 
-         if ((ix = fullVersion.indexOf(' ')) !== -1) {
 
-             fullVersion = fullVersion.substring(0, ix);
 
-         }
 
-         // Get major version
 
-         majorVersion = parseInt('' + fullVersion, 10);
 
-         if (isNaN(majorVersion)) {
 
-             fullVersion = '' + parseFloat(navigator.appVersion);
 
-             majorVersion = parseInt(navigator.appVersion, 10);
 
-         }
 
-         // Return data
 
-         return {
 
-             name: name,
 
-             version: majorVersion,
 
-             ios: /(iPad|iPhone|iPod)/g.test(navigator.platform)
 
-         };
 
-     }
 
-     // Check for mime type support against a player instance
 
-     // Credits: http://diveintohtml5.info/everything.html
 
-     // Related: http://www.leanbackplayer.com/test/h5mt.html
 
-     function _supportMime(player, mimeType) {
 
-         var media = player.media;
 
-         // Only check video types for video players
 
-         if (player.type == 'video') {
 
-             // Check type
 
-             switch (mimeType) {
 
-             case 'video/webm':
 
-                 return !!(media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, ''));
 
-             case 'video/mp4':
 
-                 return !!(media.canPlayType && media.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
 
-             case 'video/ogg':
 
-                 return !!(media.canPlayType && media.canPlayType('video/ogg; codecs="theora"').replace(/no/, ''));
 
-             }
 
-         }
 
-         // Only check audio types for audio players
 
-         else if (player.type == 'audio') {
 
-             // Check type
 
-             switch (mimeType) {
 
-             case 'audio/mpeg':
 
-                 return !!(media.canPlayType && media.canPlayType('audio/mpeg;').replace(/no/, ''));
 
-             case 'audio/ogg':
 
-                 return !!(media.canPlayType && media.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
 
-             case 'audio/wav':
 
-                 return !!(media.canPlayType && media.canPlayType('audio/wav; codecs="1"').replace(/no/, ''));
 
-             }
 
-         }
 
-         // If we got this far, we're stuffed
 
-         return false;
 
-     }
 
-     // Inject a script
 
-     function _injectScript(source) {
 
-         if (document.querySelectorAll('script[src="' + source + '"]').length) {
 
-             return;
 
-         }
 
-         var tag = document.createElement('script');
 
-         tag.src = source;
 
-         var firstScriptTag = document.getElementsByTagName('script')[0];
 
-         firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
 
-     }
 
-     // Element exists in an array
 
-     function _inArray(haystack, needle) {
 
-         return Array.prototype.indexOf && (haystack.indexOf(needle) != -1);
 
-     }
 
-     // Replace all
 
-     function _replaceAll(string, find, replace) {
 
-         return string.replace(new RegExp(find.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1'), 'g'), replace);
 
-     }
 
-     // Wrap an element
 
-     function _wrap(elements, wrapper) {
 
-         // Convert `elements` to an array, if necessary.
 
-         if (!elements.length) {
 
-             elements = [elements];
 
-         }
 
-         // Loops backwards to prevent having to clone the wrapper on the
 
-         // first element (see `child` below).
 
-         for (var i = elements.length - 1; i >= 0; i--) {
 
-             var child = (i > 0) ? wrapper.cloneNode(true) : wrapper;
 
-             var element = elements[i];
 
-             // Cache the current parent and sibling.
 
-             var parent = element.parentNode;
 
-             var sibling = element.nextSibling;
 
-             // Wrap the element (is automatically removed from its current
 
-             // parent).
 
-             child.appendChild(element);
 
-             // If the element had a sibling, insert the wrapper before
 
-             // the sibling to maintain the HTML structure; otherwise, just
 
-             // append it to the parent.
 
-             if (sibling) {
 
-                 parent.insertBefore(child, sibling);
 
-             } else {
 
-                 parent.appendChild(child);
 
-             }
 
-         }
 
-     }
 
-     // Unwrap an element
 
-     // http://plainjs.com/javascript/manipulation/unwrap-a-dom-element-35/
 
-     function _unwrap(wrapper) {
 
-         // Get the element's parent node
 
-         var parent = wrapper.parentNode;
 
-         // Move all children out of the element
 
-         while (wrapper.firstChild) {
 
-             parent.insertBefore(wrapper.firstChild, wrapper);
 
-         }
 
-         // Remove the empty element
 
-         parent.removeChild(wrapper);
 
-     }
 
-     // Remove an element
 
-     function _remove(element) {
 
-         element.parentNode.removeChild(element);
 
-     }
 
-     // Prepend child
 
-     function _prependChild(parent, element) {
 
-         parent.insertBefore(element, parent.firstChild);
 
-     }
 
-     // Set attributes
 
-     function _setAttributes(element, attributes) {
 
-         for (var key in attributes) {
 
-             element.setAttribute(key, attributes[key]);
 
-         }
 
-     }
 
-     // Toggle class on an element
 
-     function _toggleClass(element, name, state) {
 
-         if (element) {
 
-             if (element.classList) {
 
-                 element.classList[state ? 'add' : 'remove'](name);
 
-             } else {
 
-                 var className = (' ' + element.className + ' ').replace(/\s+/g, ' ').replace(' ' + name + ' ', '');
 
-                 element.className = className + (state ? ' ' + name : '');
 
-             }
 
-         }
 
-     }
 
-     // Toggle event
 
-     function _toggleHandler(element, events, callback, toggle) {
 
-         var eventList = events.split(' ');
 
-         // If a nodelist is passed, call itself on each node
 
-         if (element instanceof NodeList) {
 
-             for (var x = 0; x < element.length; x++) {
 
-                 if (element[x] instanceof Node) {
 
-                     _toggleHandler(element[x], arguments[1], arguments[2], arguments[3]);
 
-                 }
 
-             }
 
-             return;
 
-         }
 
-         // If a single node is passed, bind the event listener
 
-         for (var i = 0; i < eventList.length; i++) {
 
-             element[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, false);
 
-         }
 
-     }
 
-     // Bind event
 
-     function _on(element, events, callback) {
 
-         if (element) {
 
-             _toggleHandler(element, events, callback, true);
 
-         }
 
-     }
 
-     // Unbind event
 
-     function _off(element, events, callback) {
 
-         if (element) {
 
-             _toggleHandler(element, events, callback, false);
 
-         }
 
-     }
 
-     // Trigger event
 
-     function _triggerEvent(element, event) {
 
-         // Create faux event
 
-         var fauxEvent = document.createEvent('MouseEvents');
 
-         // Set the event type
 
-         fauxEvent.initEvent(event, true, true);
 
-         // Dispatch the event
 
-         element.dispatchEvent(fauxEvent);
 
-     }
 
-     // Toggle aria-pressed state on a toggle button
 
-     function _toggleState(target, state) {
 
-         // Get state
 
-         state = (typeof state === 'boolean' ? state : !target.getAttribute('aria-pressed'));
 
-         // Set the attribute on target
 
-         target.setAttribute('aria-pressed', state);
 
-         return state;
 
-     }
 
-     // Get percentage
 
-     function _getPercentage(current, max) {
 
-         if (current === 0 || max === 0 || isNaN(current) || isNaN(max)) {
 
-             return 0;
 
-         }
 
-         return ((current / max) * 100).toFixed(2);
 
-     }
 
-     // Deep extend/merge two Objects
 
-     // http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/
 
-     // Removed call to arguments.callee (used explicit function name instead)
 
-     function _extend(destination, source) {
 
-         for (var property in source) {
 
-             if (source[property] && source[property].constructor && source[property].constructor === Object) {
 
-                 destination[property] = destination[property] || {};
 
-                 _extend(destination[property], source[property]);
 
-             } else {
 
-                 destination[property] = source[property];
 
-             }
 
-         }
 
-         return destination;
 
-     }
 
-     // Fullscreen API
 
-     function _fullscreen() {
 
-         var fullscreen = {
 
-                 supportsFullScreen: false,
 
-                 isFullScreen: function () {
 
-                     return false;
 
-                 },
 
-                 requestFullScreen: function () {},
 
-                 cancelFullScreen: function () {},
 
-                 fullScreenEventName: '',
 
-                 element: null,
 
-                 prefix: ''
 
-             },
 
-             browserPrefixes = 'webkit moz o ms khtml'.split(' ');
 
-         // Check for native support
 
-         if (typeof document.cancelFullScreen !== 'undefined') {
 
-             fullscreen.supportsFullScreen = true;
 
-         } else {
 
-             // Check for fullscreen support by vendor prefix
 
-             for (var i = 0, il = browserPrefixes.length; i < il; i++) {
 
-                 fullscreen.prefix = browserPrefixes[i];
 
-                 if (typeof document[fullscreen.prefix + 'CancelFullScreen'] !== 'undefined') {
 
-                     fullscreen.supportsFullScreen = true;
 
-                     break;
 
-                 }
 
-                 // Special case for MS (when isn't it?)
 
-                 else if (typeof document.msExitFullscreen !== 'undefined' && document.msFullscreenEnabled) {
 
-                     fullscreen.prefix = 'ms';
 
-                     fullscreen.supportsFullScreen = true;
 
-                     break;
 
-                 }
 
-             }
 
-         }
 
-         // Update methods to do something useful
 
-         if (fullscreen.supportsFullScreen) {
 
-             // Yet again Microsoft awesomeness,
 
-             // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes
 
-             fullscreen.fullScreenEventName = (fullscreen.prefix == 'ms' ? 'MSFullscreenChange' : fullscreen.prefix + 'fullscreenchange');
 
-             fullscreen.isFullScreen = function (element) {
 
-                 if (typeof element === 'undefined') {
 
-                     element = document.body;
 
-                 }
 
-                 switch (this.prefix) {
 
-                 case '':
 
-                     return document.fullscreenElement == element;
 
-                 case 'moz':
 
-                     return document.mozFullScreenElement == element;
 
-                 default:
 
-                     return document[this.prefix + 'FullscreenElement'] == element;
 
-                 }
 
-             };
 
-             fullscreen.requestFullScreen = function (element) {
 
-                 if (typeof element === 'undefined') {
 
-                     element = document.body;
 
-                 }
 
-                 return (this.prefix === '') ? element.requestFullScreen() : element[this.prefix + (this.prefix == 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
 
-             };
 
-             fullscreen.cancelFullScreen = function () {
 
-                 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + (this.prefix == 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
 
-             };
 
-             fullscreen.element = function () {
 
-                 return (this.prefix === '') ? document.fullscreenElement : document[this.prefix + 'FullscreenElement'];
 
-             };
 
-         }
 
-         return fullscreen;
 
-     }
 
-     // Local storage
 
-     function _storage() {
 
-         var storage = {
 
-             supported: (function () {
 
-                 try {
 
-                     return 'localStorage' in window && window.localStorage !== null;
 
-                 } catch (e) {
 
-                     return false;
 
-                 }
 
-             })()
 
-         };
 
-         return storage;
 
-     }
 
-     // Player instance
 
-     function Plyr(container) {
 
-         var player = this;
 
-         player.container = container;
 
-         // Captions functions
 
-         // Seek the manual caption time and update UI
 
-         function _seekManualCaptions(time) {
 
-             // If it's not video, or we're using textTracks, bail.
 
-             if (player.usingTextTracks || player.type !== 'video' || !player.supported.full) {
 
-                 return;
 
-             }
 
-             // Reset subcount
 
-             player.subcount = 0;
 
-             // Check time is a number, if not use currentTime
 
-             // IE has a bug where currentTime doesn't go to 0
 
-             // https://twitter.com/Sam_Potts/status/573715746506731521
 
-             time = typeof time === 'number' ? time : player.media.currentTime;
 
-             while (_timecodeMax(player.captions[player.subcount][0]) < time.toFixed(1)) {
 
-                 player.subcount++;
 
-                 if (player.subcount > player.captions.length - 1) {
 
-                     player.subcount = player.captions.length - 1;
 
-                     break;
 
-                 }
 
-             }
 
-             // Check if the next caption is in the current time range
 
-             if (player.media.currentTime.toFixed(1) >= _timecodeMin(player.captions[player.subcount][0]) &&
 
-                 player.media.currentTime.toFixed(1) <= _timecodeMax(player.captions[player.subcount][0])) {
 
-                 player.currentCaption = player.captions[player.subcount][1];
 
-                 // Trim caption text
 
-                 var content = player.currentCaption.trim();
 
-                 // Render the caption (only if changed)
 
-                 if (player.captionsContainer.innerHTML != content) {
 
-                     // Empty caption
 
-                     // Otherwise NVDA reads it twice
 
-                     player.captionsContainer.innerHTML = '';
 
-                     // Set new caption text
 
-                     player.captionsContainer.innerHTML = content;
 
-                 }
 
-             } else {
 
-                 player.captionsContainer.innerHTML = '';
 
-             }
 
-         }
 
-         // Display captions container and button (for initialization)
 
-         function _showCaptions() {
 
-             // If there's no caption toggle, bail
 
-             if (!player.buttons.captions) {
 
-                 return;
 
-             }
 
-             _toggleClass(player.container, config.classes.captions.enabled, true);
 
-             if (config.captions.defaultActive) {
 
-                 _toggleClass(player.container, config.classes.captions.active, true);
 
-                 _toggleState(player.buttons.captions, true);
 
-             }
 
-         }
 
-         // Utilities for caption time codes
 
-         function _timecodeMin(tc) {
 
-             var tcpair = [];
 
-             tcpair = tc.split(' --> ');
 
-             return _subTcSecs(tcpair[0]);
 
-         }
 
-         function _timecodeMax(tc) {
 
-             var tcpair = [];
 
-             tcpair = tc.split(' --> ');
 
-             return _subTcSecs(tcpair[1]);
 
-         }
 
-         function _subTcSecs(tc) {
 
-             if (tc === null || tc === undefined) {
 
-                 return 0;
 
-             } else {
 
-                 var tc1 = [],
 
-                     tc2 = [],
 
-                     seconds;
 
-                 tc1 = tc.split(',');
 
-                 tc2 = tc1[0].split(':');
 
-                 seconds = Math.floor(tc2[0] * 60 * 60) + Math.floor(tc2[1] * 60) + Math.floor(tc2[2]);
 
-                 return seconds;
 
-             }
 
-         }
 
-         // Find all elements
 
-         function _getElements(selector) {
 
-             return player.container.querySelectorAll(selector);
 
-         }
 
-         // Find a single element
 
-         function _getElement(selector) {
 
-             return _getElements(selector)[0];
 
-         }
 
-         // Determine if we're in an iframe
 
-         function _inFrame() {
 
-             try {
 
-                 return window.self !== window.top;
 
-             } catch (e) {
 
-                 return true;
 
-             }
 
-         }
 
-         // Insert controls
 
-         function _injectControls() {
 
-             // Make a copy of the html
 
-             var html = config.html;
 
-             // Insert custom video controls
 
-             _log('Injecting custom controls.');
 
-             // If no controls are specified, create default
 
-             if (!html) {
 
-                 html = _buildControls();
 
-             }
 
-             // Replace seek time instances
 
-             html = _replaceAll(html, '{seektime}', config.seekTime);
 
-             // Replace all id references with random numbers
 
-             html = _replaceAll(html, '{id}', Math.floor(Math.random() * (10000)));
 
-             // Inject into the container
 
-             player.container.insertAdjacentHTML('beforeend', html);
 
-             // Setup tooltips
 
-             if (config.tooltips) {
 
-                 var labels = _getElements(config.selectors.labels);
 
-                 for (var i = labels.length - 1; i >= 0; i--) {
 
-                     var label = labels[i];
 
-                     _toggleClass(label, config.classes.hidden, false);
 
-                     _toggleClass(label, config.classes.tooltip, true);
 
-                 }
 
-             }
 
-         }
 
-         // Find the UI controls and store references
 
-         function _findElements() {
 
-             try {
 
-                 player.controls = _getElement(config.selectors.controls);
 
-                 // Buttons
 
-                 player.buttons = {};
 
-                 player.buttons.seek = _getElement(config.selectors.buttons.seek);
 
-                 player.buttons.play = _getElement(config.selectors.buttons.play);
 
-                 player.buttons.pause = _getElement(config.selectors.buttons.pause);
 
-                 player.buttons.restart = _getElement(config.selectors.buttons.restart);
 
-                 player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
 
-                 player.buttons.forward = _getElement(config.selectors.buttons.forward);
 
-                 player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
 
-                 // Inputs
 
-                 player.buttons.mute = _getElement(config.selectors.buttons.mute);
 
-                 player.buttons.captions = _getElement(config.selectors.buttons.captions);
 
-                 player.checkboxes = _getElements('[type="checkbox"]');
 
-                 // Progress
 
-                 player.progress = {};
 
-                 player.progress.container = _getElement(config.selectors.progress.container);
 
-                 // Progress - Buffering
 
-                 player.progress.buffer = {};
 
-                 player.progress.buffer.bar = _getElement(config.selectors.progress.buffer);
 
-                 player.progress.buffer.text = player.progress.buffer.bar && player.progress.buffer.bar.getElementsByTagName('span')[0];
 
-                 // Progress - Played
 
-                 player.progress.played = {};
 
-                 player.progress.played.bar = _getElement(config.selectors.progress.played);
 
-                 player.progress.played.text = player.progress.played.bar && player.progress.played.bar.getElementsByTagName('span')[0];
 
-                 // Volume
 
-                 player.volume = _getElement(config.selectors.buttons.volume);
 
-                 // Timing
 
-                 player.duration = _getElement(config.selectors.duration);
 
-                 player.currentTime = _getElement(config.selectors.currentTime);
 
-                 player.seekTime = _getElements(config.selectors.seekTime);
 
-                 return true;
 
-             } catch (e) {
 
-                 _log('It looks like there\'s a problem with your controls html. Bailing.', true);
 
-                 // Restore native video controls
 
-                 player.media.setAttribute('controls', '');
 
-                 return false;
 
-             }
 
-         }
 
-         // Setup aria attribute for play
 
-         function _setupPlayAria() {
 
-             // If there's no play button, bail
 
-             if (!player.buttons.play) {
 
-                 return;
 
-             }
 
-             // Find the current text
 
-             var label = player.buttons.play.innerText || config.i18n.play;
 
-             // If there's a media title set, use that for the label
 
-             if (typeof (config.title) !== 'undefined' && config.title.length) {
 
-                 label += ', ' + config.title;
 
-             }
 
-             player.buttons.play.setAttribute('aria-label', label);
 
-         }
 
-         // Setup media
 
-         function _setupMedia() {
 
-             // If there's no media, bail
 
-             if (!player.media) {
 
-                 _log('No audio or video element found!', true);
 
-                 return false;
 
-             }
 
-             if (player.supported.full) {
 
-                 // Remove native video controls
 
-                 player.media.removeAttribute('controls');
 
-                 // Add type class
 
-                 _toggleClass(player.container, config.classes.type.replace('{0}', player.type), true);
 
-                 // If there's no autoplay attribute, assume the video is stopped and add state class
 
-                 _toggleClass(player.container, config.classes.stopped, (player.media.getAttribute('autoplay') === null));
 
-                 // Add iOS class
 
-                 if (player.browser.ios) {
 
-                     _toggleClass(player.container, 'ios', true);
 
-                 }
 
-                 // Inject the player wrapper
 
-                 if (player.type === 'video') {
 
-                     // Create the wrapper div
 
-                     var wrapper = document.createElement('div');
 
-                     wrapper.setAttribute('class', config.classes.videoWrapper);
 
-                     // Wrap the video in a container
 
-                     _wrap(player.media, wrapper);
 
-                     // Cache the container
 
-                     player.videoContainer = wrapper;
 
-                 }
 
-             }
 
-             // YouTube
 
-             if (player.type == 'youtube') {
 
-                 _setupYouTube(player.media.getAttribute('data-video-id'));
 
-             }
 
-             // Autoplay
 
-             if (player.media.getAttribute('autoplay') !== null) {
 
-                 _play();
 
-             }
 
-         }
 
-         // Setup YouTube
 
-         function _setupYouTube(id) {
 
-             // Remove old containers
 
-             var containers = _getElements('[id^="youtube"]');
 
-             for (var i = containers.length - 1; i >= 0; i--) {
 
-                 _remove(containers[i]);
 
-             }
 
-             // Create the YouTube container
 
-             var container = document.createElement('div');
 
-             container.setAttribute('id', 'youtube-' + Math.floor(Math.random() * (10000)));
 
-             player.media.appendChild(container);
 
-             // Add embed class for responsive
 
-             _toggleClass(player.media, config.classes.videoWrapper, true);
 
-             _toggleClass(player.media, config.classes.embedWrapper, true);
 
-             if (typeof YT === 'object') {
 
-                 _YTReady(id, container);
 
-             } else {
 
-                 // Load the API
 
-                 _injectScript('https://www.youtube.com/iframe_api');
 
-                 // Add callback to queue
 
-                 callbacks.youtube.push(function () {
 
-                     _YTReady(id, container);
 
-                 });
 
-                 // Setup callback for the API
 
-                 window.onYouTubeIframeAPIReady = function () {
 
-                     for (var i = callbacks.youtube.length - 1; i >= 0; i--) {
 
-                         // Fire callback
 
-                         callbacks.youtube[i]();
 
-                         // Remove from queue
 
-                         callbacks.youtube.splice(i, 1);
 
-                     }
 
-                 };
 
-             }
 
-         }
 
-         // Handle API ready
 
-         function _YTReady(id, container) {
 
-             _log('YouTube API Ready');
 
-             // Setup timers object
 
-             // We have to poll YouTube for updates
 
-             if (!('timer' in player)) {
 
-                 player.timer = {};
 
-             }
 
-             // Setup instance
 
-             // https://developers.google.com/youtube/iframe_api_reference
 
-             player.embed = new YT.Player(container.id, {
 
-                 videoId: id,
 
-                 playerVars: {
 
-                     autoplay: 0,
 
-                     controls: (player.supported.full ? 0 : 1),
 
-                     rel: 0,
 
-                     showinfo: 0,
 
-                     iv_load_policy: 3,
 
-                     cc_load_policy: (config.captions.defaultActive ? 1 : 0),
 
-                     cc_lang_pref: 'en',
 
-                     wmode: 'transparent',
 
-                     modestbranding: 1,
 
-                     disablekb: 1
 
-                 },
 
-                 events: {
 
-                     'onReady': function (event) {
 
-                         // Get the instance
 
-                         var instance = event.target;
 
-                         // Create a faux HTML5 API using the YouTube API
 
-                         player.media.play = function () {
 
-                             instance.playVideo();
 
-                         };
 
-                         player.media.pause = function () {
 
-                             instance.pauseVideo();
 
-                         };
 
-                         player.media.stop = function () {
 
-                             instance.stopVideo();
 
-                         };
 
-                         player.media.duration = instance.getDuration();
 
-                         player.media.paused = true;
 
-                         player.media.currentTime = instance.getCurrentTime();
 
-                         player.media.muted = instance.isMuted();
 
-                         // Trigger timeupdate
 
-                         _triggerEvent(player.media, 'timeupdate');
 
-                         // Reset timer
 
-                         window.clearInterval(player.timer.buffering);
 
-                         // Setup buffering
 
-                         player.timer.buffering = window.setInterval(function () {
 
-                             // Get loaded % from YouTube
 
-                             player.media.buffered = instance.getVideoLoadedFraction();
 
-                             // Trigger progress
 
-                             _triggerEvent(player.media, 'progress');
 
-                             // Bail if we're at 100%
 
-                             if (player.media.buffered === 1) {
 
-                                 window.clearInterval(player.timer.buffering);
 
-                             }
 
-                         }, 200);
 
-                         if (player.supported.full) {
 
-                             // Only setup controls once
 
-                             if (!player.container.querySelectorAll(config.selectors.controls).length) {
 
-                                 _setupInterface();
 
-                             }
 
-                             // Display duration if available
 
-                             if (config.displayDuration) {
 
-                                 _displayDuration();
 
-                             }
 
-                         }
 
-                     },
 
-                     'onStateChange': function (event) {
 
-                         // Get the instance
 
-                         var instance = event.target;
 
-                         // Reset timer
 
-                         window.clearInterval(player.timer.playing);
 
-                         // Handle events
 
-                         // -1   Unstarted
 
-                         // 0    Ended
 
-                         // 1    Playing
 
-                         // 2    Paused
 
-                         // 3    Buffering
 
-                         // 5    Video cued
 
-                         switch (event.data) {
 
-                         case 0:
 
-                             player.media.paused = true;
 
-                             _triggerEvent(player.media, 'ended');
 
-                             break;
 
-                         case 1:
 
-                             player.media.paused = false;
 
-                             _triggerEvent(player.media, 'play');
 
-                             // Poll to get playback progress
 
-                             player.timer.playing = window.setInterval(function () {
 
-                                 // Set the current time
 
-                                 player.media.currentTime = instance.getCurrentTime();
 
-                                 // Trigger timeupdate
 
-                                 _triggerEvent(player.media, 'timeupdate');
 
-                             }, 200);
 
-                             break;
 
-                         case 2:
 
-                             player.media.paused = true;
 
-                             _triggerEvent(player.media, 'pause');
 
-                         }
 
-                     }
 
-                 }
 
-             });
 
-         }
 
-         // Setup captions
 
-         function _setupCaptions() {
 
-             if (player.type === 'video') {
 
-                 // Inject the container
 
-                 player.videoContainer.insertAdjacentHTML('afterbegin', '<div class="' + config.selectors.captions.replace('.', '') + '"><span></span></div>');
 
-                 // Cache selector
 
-                 player.captionsContainer = _getElement(config.selectors.captions).querySelector('span');
 
-                 // Determine if HTML5 textTracks is supported
 
-                 player.usingTextTracks = false;
 
-                 if (player.media.textTracks) {
 
-                     player.usingTextTracks = true;
 
-                 }
 
-                 // Get URL of caption file if exists
 
-                 var captionSrc = '',
 
-                     kind,
 
-                     children = player.media.childNodes;
 
-                 for (var i = 0; i < children.length; i++) {
 
-                     if (children[i].nodeName.toLowerCase() === 'track') {
 
-                         kind = children[i].kind;
 
-                         if (kind === 'captions' || kind === 'subtitles') {
 
-                             captionSrc = children[i].getAttribute('src');
 
-                         }
 
-                     }
 
-                 }
 
-                 // Record if caption file exists or not
 
-                 player.captionExists = true;
 
-                 if (captionSrc === '') {
 
-                     player.captionExists = false;
 
-                     _log('No caption track found.');
 
-                 } else {
 
-                     _log('Caption track found; URI: ' + captionSrc);
 
-                 }
 
-                 // If no caption file exists, hide container for caption text
 
-                 if (!player.captionExists) {
 
-                     _toggleClass(player.container, config.classes.captions.enabled);
 
-                 }
 
-                 // If caption file exists, process captions
 
-                 else {
 
-                     // Turn off native caption rendering to avoid double captions
 
-                     // This doesn't seem to work in Safari 7+, so the <track> elements are removed from the dom below
 
-                     var tracks = player.media.textTracks;
 
-                     for (var x = 0; x < tracks.length; x++) {
 
-                         tracks[x].mode = 'hidden';
 
-                     }
 
-                     // Enable UI
 
-                     _showCaptions(player);
 
-                     // Disable unsupported browsers than report false positive
 
-                     if ((player.browser.name === 'IE' && player.browser.version >= 10) ||
 
-                         (player.browser.name === 'Firefox' && player.browser.version >= 31) ||
 
-                         (player.browser.name === 'Chrome' && player.browser.version >= 43) ||
 
-                         (player.browser.name === 'Safari' && player.browser.version >= 7)) {
 
-                         // Debugging
 
-                         _log('Detected unsupported browser for HTML5 captions. Using fallback.');
 
-                         // Set to false so skips to 'manual' captioning
 
-                         player.usingTextTracks = false;
 
-                     }
 
-                     // Rendering caption tracks
 
-                     // Native support required - http://caniuse.com/webvtt
 
-                     if (player.usingTextTracks) {
 
-                         _log('TextTracks supported.');
 
-                         for (var y = 0; y < tracks.length; y++) {
 
-                             var track = tracks[y];
 
-                             if (track.kind === 'captions' || track.kind === 'subtitles') {
 
-                                 _on(track, 'cuechange', function () {
 
-                                     // Clear container
 
-                                     player.captionsContainer.innerHTML = '';
 
-                                     // Display a cue, if there is one
 
-                                     if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) {
 
-                                         player.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim());
 
-                                     }
 
-                                 });
 
-                             }
 
-                         }
 
-                     }
 
-                     // Caption tracks not natively supported
 
-                     else {
 
-                         _log('TextTracks not supported so rendering captions manually.');
 
-                         // Render captions from array at appropriate time
 
-                         player.currentCaption = '';
 
-                         player.captions = [];
 
-                         if (captionSrc !== '') {
 
-                             // Create XMLHttpRequest Object
 
-                             var xhr = new XMLHttpRequest();
 
-                             xhr.onreadystatechange = function () {
 
-                                 if (xhr.readyState === 4) {
 
-                                     if (xhr.status === 200) {
 
-                                         var records = [],
 
-                                             record,
 
-                                             req = xhr.responseText;
 
-                                         records = req.split('\n\n');
 
-                                         for (var r = 0; r < records.length; r++) {
 
-                                             record = records[r];
 
-                                             player.captions[r] = [];
 
-                                             player.captions[r] = record.split('\n');
 
-                                         }
 
-                                         // Remove first element ('VTT')
 
-                                         player.captions.shift();
 
-                                         _log('Successfully loaded the caption file via AJAX.');
 
-                                     } else {
 
-                                         _log('There was a problem loading the caption file via AJAX.', true);
 
-                                     }
 
-                                 }
 
-                             };
 
-                             xhr.open('get', captionSrc, true);
 
-                             xhr.send();
 
-                         }
 
-                     }
 
-                     // If Safari 7+, removing track from DOM [see 'turn off native caption rendering' above]
 
-                     if (player.browser.name === 'Safari' && player.browser.version >= 7) {
 
-                         _log('Safari 7+ detected; removing track from DOM.');
 
-                         // Find all <track> elements
 
-                         tracks = player.media.getElementsByTagName('track');
 
-                         // Loop through and remove one by one
 
-                         for (var t = 0; t < tracks.length; t++) {
 
-                             player.media.removeChild(tracks[t]);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         // Setup fullscreen
 
-         function _setupFullscreen() {
 
-             if (player.type != 'audio' && config.fullscreen.enabled) {
 
-                 // Check for native support
 
-                 var nativeSupport = fullscreen.supportsFullScreen;
 
-                 if (nativeSupport || (config.fullscreen.fallback && !_inFrame())) {
 
-                     _log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled.');
 
-                     // Add styling hook
 
-                     _toggleClass(player.container, config.classes.fullscreen.enabled, true);
 
-                 } else {
 
-                     _log('Fullscreen not supported and fallback disabled.');
 
-                 }
 
-                 // Toggle state
 
-                 _toggleState(player.buttons.fullscreen, false);
 
-                 // Set control hide class hook
 
-                 if (config.fullscreen.hideControls) {
 
-                     _toggleClass(player.container, config.classes.fullscreen.hideControls, true);
 
-                 }
 
-             }
 
-         }
 
-         // Play media
 
-         function _play() {
 
-             player.media.play();
 
-         }
 
-         // Pause media
 
-         function _pause() {
 
-             player.media.pause();
 
-         }
 
-         // Toggle playback
 
-         function _togglePlay(toggle) {
 
-             // Play
 
-             if (toggle === true) {
 
-                 _play();
 
-             }
 
-             // Pause
 
-             else if (toggle === false) {
 
-                 _pause();
 
-             }
 
-             // True toggle
 
-             else {
 
-                 player.media[player.media.paused ? 'play' : 'pause']();
 
-             }
 
-         }
 
-         // Rewind
 
-         function _rewind(seekTime) {
 
-             // Use default if needed
 
-             if (typeof seekTime !== 'number') {
 
-                 seekTime = config.seekTime;
 
-             }
 
-             _seek(player.media.currentTime - seekTime);
 
-         }
 
-         // Fast forward
 
-         function _forward(seekTime) {
 
-             // Use default if needed
 
-             if (typeof seekTime !== 'number') {
 
-                 seekTime = config.seekTime;
 
-             }
 
-             _seek(player.media.currentTime + seekTime);
 
-         }
 
-         // Seek to time
 
-         // The input parameter can be an event or a number
 
-         function _seek(input) {
 
-             var targetTime = 0,
 
-                 paused = player.media.paused;
 
-             // Explicit position
 
-             if (typeof input === 'number') {
 
-                 targetTime = input;
 
-             }
 
-             // Event
 
-             else if (typeof input === 'object' && (input.type === 'input' || input.type === 'change')) {
 
-                 // It's the seek slider
 
-                 // Seek to the selected time
 
-                 targetTime = ((input.target.value / input.target.max) * player.media.duration);
 
-             }
 
-             // Normalise targetTime
 
-             if (targetTime < 0) {
 
-                 targetTime = 0;
 
-             } else if (targetTime > player.media.duration) {
 
-                 targetTime = player.media.duration;
 
-             }
 
-             // Set the current time
 
-             // Try/catch incase the media isn't set and we're calling seek() from source() and IE moans
 
-             try {
 
-                 player.media.currentTime = targetTime.toFixed(1);
 
-             } catch (e) {}
 
-             // YouTube
 
-             if (player.type == 'youtube') {
 
-                 player.embed.seekTo(targetTime);
 
-                 if (paused) {
 
-                     _pause();
 
-                 }
 
-                 // Trigger timeupdate
 
-                 _triggerEvent(player.media, 'timeupdate');
 
-             }
 
-             // Logging
 
-             _log('Seeking to ' + player.media.currentTime + ' seconds');
 
-             // Special handling for 'manual' captions
 
-             _seekManualCaptions(targetTime);
 
-         }
 
-         // Check playing state
 
-         function _checkPlaying() {
 
-             _toggleClass(player.container, config.classes.playing, !player.media.paused);
 
-             _toggleClass(player.container, config.classes.stopped, player.media.paused);
 
-         }
 
-         // Toggle fullscreen
 
-         function _toggleFullscreen(event) {
 
-             // Check for native support
 
-             var nativeSupport = fullscreen.supportsFullScreen;
 
-             // If it's a fullscreen change event, it's probably a native close
 
-             if (event && event.type === fullscreen.fullScreenEventName) {
 
-                 player.isFullscreen = fullscreen.isFullScreen(player.container);
 
-             }
 
-             // If there's native support, use it
 
-             else if (nativeSupport) {
 
-                 // Request fullscreen
 
-                 if (!fullscreen.isFullScreen(player.container)) {
 
-                     fullscreen.requestFullScreen(player.container);
 
-                 }
 
-                 // Bail from fullscreen
 
-                 else {
 
-                     fullscreen.cancelFullScreen();
 
-                 }
 
-                 // Check if we're actually full screen (it could fail)
 
-                 player.isFullscreen = fullscreen.isFullScreen(player.container);
 
-             } else {
 
-                 // Otherwise, it's a simple toggle
 
-                 player.isFullscreen = !player.isFullscreen;
 
-                 // Bind/unbind escape key
 
-                 if (player.isFullscreen) {
 
-                     _on(document, 'keyup', _handleEscapeFullscreen);
 
-                     document.body.style.overflow = 'hidden';
 
-                 } else {
 
-                     _off(document, 'keyup', _handleEscapeFullscreen);
 
-                     document.body.style.overflow = '';
 
-                 }
 
-             }
 
-             // Set class hook
 
-             _toggleClass(player.container, config.classes.fullscreen.active, player.isFullscreen);
 
-             // Set button state
 
-             _toggleState(player.buttons.fullscreen, player.isFullscreen);
 
-             // Toggle controls visibility based on mouse movement and location
 
-             var hoverTimer, isMouseOver = false;
 
-             // Show the player controls
 
-             function _showControls() {
 
-                 // Set shown class
 
-                 _toggleClass(player.container, config.classes.hover, true);
 
-                 // Clear timer every movement
 
-                 window.clearTimeout(hoverTimer);
 
-                 // If the mouse is not over the controls, set a timeout to hide them
 
-                 if (!isMouseOver) {
 
-                     hoverTimer = window.setTimeout(function () {
 
-                         _toggleClass(player.container, config.classes.hover, false);
 
-                     }, 2000);
 
-                 }
 
-             }
 
-             // Check mouse is over the controls
 
-             function _setMouseOver(event) {
 
-                 isMouseOver = (event.type === 'mouseenter');
 
-             }
 
-             if (config.fullscreen.hideControls) {
 
-                 // Hide on entering full screen
 
-                 _toggleClass(player.controls, config.classes.hover, false);
 
-                 // Keep an eye on the mouse location in relation to controls
 
-                 _toggleHandler(player.controls, 'mouseenter mouseleave', _setMouseOver, player.isFullscreen);
 
-                 // Show the controls on mouse move
 
-                 _toggleHandler(player.container, 'mousemove', _showControls, player.isFullscreen);
 
-             }
 
-         }
 
-         // Bail from faux-fullscreen
 
-         function _handleEscapeFullscreen(event) {
 
-             // If it's a keypress and not escape, bail
 
-             if ((event.which || event.charCode || event.keyCode) === 27 && player.isFullscreen) {
 
-                 _toggleFullscreen();
 
-             }
 
-         }
 
-         // Set volume
 
-         function _setVolume(volume) {
 
-             // Use default if no value specified
 
-             if (typeof volume === 'undefined') {
 
-                 if (config.storage.enabled && _storage().supported) {
 
-                     volume = window.localStorage[config.storage.key] || config.volume;
 
-                 } else {
 
-                     volume = config.volume;
 
-                 }
 
-             }
 
-             // Maximum is 10
 
-             if (volume > 10) {
 
-                 volume = 10;
 
-             }
 
-             // Minimum is 0
 
-             if (volume < 0) {
 
-                 volume = 0;
 
-             }
 
-             // Set the player volume
 
-             player.media.volume = parseFloat(volume / 10);
 
-             // YouTube
 
-             if (player.type == 'youtube') {
 
-                 player.embed.setVolume(player.media.volume * 100);
 
-                 // Trigger timeupdate
 
-                 _triggerEvent(player.media, 'volumechange');
 
-             }
 
-             // Toggle muted state
 
-             if (player.media.muted && volume > 0) {
 
-                 _toggleMute();
 
-             }
 
-         }
 
-         // Mute
 
-         function _toggleMute(muted) {
 
-             // If the method is called without parameter, toggle based on current value
 
-             if (typeof muted !== 'boolean') {
 
-                 muted = !player.media.muted;
 
-             }
 
-             // Set button state
 
-             _toggleState(player.buttons.mute, muted);
 
-             // Set mute on the player
 
-             player.media.muted = muted;
 
-             // YouTube
 
-             if (player.type === 'youtube') {
 
-                 player.embed[player.media.muted ? 'mute' : 'unMute']();
 
-                 // Trigger timeupdate
 
-                 _triggerEvent(player.media, 'volumechange');
 
-             }
 
-         }
 
-         // Update volume UI and storage
 
-         function _updateVolume() {
 
-             // Get the current volume
 
-             var volume = player.media.muted ? 0 : (player.media.volume * 10);
 
-             // Update the <input type="range"> if present
 
-             if (player.supported.full && player.volume) {
 
-                 player.volume.value = volume;
 
-             }
 
-             // Store the volume in storage
 
-             if (config.storage.enabled && _storage().supported) {
 
-                 window.localStorage.setItem(config.storage.key, volume);
 
-             }
 
-             // Toggle class if muted
 
-             _toggleClass(player.container, config.classes.muted, (volume === 0));
 
-             // Update checkbox for mute state
 
-             if (player.supported.full && player.buttons.mute) {
 
-                 _toggleState(player.buttons.mute, (volume === 0));
 
-             }
 
-         }
 
-         // Toggle captions
 
-         function _toggleCaptions(show) {
 
-             // If there's no full support, or there's no caption toggle
 
-             if (!player.supported.full || !player.buttons.captions) {
 
-                 return;
 
-             }
 
-             // If the method is called without parameter, toggle based on current value
 
-             if (typeof show !== 'boolean') {
 
-                 show = (player.container.className.indexOf(config.classes.captions.active) === -1);
 
-             }
 
-             // Toggle state
 
-             _toggleState(player.buttons.captions, show);
 
-             // Add class hook
 
-             _toggleClass(player.container, config.classes.captions.active, show);
 
-         }
 
-         // Check if media is loading
 
-         function _checkLoading(event) {
 
-             var loading = (event.type === 'waiting');
 
-             // Clear timer
 
-             clearTimeout(player.loadingTimer);
 
-             // Timer to prevent flicker when seeking
 
-             player.loadingTimer = setTimeout(function () {
 
-                 _toggleClass(player.container, config.classes.loading, loading);
 
-             }, (loading ? 250 : 0));
 
-         }
 
-         // Update <progress> elements
 
-         function _updateProgress(event) {
 
-             var progress = player.progress.played.bar,
 
-                 text = player.progress.played.text,
 
-                 value = 0;
 
-             if (event) {
 
-                 switch (event.type) {
 
-                     // Video playing
 
-                 case 'timeupdate':
 
-                 case 'seeking':
 
-                     value = _getPercentage(player.media.currentTime, player.media.duration);
 
-                     // Set seek range value only if it's a 'natural' time event
 
-                     if (event.type == 'timeupdate' && player.buttons.seek) {
 
-                         player.buttons.seek.value = value;
 
-                     }
 
-                     break;
 
-                     // Events from seek range
 
-                 case 'change':
 
-                 case 'input':
 
-                     value = event.target.value;
 
-                     break;
 
-                     // Check buffer status
 
-                 case 'playing':
 
-                 case 'progress':
 
-                     progress = player.progress.buffer.bar;
 
-                     text = player.progress.buffer.text;
 
-                     value = (function () {
 
-                         var buffered = player.media.buffered;
 
-                         // HTML5
 
-                         if (buffered && buffered.length) {
 
-                             return _getPercentage(buffered.end(0), player.media.duration);
 
-                         }
 
-                         // YouTube returns between 0 and 1
 
-                         else if (typeof buffered === 'number') {
 
-                             return (buffered * 100);
 
-                         }
 
-                         return 0;
 
-                     })();
 
-                 }
 
-             }
 
-             // Set values
 
-             if (progress) {
 
-                 progress.value = value;
 
-             }
 
-             if (text) {
 
-                 text.innerHTML = value;
 
-             }
 
-         }
 
-         // Update the displayed time
 
-         function _updateTimeDisplay(time, element) {
 
-             // Bail if there's no duration display
 
-             if (!element) {
 
-                 return;
 
-             }
 
-             player.secs = parseInt(time % 60);
 
-             player.mins = parseInt((time / 60) % 60);
 
-             player.hours = parseInt(((time / 60) / 60) % 60);
 
-             // Do we need to display hours?
 
-             var displayHours = (parseInt(((player.media.duration / 60) / 60) % 60) > 0);
 
-             // Ensure it's two digits. For example, 03 rather than 3.
 
-             player.secs = ('0' + player.secs).slice(-2);
 
-             player.mins = ('0' + player.mins).slice(-2);
 
-             // Render
 
-             element.innerHTML = (displayHours ? player.hours + ':' : '') + player.mins + ':' + player.secs;
 
-         }
 
-         // Show the duration on metadataloaded
 
-         function _displayDuration() {
 
-             var duration = player.media.duration || 0;
 
-             // If there's only one time display, display duration there
 
-             if (!player.duration && config.displayDuration && player.media.paused) {
 
-                 _updateTimeDisplay(duration, player.currentTime);
 
-             }
 
-             // If there's a duration element, update content
 
-             if (player.duration) {
 
-                 _updateTimeDisplay(duration, player.duration);
 
-             }
 
-         }
 
-         // Handle time change event
 
-         function _timeUpdate(event) {
 
-             // Duration
 
-             _updateTimeDisplay(player.media.currentTime, player.currentTime);
 
-             // Playing progress
 
-             _updateProgress(event);
 
-         }
 
-         // Remove <source> children and src attribute
 
-         function _removeSources() {
 
-             // Find child <source> elements
 
-             var sources = player.media.querySelectorAll('source');
 
-             // Remove each
 
-             for (var i = sources.length - 1; i >= 0; i--) {
 
-                 _remove(sources[i]);
 
-             }
 
-             // Remove src attribute
 
-             player.media.removeAttribute('src');
 
-         }
 
-         // Inject a source
 
-         function _addSource(attributes) {
 
-             if (attributes.src) {
 
-                 // Create a new <source>
 
-                 var element = document.createElement('source');
 
-                 // Set all passed attributes
 
-                 _setAttributes(element, attributes);
 
-                 // Inject the new source
 
-                 _prependChild(player.media, element);
 
-             }
 
-         }
 
-         // Update source
 
-         // Sources are not checked for support so be careful
 
-         function _parseSource(sources) {
 
-             // YouTube
 
-             if (player.type === 'youtube' && typeof sources === 'string') {
 
-                 // Destroy YouTube instance
 
-                 player.embed.destroy();
 
-                 // Re-setup YouTube
 
-                 // We don't use loadVideoBy[x] here since it has issues
 
-                 _setupYouTube(sources);
 
-                 // Update times
 
-                 _timeUpdate();
 
-                 // Bail
 
-                 return;
 
-             }
 
-             // Pause playback (webkit freaks out)
 
-             _pause();
 
-             // Restart
 
-             _seek();
 
-             // Remove current sources
 
-             _removeSources();
 
-             // If a single source is passed
 
-             // .source('path/to/video.mp4')
 
-             if (typeof sources === 'string') {
 
-                 _addSource({
 
-                     src: sources
 
-                 });
 
-             }
 
-             // An array of source objects
 
-             // Check if a source exists, use that or set the 'src' attribute?
 
-             // .source([{ src: 'path/to/video.mp4', type: 'video/mp4' },{ src: 'path/to/video.webm', type: 'video/webm' }])
 
-             else if (sources.constructor === Array) {
 
-                 for (var index in sources) {
 
-                     _addSource(sources[index]);
 
-                 }
 
-             }
 
-             if (player.supported.full) {
 
-                 // Reset time display
 
-                 _timeUpdate();
 
-                 // Update the UI
 
-                 _checkPlaying();
 
-             }
 
-             // Re-load sources
 
-             player.media.load();
 
-             // Play if autoplay attribute is present
 
-             if (player.media.getAttribute('autoplay') !== null) {
 
-                 _play();
 
-             }
 
-         }
 
-         // Update poster
 
-         function _updatePoster(source) {
 
-             if (player.type === 'video') {
 
-                 player.media.setAttribute('poster', source);
 
-             }
 
-         }
 
-         // Listen for events
 
-         function _listeners() {
 
-             // IE doesn't support input event, so we fallback to change
 
-             var inputEvent = (player.browser.name == 'IE' ? 'change' : 'input');
 
-             // Detect tab focus
 
-             function checkFocus() {
 
-                 var focused = document.activeElement;
 
-                 if (!focused || focused == document.body) {
 
-                     focused = null;
 
-                 } else if (document.querySelector) {
 
-                     focused = document.querySelector(':focus');
 
-                 }
 
-                 for (var button in player.buttons) {
 
-                     var element = player.buttons[button];
 
-                     _toggleClass(element, 'tab-focus', (element === focused));
 
-                 }
 
-             }
 
-             _on(window, 'keyup', function (event) {
 
-                 var code = (event.keyCode ? event.keyCode : event.which);
 
-                 if (code == 9) {
 
-                     checkFocus();
 
-                 }
 
-             });
 
-             for (var button in player.buttons) {
 
-                 var element = player.buttons[button];
 
-                 _on(element, 'blur', function () {
 
-                     _toggleClass(element, 'tab-focus', false);
 
-                 });
 
-             }
 
-             // Play
 
-             _on(player.buttons.play, 'click', function () {
 
-                 _play();
 
-                 setTimeout(function () {
 
-                     player.buttons.pause.focus();
 
-                 }, 100);
 
-             });
 
-             // Pause
 
-             _on(player.buttons.pause, 'click', function () {
 
-                 _pause();
 
-                 setTimeout(function () {
 
-                     player.buttons.play.focus();
 
-                 }, 100);
 
-             });
 
-             // Restart
 
-             _on(player.buttons.restart, 'click', _seek);
 
-             // Rewind
 
-             _on(player.buttons.rewind, 'click', _rewind);
 
-             // Fast forward
 
-             _on(player.buttons.forward, 'click', _forward);
 
-             // Seek
 
-             _on(player.buttons.seek, inputEvent, _seek);
 
-             // Set volume
 
-             _on(player.volume, inputEvent, function () {
 
-                 _setVolume(this.value);
 
-             });
 
-             // Mute
 
-             _on(player.buttons.mute, 'click', _toggleMute);
 
-             // Fullscreen
 
-             _on(player.buttons.fullscreen, 'click', _toggleFullscreen);
 
-             // Handle user exiting fullscreen by escaping etc
 
-             if (fullscreen.supportsFullScreen) {
 
-                 _on(document, fullscreen.fullScreenEventName, _toggleFullscreen);
 
-             }
 
-             // Time change on media
 
-             _on(player.media, 'timeupdate seeking', _timeUpdate);
 
-             // Update manual captions
 
-             _on(player.media, 'timeupdate', _seekManualCaptions);
 
-             // Display duration
 
-             _on(player.media, 'loadedmetadata', _displayDuration);
 
-             // Captions
 
-             _on(player.buttons.captions, 'click', _toggleCaptions);
 
-             // Handle the media finishing
 
-             _on(player.media, 'ended', function () {
 
-                 // Clear
 
-                 if (player.type === 'video') {
 
-                     player.captionsContainer.innerHTML = '';
 
-                 }
 
-                 // Reset UI
 
-                 _checkPlaying();
 
-             });
 
-             // Check for buffer progress
 
-             _on(player.media, 'progress playing', _updateProgress);
 
-             // Handle native mute
 
-             _on(player.media, 'volumechange', _updateVolume);
 
-             // Handle native play/pause
 
-             _on(player.media, 'play pause', _checkPlaying);
 
-             // Loading
 
-             _on(player.media, 'waiting canplay seeked', _checkLoading);
 
-             // Click video
 
-             if (player.type === 'video' && config.click) {
 
-                 _on(player.videoContainer, 'click', function () {
 
-                     if (player.media.paused) {
 
-                         _triggerEvent(player.buttons.play, 'click');
 
-                     } else if (player.media.ended) {
 
-                         _seek();
 
-                         _triggerEvent(player.buttons.play, 'click');
 
-                     } else {
 
-                         _triggerEvent(player.buttons.pause, 'click');
 
-                     }
 
-                 });
 
-             }
 
-         }
 
-         // Destroy an instance
 
-         // Event listeners are removed when elements are removed
 
-         // http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory
 
-         function _destroy() {
 
-             // Bail if the element is not initialized
 
-             if (!player.init) {
 
-                 return null;
 
-             }
 
-             // Reset container classname
 
-             player.container.setAttribute('class', config.selectors.container.replace('.', ''));
 
-             // Remove init flag
 
-             player.init = false;
 
-             // Remove controls
 
-             _remove(_getElement(config.selectors.controls));
 
-             // YouTube
 
-             if (player.type === 'youtube') {
 
-                 player.embed.destroy();
 
-                 return;
 
-             }
 
-             // If video, we need to remove some more
 
-             if (player.type === 'video') {
 
-                 // Remove captions
 
-                 _remove(_getElement(config.selectors.captions));
 
-                 // Remove video wrapper
 
-                 _unwrap(player.videoContainer);
 
-             }
 
-             // Restore native video controls
 
-             player.media.setAttribute('controls', '');
 
-             // Clone the media element to remove listeners
 
-             // http://stackoverflow.com/questions/19469881/javascript-remove-all-event-listeners-of-specific-type
 
-             var clone = player.media.cloneNode(true);
 
-             player.media.parentNode.replaceChild(clone, player.media);
 
-         }
 
-         // Setup a player
 
-         function _init() {
 
-             // Bail if the element is initialized
 
-             if (player.init) {
 
-                 return null;
 
-             }
 
-             // Setup the fullscreen api
 
-             fullscreen = _fullscreen();
 
-             // Sniff out the browser
 
-             player.browser = _browserSniff();
 
-             // Get the media element
 
-             player.media = player.container.querySelectorAll('audio, video, div')[0];
 
-             // Set media type
 
-             var tagName = player.media.tagName.toLowerCase();
 
-             if (tagName === 'div') {
 
-                 player.type = player.media.getAttribute('data-type');
 
-             } else {
 
-                 player.type = tagName;
 
-             }
 
-             // Check for full support
 
-             player.supported = api.supported(player.type);
 
-             // If no native support, bail
 
-             if (!player.supported.basic) {
 
-                 return false;
 
-             }
 
-             // Debug info
 
-             _log(player.browser.name + ' ' + player.browser.version);
 
-             // Setup media
 
-             _setupMedia();
 
-             // Setup interface
 
-             if (player.type == 'video' || player.type == 'audio') {
 
-                 // Bail if no support
 
-                 if (!player.supported.full) {
 
-                     // Successful setup
 
-                     player.init = true;
 
-                     // Don't inject controls if no full support
 
-                     return;
 
-                 }
 
-                 // Setup UI
 
-                 _setupInterface();
 
-                 // Display duration if available
 
-                 if (config.displayDuration) {
 
-                     _displayDuration();
 
-                 }
 
-                 // Set up aria-label for Play button with the title option
 
-                 _setupPlayAria();
 
-             }
 
-             // Successful setup
 
-             player.init = true;
 
-         }
 
-         function _setupInterface() {
 
-             // Inject custom controls
 
-             _injectControls();
 
-             // Find the elements
 
-             if (!_findElements()) {
 
-                 return false;
 
-             }
 
-             // Captions
 
-             _setupCaptions();
 
-             // Set volume
 
-             _setVolume();
 
-             _updateVolume();
 
-             // Setup fullscreen
 
-             _setupFullscreen();
 
-             // Listeners
 
-             _listeners();
 
-         }
 
-         // Initialize instance
 
-         _init();
 
-         // If init failed, return an empty object
 
-         if (!player.init) {
 
-             return {};
 
-         }
 
-         return {
 
-             media: player.media,
 
-             play: _play,
 
-             pause: _pause,
 
-             restart: _seek,
 
-             rewind: _rewind,
 
-             forward: _forward,
 
-             seek: _seek,
 
-             source: _parseSource,
 
-             poster: _updatePoster,
 
-             setVolume: _setVolume,
 
-             togglePlay: _togglePlay,
 
-             toggleMute: _toggleMute,
 
-             toggleCaptions: _toggleCaptions,
 
-             toggleFullscreen: _toggleFullscreen,
 
-             isFullscreen: function () {
 
-                 return player.isFullscreen || false;
 
-             },
 
-             support: function (mimeType) {
 
-                 return _supportMime(player, mimeType);
 
-             },
 
-             destroy: _destroy,
 
-             restore: _init
 
-         };
 
-     }
 
-     // Check for support
 
-     api.supported = function (type) {
 
-         var browser = _browserSniff(),
 
-             oldIE = (browser.name === 'IE' && browser.version <= 9),
 
-             iPhone = /iPhone|iPod/i.test(navigator.userAgent),
 
-             audio = !!document.createElement('audio').canPlayType,
 
-             video = !!document.createElement('video').canPlayType,
 
-             basic, full;
 
-         switch (type) {
 
-         case 'video':
 
-             basic = video;
 
-             full = (basic && (!oldIE && !iPhone));
 
-             break;
 
-         case 'audio':
 
-             basic = audio;
 
-             full = (basic && !oldIE);
 
-             break;
 
-         case 'youtube':
 
-             basic = true;
 
-             full = (!oldIE && !iPhone);
 
-             break;
 
-         default:
 
-             basic = (audio && video);
 
-             full = (basic && !oldIE);
 
-         }
 
-         return {
 
-             basic: basic,
 
-             full: full
 
-         };
 
-     };
 
-     // Expose setup function
 
-     api.setup = function (options) {
 
-         // Extend the default options with user specified
 
-         config = _extend(defaults, options);
 
-         // Bail if disabled or no basic support
 
-         // You may want to disable certain UAs etc
 
-         if (!config.enabled || !api.supported().basic) {
 
-             return false;
 
-         }
 
-         // Get the players
 
-         var elements = document.querySelectorAll(config.selectors.container),
 
-             players = [];
 
-         // Create a player instance for each element
 
-         for (var i = elements.length - 1; i >= 0; i--) {
 
-             // Get the current element
 
-             var element = elements[i];
 
-             // Setup a player instance and add to the element
 
-             if (typeof element.plyr === 'undefined') {
 
-                 // Create new instance
 
-                 var instance = new Plyr(element);
 
-                 // Set plyr to false if setup failed
 
-                 element.plyr = (Object.keys(instance).length ? instance : false);
 
-                 // Callback
 
-                 if (typeof config.onSetup === 'function') {
 
-                     config.onSetup.apply(element.plyr);
 
-                 }
 
-             }
 
-             // Add to return array even if it's already setup
 
-             players.push(element.plyr);
 
-         }
 
-         return players;
 
-     };
 
- }(this.plyr = this.plyr || {}));
 
 
  |