Plugin Directory

Changeset 863995


Ignore:
Timestamp:
02/24/2014 11:18:42 AM (12 years ago)
Author:
amolv
Message:

js file updates

Location:
soundslides/trunk
Files:
2 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • soundslides/trunk/js/jquery.jplayer.js

    r574407 r863995  
    33 * http://www.jplayer.org
    44 *
    5  * Copyright (c) 2009 - 2011 Happyworm Ltd
    6  * Dual licensed under the MIT and GPL licenses.
    7  *  - http://www.opensource.org/licenses/mit-license.php
    8  *  - http://www.gnu.org/copyleft/gpl.html
     5 * Copyright (c) 2009 - 2013 Happyworm Ltd
     6 * Licensed under the MIT license.
     7 * http://opensource.org/licenses/MIT
    98 *
    109 * Author: Mark J Panaghiston
    11  * Version: 2.1.0
    12  * Date: 1st September 2011
     10 * Version: 2.5.0
     11 * Date: 7th November 2013
    1312 */
    1413
    15 /* Code verified using http://www.jshint.com/ */
    16 /*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, nomem:false, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false */
    17 /*global jQuery:false, ActiveXObject:false, alert:false */
    18 
    19 (function($, undefined) {
    20 
    21     // Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge
    22     $.fn.jPlayer = function( options ) {
    23         var name = "jPlayer";
    24         var isMethodCall = typeof options === "string",
    25             args = Array.prototype.slice.call( arguments, 1 ),
    26             returnValue = this;
    27 
    28         // allow multiple hashes to be passed on init
    29         options = !isMethodCall && args.length ?
    30             $.extend.apply( null, [ true, options ].concat(args) ) :
    31             options;
    32 
    33         // prevent calls to internal methods
    34         if ( isMethodCall && options.charAt( 0 ) === "_" ) {
    35             return returnValue;
    36         }
    37 
    38         if ( isMethodCall ) {
    39             this.each(function() {
    40                 var instance = $.data( this, name ),
    41                     methodValue = instance && $.isFunction( instance[options] ) ?
    42                         instance[ options ].apply( instance, args ) :
    43                         instance;
    44                 if ( methodValue !== instance && methodValue !== undefined ) {
    45                     returnValue = methodValue;
    46                     return false;
    47                 }
    48             });
    49         } else {
    50             this.each(function() {
    51                 var instance = $.data( this, name );
    52                 if ( instance ) {
    53                     // instance.option( options || {} )._init(); // Orig jquery.ui.widget.js code: Not recommend for jPlayer. ie., Applying new options to an existing instance (via the jPlayer constructor) and performing the _init(). The _init() is what concerns me. It would leave a lot of event handlers acting on jPlayer instance and the interface.
    54                     instance.option( options || {} ); // The new constructor only changes the options. Changing options only has basic support atm.
    55                 } else {
    56                     $.data( this, name, new $.jPlayer( options, this ) );
    57                 }
    58             });
    59         }
    60 
    61         return returnValue;
    62     };
    63 
    64     $.jPlayer = function( options, element ) {
    65         // allow instantiation without initializing for simple inheritance
    66         if ( arguments.length ) {
    67             this.element = $(element);
    68             this.options = $.extend(true, {},
    69                 this.options,
    70                 options
    71             );
    72             var self = this;
    73             this.element.bind( "remove.jPlayer", function() {
    74                 self.destroy();
    75             });
    76             this._init();
    77         }
    78     };
    79     // End of: (Adapted from jquery.ui.widget.js (1.8.7))
    80 
    81     // Emulated HTML5 methods and properties
    82     $.jPlayer.emulateMethods = "load play pause";
    83     $.jPlayer.emulateStatus = "src readyState networkState currentTime duration paused ended playbackRate";
    84     $.jPlayer.emulateOptions = "muted volume";
    85 
    86     // Reserved event names generated by jPlayer that are not part of the HTML5 Media element spec
    87     $.jPlayer.reservedEvent = "ready flashreset resize repeat error warning";
    88 
    89     // Events generated by jPlayer
    90     $.jPlayer.event = {
    91         ready: "jPlayer_ready",
    92         flashreset: "jPlayer_flashreset", // Similar to the ready event if the Flash solution is set to display:none and then shown again or if it's reloaded for another reason by the browser. For example, using CSS position:fixed on Firefox for the full screen feature.
    93         resize: "jPlayer_resize", // Occurs when the size changes through a full/restore screen operation or if the size/sizeFull options are changed.
    94         repeat: "jPlayer_repeat", // Occurs when the repeat status changes. Usually through clicks on the repeat button of the interface.
    95         click: "jPlayer_click", // Occurs when the user clicks on one of the following: poster image, html video, flash video.
    96         error: "jPlayer_error", // Event error code in event.jPlayer.error.type. See $.jPlayer.error
    97         warning: "jPlayer_warning", // Event warning code in event.jPlayer.warning.type. See $.jPlayer.warning
    98 
    99         // Other events match HTML5 spec.
    100         loadstart: "jPlayer_loadstart",
    101         progress: "jPlayer_progress",
    102         suspend: "jPlayer_suspend",
    103         abort: "jPlayer_abort",
    104         emptied: "jPlayer_emptied",
    105         stalled: "jPlayer_stalled",
    106         play: "jPlayer_play",
    107         pause: "jPlayer_pause",
    108         loadedmetadata: "jPlayer_loadedmetadata",
    109         loadeddata: "jPlayer_loadeddata",
    110         waiting: "jPlayer_waiting",
    111         playing: "jPlayer_playing",
    112         canplay: "jPlayer_canplay",
    113         canplaythrough: "jPlayer_canplaythrough",
    114         seeking: "jPlayer_seeking",
    115         seeked: "jPlayer_seeked",
    116         timeupdate: "jPlayer_timeupdate",
    117         ended: "jPlayer_ended",
    118         ratechange: "jPlayer_ratechange",
    119         durationchange: "jPlayer_durationchange",
    120         volumechange: "jPlayer_volumechange"
    121     };
    122 
    123     $.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPlayer event, without any internal action.
    124         "loadstart",
    125         // "progress", // jPlayer uses internally before bubbling.
    126         // "suspend", // jPlayer uses internally before bubbling.
    127         "abort",
    128         // "error", // jPlayer uses internally before bubbling.
    129         "emptied",
    130         "stalled",
    131         // "play", // jPlayer uses internally before bubbling.
    132         // "pause", // jPlayer uses internally before bubbling.
    133         "loadedmetadata",
    134         "loadeddata",
    135         // "waiting", // jPlayer uses internally before bubbling.
    136         // "playing", // jPlayer uses internally before bubbling.
    137         "canplay",
    138         "canplaythrough",
    139         // "seeking", // jPlayer uses internally before bubbling.
    140         // "seeked", // jPlayer uses internally before bubbling.
    141         // "timeupdate", // jPlayer uses internally before bubbling.
    142         // "ended", // jPlayer uses internally before bubbling.
    143         "ratechange"
    144         // "durationchange" // jPlayer uses internally before bubbling.
    145         // "volumechange" // jPlayer uses internally before bubbling.
    146     ];
    147 
    148     $.jPlayer.pause = function() {
    149         $.each($.jPlayer.prototype.instances, function(i, element) {
    150             if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
    151                 element.jPlayer("pause");
    152             }
    153         });
    154     };
    155    
    156     $.jPlayer.timeFormat = {
    157         showHour: false,
    158         showMin: true,
    159         showSec: true,
    160         padHour: false,
    161         padMin: true,
    162         padSec: true,
    163         sepHour: ":",
    164         sepMin: ":",
    165         sepSec: ""
    166     };
    167 
    168     $.jPlayer.convertTime = function(s) {
    169         var myTime = new Date(s * 1000);
    170         var hour = myTime.getUTCHours();
    171         var min = myTime.getUTCMinutes();
    172         var sec = myTime.getUTCSeconds();
    173         var strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour : hour;
    174         var strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min;
    175         var strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec;
    176         return (($.jPlayer.timeFormat.showHour) ? strHour + $.jPlayer.timeFormat.sepHour : "") + (($.jPlayer.timeFormat.showMin) ? strMin + $.jPlayer.timeFormat.sepMin : "") + (($.jPlayer.timeFormat.showSec) ? strSec + $.jPlayer.timeFormat.sepSec : "");
    177     };
    178 
    179     // Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.2 does not detect Chrome as webkit.
    180     $.jPlayer.uaBrowser = function( userAgent ) {
    181         var ua = userAgent.toLowerCase();
    182 
    183         // Useragent RegExp
    184         var rwebkit = /(webkit)[ \/]([\w.]+)/;
    185         var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/;
    186         var rmsie = /(msie) ([\w.]+)/;
    187         var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;
    188 
    189         var match = rwebkit.exec( ua ) ||
    190             ropera.exec( ua ) ||
    191             rmsie.exec( ua ) ||
    192             ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
    193             [];
    194 
    195         return { browser: match[1] || "", version: match[2] || "0" };
    196     };
    197 
    198     // Platform sniffer for detecting mobile devices
    199     $.jPlayer.uaPlatform = function( userAgent ) {
    200         var ua = userAgent.toLowerCase();
    201 
    202         // Useragent RegExp
    203         var rplatform = /(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/;
    204         var rtablet = /(ipad|playbook)/;
    205         var randroid = /(android)/;
    206         var rmobile = /(mobile)/;
    207 
    208         var platform = rplatform.exec( ua ) || [];
    209         var tablet = rtablet.exec( ua ) ||
    210             !rmobile.exec( ua ) && randroid.exec( ua ) ||
    211             [];
    212 
    213         if(platform[1]) {
    214             platform[1] = platform[1].replace(/\s/g, "_"); // Change whitespace to underscore. Enables dot notation.
    215         }
    216 
    217         return { platform: platform[1] || "", tablet: tablet[1] || "" };
    218     };
    219 
    220     $.jPlayer.browser = {
    221     };
    222     $.jPlayer.platform = {
    223     };
    224 
    225     var browserMatch = $.jPlayer.uaBrowser(navigator.userAgent);
    226     if ( browserMatch.browser ) {
    227         $.jPlayer.browser[ browserMatch.browser ] = true;
    228         $.jPlayer.browser.version = browserMatch.version;
    229     }
    230     var platformMatch = $.jPlayer.uaPlatform(navigator.userAgent);
    231     if ( platformMatch.platform ) {
    232         $.jPlayer.platform[ platformMatch.platform ] = true;
    233         $.jPlayer.platform.mobile = !platformMatch.tablet;
    234         $.jPlayer.platform.tablet = !!platformMatch.tablet;
    235     }
    236 
    237     $.jPlayer.prototype = {
    238         count: 0, // Static Variable: Change it via prototype.
    239         version: { // Static Object
    240             script: "2.1.0",
    241             needFlash: "2.1.0",
    242             flash: "unknown"
    243         },
    244         options: { // Instanced in $.jPlayer() constructor
    245             swfPath: "js", // Path to Jplayer.swf. Can be relative, absolute or server root relative.
    246             solution: "html, flash", // Valid solutions: html, flash. Order defines priority. 1st is highest,
    247             supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest,
    248             preload: 'metadata',  // HTML5 Spec values: none, metadata, auto.
    249             volume: 0.8, // The volume. Number 0 to 1.
    250             muted: false,
    251             wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu.
    252             backgroundColor: "#000000", // To define the jPlayer div and Flash background color.
    253             cssSelectorAncestor: "#jp_container_1",
    254             cssSelector: { // * denotes properties that should only be required when video media type required. _cssSelector() would require changes to enable splitting these into Audio and Video defaults.
    255                 videoPlay: ".jp-video-play", // *
    256                 play: ".jp-play",
    257                 pause: ".jp-pause",
    258                 stop: ".jp-stop",
    259                 seekBar: ".jp-seek-bar",
    260                 playBar: ".jp-play-bar",
    261                 mute: ".jp-mute",
    262                 unmute: ".jp-unmute",
    263                 volumeBar: ".jp-volume-bar",
    264                 volumeBarValue: ".jp-volume-bar-value",
    265                 volumeMax: ".jp-volume-max",
    266                 currentTime: ".jp-current-time",
    267                 duration: ".jp-duration",
    268                 fullScreen: ".jp-full-screen", // *
    269                 restoreScreen: ".jp-restore-screen", // *
    270                 repeat: ".jp-repeat",
    271                 repeatOff: ".jp-repeat-off",
    272                 gui: ".jp-gui", // The interface used with autohide feature.
    273                 noSolution: ".jp-no-solution" // For error feedback when jPlayer cannot find a solution.
    274             },
    275             fullScreen: false,
    276             autohide: {
    277                 restored: false, // Controls the interface autohide feature.
    278                 full: true, // Controls the interface autohide feature.
    279                 fadeIn: 200, // Milliseconds. The period of the fadeIn anim.
    280                 fadeOut: 600, // Milliseconds. The period of the fadeOut anim.
    281                 hold: 1000 // Milliseconds. The period of the pause before autohide beings.
    282             },
    283             loop: false,
    284             repeat: function(event) { // The default jPlayer repeat event handler
    285                 if(event.jPlayer.options.loop) {
    286                     $(this).unbind(".jPlayerRepeat").bind($.jPlayer.event.ended + ".jPlayer.jPlayerRepeat", function() {
    287                         $(this).jPlayer("play");
    288                     });
    289                 } else {
    290                     $(this).unbind(".jPlayerRepeat");
    291                 }
    292             },
    293             nativeVideoControls: {
    294                 // Works well on standard browsers.
    295                 // Phone and tablet browsers can have problems with the controls disappearing.
    296             },
    297             noFullScreen: {
    298                 msie: /msie [0-6]/,
    299                 ipad: /ipad.*?os [0-4]/,
    300                 iphone: /iphone/,
    301                 ipod: /ipod/,
    302                 android_pad: /android [0-3](?!.*?mobile)/,
    303                 android_phone: /android.*?mobile/,
    304                 blackberry: /blackberry/,
    305                 windows_ce: /windows ce/,
    306                 webos: /webos/
    307             },
    308             noVolume: {
    309                 ipad: /ipad/,
    310                 iphone: /iphone/,
    311                 ipod: /ipod/,
    312                 android_pad: /android(?!.*?mobile)/,
    313                 android_phone: /android.*?mobile/,
    314                 blackberry: /blackberry/,
    315                 windows_ce: /windows ce/,
    316                 webos: /webos/,
    317                 playbook: /playbook/
    318             },
    319             verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height.
    320             // globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances
    321             // globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances
    322             idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \
    323             noConflict: "jQuery",
    324             emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element.
    325             errorAlerts: false,
    326             warningAlerts: false
    327         },
    328         optionsAudio: {
    329             size: {
    330                 width: "0px",
    331                 height: "0px",
    332                 cssClass: ""
    333             },
    334             sizeFull: {
    335                 width: "0px",
    336                 height: "0px",
    337                 cssClass: ""
    338             }
    339         },
    340         optionsVideo: {
    341             size: {
    342                 width: "480px",
    343                 height: "270px",
    344                 cssClass: "jp-video-270p"
    345             },
    346             sizeFull: {
    347                 width: "100%",
    348                 height: "100%",
    349                 cssClass: "jp-video-full"
    350             }
    351         },
    352         instances: {}, // Static Object
    353         status: { // Instanced in _init()
    354             src: "",
    355             media: {},
    356             paused: true,
    357             format: {},
    358             formatType: "",
    359             waitForPlay: true, // Same as waitForLoad except in case where preloading.
    360             waitForLoad: true,
    361             srcSet: false,
    362             video: false, // True if playing a video
    363             seekPercent: 0,
    364             currentPercentRelative: 0,
    365             currentPercentAbsolute: 0,
    366             currentTime: 0,
    367             duration: 0,
    368             readyState: 0,
    369             networkState: 0,
    370             playbackRate: 1,
    371             ended: 0
    372 
    373 /*      Persistant status properties created dynamically at _init():
    374             width
    375             height
    376             cssClass
    377             nativeVideoControls
    378             noFullScreen
    379             noVolume
    380 */
    381         },
    382 
    383         internal: { // Instanced in _init()
    384             ready: false
    385             // instance: undefined
    386             // domNode: undefined
    387             // htmlDlyCmdId: undefined
    388             // autohideId: undefined
    389         },
    390         solution: { // Static Object: Defines the solutions built in jPlayer.
    391             html: true,
    392             flash: true
    393         },
    394         // 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"')
    395         format: { // Static Object
    396             mp3: {
    397                 codec: 'audio/mpeg; codecs="mp3"',
    398                 flashCanPlay: true,
    399                 media: 'audio'
    400             },
    401             m4a: { // AAC / MP4
    402                 codec: 'audio/mp4; codecs="mp4a.40.2"',
    403                 flashCanPlay: true,
    404                 media: 'audio'
    405             },
    406             oga: { // OGG
    407                 codec: 'audio/ogg; codecs="vorbis"',
    408                 flashCanPlay: false,
    409                 media: 'audio'
    410             },
    411             wav: { // PCM
    412                 codec: 'audio/wav; codecs="1"',
    413                 flashCanPlay: false,
    414                 media: 'audio'
    415             },
    416             webma: { // WEBM
    417                 codec: 'audio/webm; codecs="vorbis"',
    418                 flashCanPlay: false,
    419                 media: 'audio'
    420             },
    421             fla: { // FLV / F4A
    422                 codec: 'audio/x-flv',
    423                 flashCanPlay: true,
    424                 media: 'audio'
    425             },
    426             m4v: { // H.264 / MP4
    427                 codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
    428                 flashCanPlay: true,
    429                 media: 'video'
    430             },
    431             ogv: { // OGG
    432                 codec: 'video/ogg; codecs="theora, vorbis"',
    433                 flashCanPlay: false,
    434                 media: 'video'
    435             },
    436             webmv: { // WEBM
    437                 codec: 'video/webm; codecs="vorbis, vp8"',
    438                 flashCanPlay: false,
    439                 media: 'video'
    440             },
    441             flv: { // FLV / F4V
    442                 codec: 'video/x-flv',
    443                 flashCanPlay: true,
    444                 media: 'video'
    445             }
    446         },
    447         _init: function() {
    448             var self = this;
    449            
    450             this.element.empty();
    451            
    452             this.status = $.extend({}, this.status); // Copy static to unique instance.
    453             this.internal = $.extend({}, this.internal); // Copy static to unique instance.
    454 
    455             this.internal.domNode = this.element.get(0);
    456 
    457             this.formats = []; // Array based on supplied string option. Order defines priority.
    458             this.solutions = []; // Array based on solution string option. Order defines priority.
    459             this.require = {}; // Which media types are required: video, audio.
    460            
    461             this.htmlElement = {}; // DOM elements created by jPlayer
    462             this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
    463             this.html.audio = {};
    464             this.html.video = {};
    465             this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
    466            
    467             this.css = {};
    468             this.css.cs = {}; // Holds the css selector strings
    469             this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method)
    470 
    471             this.ancestorJq = []; // Holds jQuery selector of cssSelectorAncestor. Init would use $() instead of [], but it is only 1.4+
    472 
    473             this.options.volume = this._limitValue(this.options.volume, 0, 1); // Limit volume value's bounds.
    474 
    475             // Create the formats array, with prority based on the order of the supplied formats string
    476             $.each(this.options.supplied.toLowerCase().split(","), function(index1, value1) {
    477                 var format = value1.replace(/^\s+|\s+$/g, ""); //trim
    478                 if(self.format[format]) { // Check format is valid.
    479                     var dupFound = false;
    480                     $.each(self.formats, function(index2, value2) { // Check for duplicates
    481                         if(format === value2) {
    482                             dupFound = true;
    483                             return false;
    484                         }
    485                     });
    486                     if(!dupFound) {
    487                         self.formats.push(format);
    488                     }
    489                 }
    490             });
    491 
    492             // Create the solutions array, with prority based on the order of the solution string
    493             $.each(this.options.solution.toLowerCase().split(","), function(index1, value1) {
    494                 var solution = value1.replace(/^\s+|\s+$/g, ""); //trim
    495                 if(self.solution[solution]) { // Check solution is valid.
    496                     var dupFound = false;
    497                     $.each(self.solutions, function(index2, value2) { // Check for duplicates
    498                         if(solution === value2) {
    499                             dupFound = true;
    500                             return false;
    501                         }
    502                     });
    503                     if(!dupFound) {
    504                         self.solutions.push(solution);
    505                     }
    506                 }
    507             });
    508 
    509             this.internal.instance = "jp_" + this.count;
    510             this.instances[this.internal.instance] = this.element;
    511 
    512             // Check the jPlayer div has an id and create one if required. Important for Flash to know the unique id for comms.
    513             if(!this.element.attr("id")) {
    514                 this.element.attr("id", this.options.idPrefix + "_jplayer_" + this.count);
    515             }
    516 
    517             this.internal.self = $.extend({}, {
    518                 id: this.element.attr("id"),
    519                 jq: this.element
    520             });
    521             this.internal.audio = $.extend({}, {
    522                 id: this.options.idPrefix + "_audio_" + this.count,
    523                 jq: undefined
    524             });
    525             this.internal.video = $.extend({}, {
    526                 id: this.options.idPrefix + "_video_" + this.count,
    527                 jq: undefined
    528             });
    529             this.internal.flash = $.extend({}, {
    530                 id: this.options.idPrefix + "_flash_" + this.count,
    531                 jq: undefined,
    532                 swf: this.options.swfPath + (this.options.swfPath.toLowerCase().slice(-4) !== ".swf" ? (this.options.swfPath && this.options.swfPath.slice(-1) !== "/" ? "/" : "") + "Jplayer.swf" : "")
    533             });
    534             this.internal.poster = $.extend({}, {
    535                 id: this.options.idPrefix + "_poster_" + this.count,
    536                 jq: undefined
    537             });
    538 
    539             // Register listeners defined in the constructor
    540             $.each($.jPlayer.event, function(eventName,eventType) {
    541                 if(self.options[eventName] !== undefined) {
    542                     self.element.bind(eventType + ".jPlayer", self.options[eventName]); // With .jPlayer namespace.
    543                     self.options[eventName] = undefined; // Destroy the handler pointer copy on the options. Reason, events can be added/removed in other ways so this could be obsolete and misleading.
    544                 }
    545             });
    546 
    547             // Determine if we require solutions for audio, video or both media types.
    548             this.require.audio = false;
    549             this.require.video = false;
    550             $.each(this.formats, function(priority, format) {
    551                 self.require[self.format[format].media] = true;
    552             });
    553 
    554             // Now required types are known, finish the options default settings.
    555             if(this.require.video) {
    556                 this.options = $.extend(true, {},
    557                     this.optionsVideo,
    558                     this.options
    559                 );
    560             } else {
    561                 this.options = $.extend(true, {},
    562                     this.optionsAudio,
    563                     this.options
    564                 );
    565             }
    566             this._setSize(); // update status and jPlayer element size
    567 
    568             // Determine the status for Blocklisted options.
    569             this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls);
    570             this.status.noFullScreen = this._uaBlocklist(this.options.noFullScreen);
    571             this.status.noVolume = this._uaBlocklist(this.options.noVolume);
    572 
    573             // The native controls are only for video and are disabled when audio is also used.
    574             this._restrictNativeVideoControls();
    575 
    576             // Create the poster image.
    577             this.htmlElement.poster = document.createElement('img');
    578             this.htmlElement.poster.id = this.internal.poster.id;
    579             this.htmlElement.poster.onload = function() { // Note that this did not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false); Did not investigate x-browser.
    580                 if(!self.status.video || self.status.waitForPlay) {
    581                     self.internal.poster.jq.show();
    582                 }
    583             };
    584             this.element.append(this.htmlElement.poster);
    585             this.internal.poster.jq = $("#" + this.internal.poster.id);
    586             this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height});
    587             this.internal.poster.jq.hide();
    588             this.internal.poster.jq.bind("click.jPlayer", function() {
    589                 self._trigger($.jPlayer.event.click);
    590             });
    591            
    592             // Generate the required media elements
    593             this.html.audio.available = false;
    594             if(this.require.audio) { // If a supplied format is audio
    595                 this.htmlElement.audio = document.createElement('audio');
    596                 this.htmlElement.audio.id = this.internal.audio.id;
    597                 this.html.audio.available = !!this.htmlElement.audio.canPlayType && this._testCanPlayType(this.htmlElement.audio); // Test is for IE9 on Win Server 2008.
    598             }
    599             this.html.video.available = false;
    600             if(this.require.video) { // If a supplied format is video
    601                 this.htmlElement.video = document.createElement('video');
    602                 this.htmlElement.video.id = this.internal.video.id;
    603                 this.html.video.available = !!this.htmlElement.video.canPlayType && this._testCanPlayType(this.htmlElement.video); // Test is for IE9 on Win Server 2008.
    604             }
    605 
    606             this.flash.available = this._checkForFlash(10);
    607 
    608             this.html.canPlay = {};
    609             this.flash.canPlay = {};
    610             $.each(this.formats, function(priority, format) {
    611                 self.html.canPlay[format] = self.html[self.format[format].media].available && "" !== self.htmlElement[self.format[format].media].canPlayType(self.format[format].codec);
    612                 self.flash.canPlay[format] = self.format[format].flashCanPlay && self.flash.available;
    613             });
    614             this.html.desired = false;
    615             this.flash.desired = false;
    616             $.each(this.solutions, function(solutionPriority, solution) {
    617                 if(solutionPriority === 0) {
    618                     self[solution].desired = true;
    619                 } else {
    620                     var audioCanPlay = false;
    621                     var videoCanPlay = false;
    622                     $.each(self.formats, function(formatPriority, format) {
    623                         if(self[self.solutions[0]].canPlay[format]) { // The other solution can play
    624                             if(self.format[format].media === 'video') {
    625                                 videoCanPlay = true;
    626                             } else {
    627                                 audioCanPlay = true;
    628                             }
    629                         }
    630                     });
    631                     self[solution].desired = (self.require.audio && !audioCanPlay) || (self.require.video && !videoCanPlay);
    632                 }
    633             });
    634             // This is what jPlayer will support, based on solution and supplied.
    635             this.html.support = {};
    636             this.flash.support = {};
    637             $.each(this.formats, function(priority, format) {
    638                 self.html.support[format] = self.html.canPlay[format] && self.html.desired;
    639                 self.flash.support[format] = self.flash.canPlay[format] && self.flash.desired;
    640             });
    641             // If jPlayer is supporting any format in a solution, then the solution is used.
    642             this.html.used = false;
    643             this.flash.used = false;
    644             $.each(this.solutions, function(solutionPriority, solution) {
    645                 $.each(self.formats, function(formatPriority, format) {
    646                     if(self[solution].support[format]) {
    647                         self[solution].used = true;
    648                         return false;
    649                     }
    650                 });
    651             });
    652 
    653             // Init solution active state and the event gates to false.
    654             this._resetActive();
    655             this._resetGate();
    656 
    657             // Set up the css selectors for the control and feedback entities.
    658             this._cssSelectorAncestor(this.options.cssSelectorAncestor);
    659            
    660             // If neither html nor flash are being used by this browser, then media playback is not possible. Trigger an error event.
    661             if(!(this.html.used || this.flash.used)) {
    662                 this._error( {
    663                     type: $.jPlayer.error.NO_SOLUTION,
    664                     context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}",
    665                     message: $.jPlayer.errorMsg.NO_SOLUTION,
    666                     hint: $.jPlayer.errorHint.NO_SOLUTION
    667                 });
    668                 if(this.css.jq.noSolution.length) {
    669                     this.css.jq.noSolution.show();
    670                 }
    671             } else {
    672                 if(this.css.jq.noSolution.length) {
    673                     this.css.jq.noSolution.hide();
    674                 }
    675             }
    676 
    677             // Add the flash solution if it is being used.
    678             if(this.flash.used) {
    679                 var htmlObj,
    680                 flashVars = 'jQuery=' + encodeURI(this.options.noConflict) + '&id=' + encodeURI(this.internal.self.id) + '&vol=' + this.options.volume + '&muted=' + this.options.muted;
    681 
    682                 // Code influenced by SWFObject 2.2: http://code.google.com/p/swfobject/
    683                 // Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event.
    684 
    685                 if($.browser.msie && Number($.browser.version) <= 8) {
    686                     var objStr = '<object id="' + this.internal.flash.id + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0"></object>';
    687 
    688                     var paramStr = [
    689                         '<param name="movie" value="' + this.internal.flash.swf + '" />',
    690                         '<param name="FlashVars" value="' + flashVars + '" />',
    691                         '<param name="allowScriptAccess" value="always" />',
    692                         '<param name="bgcolor" value="' + this.options.backgroundColor + '" />',
    693                         '<param name="wmode" value="' + this.options.wmode + '" />'
    694                     ];
    695 
    696                     htmlObj = document.createElement(objStr);
    697                     for(var i=0; i < paramStr.length; i++) {
    698                         htmlObj.appendChild(document.createElement(paramStr[i]));
    699                     }
    700                 } else {
    701                     var createParam = function(el, n, v) {
    702                         var p = document.createElement("param");
    703                         p.setAttribute("name", n); 
    704                         p.setAttribute("value", v);
    705                         el.appendChild(p);
    706                     };
    707 
    708                     htmlObj = document.createElement("object");
    709                     htmlObj.setAttribute("id", this.internal.flash.id);
    710                     htmlObj.setAttribute("data", this.internal.flash.swf);
    711                     htmlObj.setAttribute("type", "application/x-shockwave-flash");
    712                     htmlObj.setAttribute("width", "1"); // Non-zero
    713                     htmlObj.setAttribute("height", "1"); // Non-zero
    714                     createParam(htmlObj, "flashvars", flashVars);
    715                     createParam(htmlObj, "allowscriptaccess", "always");
    716                     createParam(htmlObj, "bgcolor", this.options.backgroundColor);
    717                     createParam(htmlObj, "wmode", this.options.wmode);
    718                 }
    719 
    720                 this.element.append(htmlObj);
    721                 this.internal.flash.jq = $(htmlObj);
    722             }
    723            
    724             // Add the HTML solution if being used.
    725             if(this.html.used) {
    726 
    727                 // The HTML Audio handlers
    728                 if(this.html.audio.available) {
    729                     this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio);
    730                     this.element.append(this.htmlElement.audio);
    731                     this.internal.audio.jq = $("#" + this.internal.audio.id);
    732                 }
    733 
    734                 // The HTML Video handlers
    735                 if(this.html.video.available) {
    736                     this._addHtmlEventListeners(this.htmlElement.video, this.html.video);
    737                     this.element.append(this.htmlElement.video);
    738                     this.internal.video.jq = $("#" + this.internal.video.id);
    739                     if(this.status.nativeVideoControls) {
    740                         this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
    741                     } else {
    742                         this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS
    743                     }
    744                     this.internal.video.jq.bind("click.jPlayer", function() {
    745                         self._trigger($.jPlayer.event.click);
    746                     });
    747                 }
    748             }
    749 
    750             // Create the bridge that emulates the HTML Media element on the jPlayer DIV
    751             if( this.options.emulateHtml ) {
    752                 this._emulateHtmlBridge();
    753             }
    754 
    755             if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms.
    756                 setTimeout( function() {
    757                     self.internal.ready = true;
    758                     self.version.flash = "n/a";
    759                     self._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option.
    760                     self._trigger($.jPlayer.event.ready);
    761                 }, 100);
    762             }
    763 
    764             // Initialize the interface components with the options.
    765             this._updateNativeVideoControls(); // Must do this first, otherwise there is a bizarre bug in iOS 4.3.2, where the native controls are not shown. Fails in iOS if called after _updateButtons() below. Works if called later in setMedia too, so it odd.
    766             this._updateInterface();
    767             this._updateButtons(false);
    768             this._updateAutohide();
    769             this._updateVolume(this.options.volume);
    770             this._updateMute(this.options.muted);
    771             if(this.css.jq.videoPlay.length) {
    772                 this.css.jq.videoPlay.hide();
    773             }
    774 
    775             $.jPlayer.prototype.count++; // Change static variable via prototype.
    776         },
    777         destroy: function() {
    778             // MJP: The background change remains. Would need to store the original to restore it correctly.
    779             // MJP: The jPlayer element's size change remains.
    780 
    781             // Clear the media to reset the GUI and stop any downloads. Streams on some browsers had persited. (Chrome)
    782             this.clearMedia();
    783             // Remove the size/sizeFull cssClass from the cssSelectorAncestor
    784             this._removeUiClass();
    785             // Remove the times from the GUI
    786             if(this.css.jq.currentTime.length) {
    787                 this.css.jq.currentTime.text("");
    788             }
    789             if(this.css.jq.duration.length) {
    790                 this.css.jq.duration.text("");
    791             }
    792             // Remove any bindings from the interface controls.
    793             $.each(this.css.jq, function(fn, jq) {
    794                 // Check selector is valid before trying to execute method.
    795                 if(jq.length) {
    796                     jq.unbind(".jPlayer");
    797                 }
    798             });
    799             // Remove the click handlers for $.jPlayer.event.click
    800             this.internal.poster.jq.unbind(".jPlayer");
    801             if(this.internal.video.jq) {
    802                 this.internal.video.jq.unbind(".jPlayer");
    803             }
    804             // Destroy the HTML bridge.
    805             if(this.options.emulateHtml) {
    806                 this._destroyHtmlBridge();
    807             }
    808             this.element.removeData("jPlayer"); // Remove jPlayer data
    809             this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor
    810             this.element.empty(); // Remove the inserted child elements
    811            
    812             delete this.instances[this.internal.instance]; // Clear the instance on the static instance object
    813         },
    814         enable: function() { // Plan to implement
    815             // options.disabled = false
    816         },
    817         disable: function () { // Plan to implement
    818             // options.disabled = true
    819         },
    820         _testCanPlayType: function(elem) {
    821             // IE9 on Win Server 2008 did not implement canPlayType(), but it has the property.
    822             try {
    823                 elem.canPlayType(this.format.mp3.codec); // The type is irrelevant.
    824                 return true;
    825             } catch(err) {
    826                 return false;
    827             }
    828         },
    829         _uaBlocklist: function(list) {
    830             // list : object with properties that are all regular expressions. Property names are irrelevant.
    831             // Returns true if the user agent is matched in list.
    832             var ua = navigator.userAgent.toLowerCase(),
    833                 block = false;
    834 
    835             $.each(list, function(p, re) {
    836                 if(re && re.test(ua)) {
    837                     block = true;
    838                     return false; // exit $.each.
    839                 }
    840             });
    841             return block;
    842         },
    843         _restrictNativeVideoControls: function() {
    844             // Fallback to noFullScreen when nativeVideoControls is true and audio media is being used. Affects when both media types are used.
    845             if(this.require.audio) {
    846                 if(this.status.nativeVideoControls) {
    847                     this.status.nativeVideoControls = false;
    848                     this.status.noFullScreen = true;
    849                 }
    850             }
    851         },
    852         _updateNativeVideoControls: function() {
    853             if(this.html.video.available && this.html.used) {
    854                 // Turn the HTML Video controls on/off
    855                 this.htmlElement.video.controls = this.status.nativeVideoControls;
    856                 // Show/hide the jPlayer GUI.
    857                 this._updateAutohide();
    858                 // For when option changed. The poster image is not updated, as it is dealt with in setMedia(). Acceptable degradation since seriously doubt these options will change on the fly. Can again review later.
    859                 if(this.status.nativeVideoControls && this.require.video) {
    860                     this.internal.poster.jq.hide();
    861                     this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
    862                 } else if(this.status.waitForPlay && this.status.video) {
    863                     this.internal.poster.jq.show();
    864                     this.internal.video.jq.css({'width': '0px', 'height': '0px'});
    865                 }
    866             }
    867         },
    868         _addHtmlEventListeners: function(mediaElement, entity) {
    869             var self = this;
    870             mediaElement.preload = this.options.preload;
    871             mediaElement.muted = this.options.muted;
    872             mediaElement.volume = this.options.volume;
    873 
    874             // Create the event listeners
    875             // Only want the active entity to affect jPlayer and bubble events.
    876             // Using entity.gate so that object is referenced and gate property always current
    877            
    878             mediaElement.addEventListener("progress", function() {
    879                 if(entity.gate) {
    880                     self._getHtmlStatus(mediaElement);
    881                     self._updateInterface();
    882                     self._trigger($.jPlayer.event.progress);
    883                 }
    884             }, false);
    885             mediaElement.addEventListener("timeupdate", function() {
    886                 if(entity.gate) {
    887                     self._getHtmlStatus(mediaElement);
    888                     self._updateInterface();
    889                     self._trigger($.jPlayer.event.timeupdate);
    890                 }
    891             }, false);
    892             mediaElement.addEventListener("durationchange", function() {
    893                 if(entity.gate) {
    894                     self.status.duration = this.duration;
    895                     self._getHtmlStatus(mediaElement);
    896                     self._updateInterface();
    897                     self._trigger($.jPlayer.event.durationchange);
    898                 }
    899             }, false);
    900             mediaElement.addEventListener("play", function() {
    901                 if(entity.gate) {
    902                     self._updateButtons(true);
    903                     self._html_checkWaitForPlay(); // So the native controls update this variable and puts the hidden interface in the correct state. Affects toggling native controls.
    904                     self._trigger($.jPlayer.event.play);
    905                 }
    906             }, false);
    907             mediaElement.addEventListener("playing", function() {
    908                 if(entity.gate) {
    909                     self._updateButtons(true);
    910                     self._seeked();
    911                     self._trigger($.jPlayer.event.playing);
    912                 }
    913             }, false);
    914             mediaElement.addEventListener("pause", function() {
    915                 if(entity.gate) {
    916                     self._updateButtons(false);
    917                     self._trigger($.jPlayer.event.pause);
    918                 }
    919             }, false);
    920             mediaElement.addEventListener("waiting", function() {
    921                 if(entity.gate) {
    922                     self._seeking();
    923                     self._trigger($.jPlayer.event.waiting);
    924                 }
    925             }, false);
    926             mediaElement.addEventListener("seeking", function() {
    927                 if(entity.gate) {
    928                     self._seeking();
    929                     self._trigger($.jPlayer.event.seeking);
    930                 }
    931             }, false);
    932             mediaElement.addEventListener("seeked", function() {
    933                 if(entity.gate) {
    934                     self._seeked();
    935                     self._trigger($.jPlayer.event.seeked);
    936                 }
    937             }, false);
    938             mediaElement.addEventListener("volumechange", function() {
    939                 if(entity.gate) {
    940                     // Read the values back from the element as the Blackberry PlayBook shares the volume with the physical buttons master volume control.
    941                     // However, when tested 6th July 2011, those buttons do not generate an event. The physical play/pause button does though.
    942                     self.options.volume = mediaElement.volume;
    943                     self.options.muted = mediaElement.muted;
    944                     self._updateMute();
    945                     self._updateVolume();
    946                     self._trigger($.jPlayer.event.volumechange);
    947                 }
    948             }, false);
    949             mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture.
    950                 if(entity.gate) {
    951                     self._seeked();
    952                     self._trigger($.jPlayer.event.suspend);
    953                 }
    954             }, false);
    955             mediaElement.addEventListener("ended", function() {
    956                 if(entity.gate) {
    957                     // Order of the next few commands are important. Change the time and then pause.
    958                     // Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored.
    959                     if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo.
    960                         self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.)
    961                     }
    962                     self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback.
    963                     self._updateButtons(false);
    964                     self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full.
    965                     self._updateInterface();
    966                     self._trigger($.jPlayer.event.ended);
    967                 }
    968             }, false);
    969             mediaElement.addEventListener("error", function() {
    970                 if(entity.gate) {
    971                     self._updateButtons(false);
    972                     self._seeked();
    973                     if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event.
    974                         clearTimeout(self.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution.
    975                         self.status.waitForLoad = true; // Allows the load operation to try again.
    976                         self.status.waitForPlay = true; // Reset since a play was captured.
    977                         if(self.status.video && !self.status.nativeVideoControls) {
    978                             self.internal.video.jq.css({'width':'0px', 'height':'0px'});
    979                         }
    980                         if(self._validString(self.status.media.poster) && !self.status.nativeVideoControls) {
    981                             self.internal.poster.jq.show();
    982                         }
    983                         if(self.css.jq.videoPlay.length) {
    984                             self.css.jq.videoPlay.show();
    985                         }
    986                         self._error( {
    987                             type: $.jPlayer.error.URL,
    988                             context: self.status.src, // this.src shows absolute urls. Want context to show the url given.
    989                             message: $.jPlayer.errorMsg.URL,
    990                             hint: $.jPlayer.errorHint.URL
    991                         });
    992                     }
    993                 }
    994             }, false);
    995             // Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer.
    996             $.each($.jPlayer.htmlEvent, function(i, eventType) {
    997                 mediaElement.addEventListener(this, function() {
    998                     if(entity.gate) {
    999                         self._trigger($.jPlayer.event[eventType]);
    1000                     }
    1001                 }, false);
    1002             });
    1003         },
    1004         _getHtmlStatus: function(media, override) {
    1005             var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0;
    1006 
    1007             if(media.duration) { // Fixes the duration bug in iOS, where the durationchange event occurs when media.duration is not always correct.
    1008                 this.status.duration = media.duration;
    1009             }
    1010             ct = media.currentTime;
    1011             cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0;
    1012             if((typeof media.seekable === "object") && (media.seekable.length > 0)) {
    1013                 sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100;
    1014                 cpr = 100 * media.currentTime / media.seekable.end(media.seekable.length-1);
    1015             } else {
    1016                 sp = 100;
    1017                 cpr = cpa;
    1018             }
    1019            
    1020             if(override) {
    1021                 ct = 0;
    1022                 cpr = 0;
    1023                 cpa = 0;
    1024             }
    1025 
    1026             this.status.seekPercent = sp;
    1027             this.status.currentPercentRelative = cpr;
    1028             this.status.currentPercentAbsolute = cpa;
    1029             this.status.currentTime = ct;
    1030 
    1031             this.status.readyState = media.readyState;
    1032             this.status.networkState = media.networkState;
    1033             this.status.playbackRate = media.playbackRate;
    1034             this.status.ended = media.ended;
    1035         },
    1036         _resetStatus: function() {
    1037             this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset.
    1038         },
    1039         _trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType
    1040             var event = $.Event(eventType);
    1041             event.jPlayer = {};
    1042             event.jPlayer.version = $.extend({}, this.version);
    1043             event.jPlayer.options = $.extend(true, {}, this.options); // Deep copy
    1044             event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy
    1045             event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy
    1046             event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy
    1047             if(error) {
    1048                 event.jPlayer.error = $.extend({}, error);
    1049             }
    1050             if(warning) {
    1051                 event.jPlayer.warning = $.extend({}, warning);
    1052             }
    1053             this.element.trigger(event);
    1054         },
    1055         jPlayerFlashEvent: function(eventType, status) { // Called from Flash
    1056             if(eventType === $.jPlayer.event.ready) {
    1057                 if(!this.internal.ready) {
    1058                     this.internal.ready = true;
    1059                     this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Once Flash generates the ready event, minimise to zero as it is not affected by wmode anymore.
    1060 
    1061                     this.version.flash = status.version;
    1062                     if(this.version.needFlash !== this.version.flash) {
    1063                         this._error( {
    1064                             type: $.jPlayer.error.VERSION,
    1065                             context: this.version.flash,
    1066                             message: $.jPlayer.errorMsg.VERSION + this.version.flash,
    1067                             hint: $.jPlayer.errorHint.VERSION
    1068                         });
    1069                     }
    1070                     this._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option.
    1071                     this._trigger(eventType);
    1072                 } else {
    1073                     // This condition occurs if the Flash is hidden and then shown again.
    1074                     // Firefox also reloads the Flash if the CSS position changes. position:fixed is used for full screen.
    1075 
    1076                     // Only do this if the Flash is the solution being used at the moment. Affects Media players where both solution may be being used.
    1077                     if(this.flash.gate) {
    1078 
    1079                         // Send the current status to the Flash now that it is ready (available) again.
    1080                         if(this.status.srcSet) {
    1081 
    1082                             // Need to read original status before issuing the setMedia command.
    1083                             var currentTime = this.status.currentTime,
    1084                                 paused = this.status.paused;
    1085 
    1086                             this.setMedia(this.status.media);
    1087                             if(currentTime > 0) {
    1088                                 if(paused) {
    1089                                     this.pause(currentTime);
    1090                                 } else {
    1091                                     this.play(currentTime);
    1092                                 }
    1093                             }
    1094                         }
    1095                         this._trigger($.jPlayer.event.flashreset);
    1096                     }
    1097                 }
    1098             }
    1099             if(this.flash.gate) {
    1100                 switch(eventType) {
    1101                     case $.jPlayer.event.progress:
    1102                         this._getFlashStatus(status);
    1103                         this._updateInterface();
    1104                         this._trigger(eventType);
    1105                         break;
    1106                     case $.jPlayer.event.timeupdate:
    1107                         this._getFlashStatus(status);
    1108                         this._updateInterface();
    1109                         this._trigger(eventType);
    1110                         break;
    1111                     case $.jPlayer.event.play:
    1112                         this._seeked();
    1113                         this._updateButtons(true);
    1114                         this._trigger(eventType);
    1115                         break;
    1116                     case $.jPlayer.event.pause:
    1117                         this._updateButtons(false);
    1118                         this._trigger(eventType);
    1119                         break;
    1120                     case $.jPlayer.event.ended:
    1121                         this._updateButtons(false);
    1122                         this._trigger(eventType);
    1123                         break;
    1124                     case $.jPlayer.event.click:
    1125                         this._trigger(eventType); // This could be dealt with by the default
    1126                         break;
    1127                     case $.jPlayer.event.error:
    1128                         this.status.waitForLoad = true; // Allows the load operation to try again.
    1129                         this.status.waitForPlay = true; // Reset since a play was captured.
    1130                         if(this.status.video) {
    1131                             this.internal.flash.jq.css({'width':'0px', 'height':'0px'});
    1132                         }
    1133                         if(this._validString(this.status.media.poster)) {
    1134                             this.internal.poster.jq.show();
    1135                         }
    1136                         if(this.css.jq.videoPlay.length && this.status.video) {
    1137                             this.css.jq.videoPlay.show();
    1138                         }
    1139                         if(this.status.video) { // Set up for another try. Execute before error event.
    1140                             this._flash_setVideo(this.status.media);
    1141                         } else {
    1142                             this._flash_setAudio(this.status.media);
    1143                         }
    1144                         this._updateButtons(false);
    1145                         this._error( {
    1146                             type: $.jPlayer.error.URL,
    1147                             context:status.src,
    1148                             message: $.jPlayer.errorMsg.URL,
    1149                             hint: $.jPlayer.errorHint.URL
    1150                         });
    1151                         break;
    1152                     case $.jPlayer.event.seeking:
    1153                         this._seeking();
    1154                         this._trigger(eventType);
    1155                         break;
    1156                     case $.jPlayer.event.seeked:
    1157                         this._seeked();
    1158                         this._trigger(eventType);
    1159                         break;
    1160                     case $.jPlayer.event.ready:
    1161                         // The ready event is handled outside the switch statement.
    1162                         // Captured here otherwise 2 ready events would be generated if the ready event handler used setMedia.
    1163                         break;
    1164                     default:
    1165                         this._trigger(eventType);
    1166                 }
    1167             }
    1168             return false;
    1169         },
    1170         _getFlashStatus: function(status) {
    1171             this.status.seekPercent = status.seekPercent;
    1172             this.status.currentPercentRelative = status.currentPercentRelative;
    1173             this.status.currentPercentAbsolute = status.currentPercentAbsolute;
    1174             this.status.currentTime = status.currentTime;
    1175             this.status.duration = status.duration;
    1176 
    1177             // The Flash does not generate this information in this release
    1178             this.status.readyState = 4; // status.readyState;
    1179             this.status.networkState = 0; // status.networkState;
    1180             this.status.playbackRate = 1; // status.playbackRate;
    1181             this.status.ended = false; // status.ended;
    1182         },
    1183         _updateButtons: function(playing) {
    1184             if(playing !== undefined) {
    1185                 this.status.paused = !playing;
    1186                 if(this.css.jq.play.length && this.css.jq.pause.length) {
    1187                     if(playing) {
    1188                         this.css.jq.play.hide();
    1189                         this.css.jq.pause.show();
    1190                     } else {
    1191                         this.css.jq.play.show();
    1192                         this.css.jq.pause.hide();
    1193                     }
    1194                 }
    1195             }
    1196             if(this.css.jq.restoreScreen.length && this.css.jq.fullScreen.length) {
    1197                 if(this.status.noFullScreen) {
    1198                     this.css.jq.fullScreen.hide();
    1199                     this.css.jq.restoreScreen.hide();
    1200                 } else if(this.options.fullScreen) {
    1201                     this.css.jq.fullScreen.hide();
    1202                     this.css.jq.restoreScreen.show();
    1203                 } else {
    1204                     this.css.jq.fullScreen.show();
    1205                     this.css.jq.restoreScreen.hide();
    1206                 }
    1207             }
    1208             if(this.css.jq.repeat.length && this.css.jq.repeatOff.length) {
    1209                 if(this.options.loop) {
    1210                     this.css.jq.repeat.hide();
    1211                     this.css.jq.repeatOff.show();
    1212                 } else {
    1213                     this.css.jq.repeat.show();
    1214                     this.css.jq.repeatOff.hide();
    1215                 }
    1216             }
    1217         },
    1218         _updateInterface: function() {
    1219             if(this.css.jq.seekBar.length) {
    1220                 this.css.jq.seekBar.width(this.status.seekPercent+"%");
    1221             }
    1222             if(this.css.jq.playBar.length) {
    1223                 this.css.jq.playBar.width(this.status.currentPercentRelative+"%");
    1224             }
    1225             if(this.css.jq.currentTime.length) {
    1226                 this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime));
    1227             }
    1228             if(this.css.jq.duration.length) {
    1229                 this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration));
    1230             }
    1231         },
    1232         _seeking: function() {
    1233             if(this.css.jq.seekBar.length) {
    1234                 this.css.jq.seekBar.addClass("jp-seeking-bg");
    1235             }
    1236         },
    1237         _seeked: function() {
    1238             if(this.css.jq.seekBar.length) {
    1239                 this.css.jq.seekBar.removeClass("jp-seeking-bg");
    1240             }
    1241         },
    1242         _resetGate: function() {
    1243             this.html.audio.gate = false;
    1244             this.html.video.gate = false;
    1245             this.flash.gate = false;
    1246         },
    1247         _resetActive: function() {
    1248             this.html.active = false;
    1249             this.flash.active = false;
    1250         },
    1251         setMedia: function(media) {
    1252        
    1253             /*  media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats.
    1254              *  media.poster = String: Video poster URL.
    1255              *  media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file
    1256              *  media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file
    1257              *  media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often.
    1258              */
    1259 
    1260             var self = this,
    1261                 supported = false,
    1262                 posterChanged = this.status.media.poster !== media.poster; // Compare before reset. Important for OSX Safari as this.htmlElement.poster.src is absolute, even if original poster URL was relative.
    1263 
    1264             this._resetMedia();
    1265             this._resetGate();
    1266             this._resetActive();
    1267 
    1268             $.each(this.formats, function(formatPriority, format) {
    1269                 var isVideo = self.format[format].media === 'video';
    1270                 $.each(self.solutions, function(solutionPriority, solution) {
    1271                     if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format.
    1272                         var isHtml = solution === 'html';
    1273 
    1274                         if(isVideo) {
    1275                             if(isHtml) {
    1276                                 self.html.video.gate = true;
    1277                                 self._html_setVideo(media);
    1278                                 self.html.active = true;
    1279                             } else {
    1280                                 self.flash.gate = true;
    1281                                 self._flash_setVideo(media);
    1282                                 self.flash.active = true;
    1283                             }
    1284                             if(self.css.jq.videoPlay.length) {
    1285                                 self.css.jq.videoPlay.show();
    1286                             }
    1287                             self.status.video = true;
    1288                         } else {
    1289                             if(isHtml) {
    1290                                 self.html.audio.gate = true;
    1291                                 self._html_setAudio(media);
    1292                                 self.html.active = true;
    1293                             } else {
    1294                                 self.flash.gate = true;
    1295                                 self._flash_setAudio(media);
    1296                                 self.flash.active = true;
    1297                             }
    1298                             if(self.css.jq.videoPlay.length) {
    1299                                 self.css.jq.videoPlay.hide();
    1300                             }
    1301                             self.status.video = false;
    1302                         }
    1303                        
    1304                         supported = true;
    1305                         return false; // Exit $.each
    1306                     }
    1307                 });
    1308                 if(supported) {
    1309                     return false; // Exit $.each
    1310                 }
    1311             });
    1312 
    1313             if(supported) {
    1314                 if(!(this.status.nativeVideoControls && this.html.video.gate)) {
    1315                     // Set poster IMG if native video controls are not being used
    1316                     // Note: With IE the IMG onload event occurs immediately when cached.
    1317                     // Note: Poster hidden by default in _resetMedia()
    1318                     if(this._validString(media.poster)) {
    1319                         if(posterChanged) { // Since some browsers do not generate img onload event.
    1320                             this.htmlElement.poster.src = media.poster;
    1321                         } else {
    1322                             this.internal.poster.jq.show();
    1323                         }
    1324                     }
    1325                 }
    1326                 this.status.srcSet = true;
    1327                 this.status.media = $.extend({}, media);
    1328                 this._updateButtons(false);
    1329                 this._updateInterface();
    1330             } else { // jPlayer cannot support any formats provided in this browser
    1331                 // Send an error event
    1332                 this._error( {
    1333                     type: $.jPlayer.error.NO_SUPPORT,
    1334                     context: "{supplied:'" + this.options.supplied + "'}",
    1335                     message: $.jPlayer.errorMsg.NO_SUPPORT,
    1336                     hint: $.jPlayer.errorHint.NO_SUPPORT
    1337                 });
    1338             }
    1339         },
    1340         _resetMedia: function() {
    1341             this._resetStatus();
    1342             this._updateButtons(false);
    1343             this._updateInterface();
    1344             this._seeked();
    1345             this.internal.poster.jq.hide();
    1346 
    1347             clearTimeout(this.internal.htmlDlyCmdId);
    1348 
    1349             if(this.html.active) {
    1350                 this._html_resetMedia();
    1351             } else if(this.flash.active) {
    1352                 this._flash_resetMedia();
    1353             }
    1354         },
    1355         clearMedia: function() {
    1356             this._resetMedia();
    1357 
    1358             if(this.html.active) {
    1359                 this._html_clearMedia();
    1360             } else if(this.flash.active) {
    1361                 this._flash_clearMedia();
    1362             }
    1363 
    1364             this._resetGate();
    1365             this._resetActive();
    1366         },
    1367         load: function() {
    1368             if(this.status.srcSet) {
    1369                 if(this.html.active) {
    1370                     this._html_load();
    1371                 } else if(this.flash.active) {
    1372                     this._flash_load();
    1373                 }
    1374             } else {
    1375                 this._urlNotSetError("load");
    1376             }
    1377         },
    1378         play: function(time) {
    1379             time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
    1380             if(this.status.srcSet) {
    1381                 if(this.html.active) {
    1382                     this._html_play(time);
    1383                 } else if(this.flash.active) {
    1384                     this._flash_play(time);
    1385                 }
    1386             } else {
    1387                 this._urlNotSetError("play");
    1388             }
    1389         },
    1390         videoPlay: function(e) { // Handles clicks on the play button over the video poster
    1391             this.play();
    1392         },
    1393         pause: function(time) {
    1394             time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
    1395             if(this.status.srcSet) {
    1396                 if(this.html.active) {
    1397                     this._html_pause(time);
    1398                 } else if(this.flash.active) {
    1399                     this._flash_pause(time);
    1400                 }
    1401             } else {
    1402                 this._urlNotSetError("pause");
    1403             }
    1404         },
    1405         pauseOthers: function() {
    1406             var self = this;
    1407             $.each(this.instances, function(i, element) {
    1408                 if(self.element !== element) { // Do not this instance.
    1409                     if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
    1410                         element.jPlayer("pause");
    1411                     }
    1412                 }
    1413             });
    1414         },
    1415         stop: function() {
    1416             if(this.status.srcSet) {
    1417                 if(this.html.active) {
    1418                     this._html_pause(0);
    1419                 } else if(this.flash.active) {
    1420                     this._flash_pause(0);
    1421                 }
    1422             } else {
    1423                 this._urlNotSetError("stop");
    1424             }
    1425         },
    1426         playHead: function(p) {
    1427             p = this._limitValue(p, 0, 100);
    1428             if(this.status.srcSet) {
    1429                 if(this.html.active) {
    1430                     this._html_playHead(p);
    1431                 } else if(this.flash.active) {
    1432                     this._flash_playHead(p);
    1433                 }
    1434             } else {
    1435                 this._urlNotSetError("playHead");
    1436             }
    1437         },
    1438         _muted: function(muted) {
    1439             this.options.muted = muted;
    1440             if(this.html.used) {
    1441                 this._html_mute(muted);
    1442             }
    1443             if(this.flash.used) {
    1444                 this._flash_mute(muted);
    1445             }
    1446 
    1447             // The HTML solution generates this event from the media element itself.
    1448             if(!this.html.video.gate && !this.html.audio.gate) {
    1449                 this._updateMute(muted);
    1450                 this._updateVolume(this.options.volume);
    1451                 this._trigger($.jPlayer.event.volumechange);
    1452             }
    1453         },
    1454         mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted).
    1455             mute = mute === undefined ? true : !!mute;
    1456             this._muted(mute);
    1457         },
    1458         unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted).
    1459             unmute = unmute === undefined ? true : !!unmute;
    1460             this._muted(!unmute);
    1461         },
    1462         _updateMute: function(mute) {
    1463             if(mute === undefined) {
    1464                 mute = this.options.muted;
    1465             }
    1466             if(this.css.jq.mute.length && this.css.jq.unmute.length) {
    1467                 if(this.status.noVolume) {
    1468                     this.css.jq.mute.hide();
    1469                     this.css.jq.unmute.hide();
    1470                 } else if(mute) {
    1471                     this.css.jq.mute.hide();
    1472                     this.css.jq.unmute.show();
    1473                 } else {
    1474                     this.css.jq.mute.show();
    1475                     this.css.jq.unmute.hide();
    1476                 }
    1477             }
    1478         },
    1479         volume: function(v) {
    1480             v = this._limitValue(v, 0, 1);
    1481             this.options.volume = v;
    1482 
    1483             if(this.html.used) {
    1484                 this._html_volume(v);
    1485             }
    1486             if(this.flash.used) {
    1487                 this._flash_volume(v);
    1488             }
    1489 
    1490             // The HTML solution generates this event from the media element itself.
    1491             if(!this.html.video.gate && !this.html.audio.gate) {
    1492                 this._updateVolume(v);
    1493                 this._trigger($.jPlayer.event.volumechange);
    1494             }
    1495         },
    1496         volumeBar: function(e) { // Handles clicks on the volumeBar
    1497             if(this.css.jq.volumeBar.length) {
    1498                 var offset = this.css.jq.volumeBar.offset(),
    1499                     x = e.pageX - offset.left,
    1500                     w = this.css.jq.volumeBar.width(),
    1501                     y = this.css.jq.volumeBar.height() - e.pageY + offset.top,
    1502                     h = this.css.jq.volumeBar.height();
    1503 
    1504                 if(this.options.verticalVolume) {
    1505                     this.volume(y/h);
    1506                 } else {
    1507                     this.volume(x/w);
    1508                 }
    1509             }
    1510             if(this.options.muted) {
    1511                 this._muted(false);
    1512             }
    1513         },
    1514         volumeBarValue: function(e) { // Handles clicks on the volumeBarValue
    1515             this.volumeBar(e);
    1516         },
    1517         _updateVolume: function(v) {
    1518             if(v === undefined) {
    1519                 v = this.options.volume;
    1520             }
    1521             v = this.options.muted ? 0 : v;
    1522 
    1523             if(this.status.noVolume) {
    1524                 if(this.css.jq.volumeBar.length) {
    1525                     this.css.jq.volumeBar.hide();
    1526                 }
    1527                 if(this.css.jq.volumeBarValue.length) {
    1528                     this.css.jq.volumeBarValue.hide();
    1529                 }
    1530                 if(this.css.jq.volumeMax.length) {
    1531                     this.css.jq.volumeMax.hide();
    1532                 }
    1533             } else {
    1534                 if(this.css.jq.volumeBar.length) {
    1535                     this.css.jq.volumeBar.show();
    1536                 }
    1537                 if(this.css.jq.volumeBarValue.length) {
    1538                     this.css.jq.volumeBarValue.show();
    1539                     this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((v*100)+"%");
    1540                 }
    1541                 if(this.css.jq.volumeMax.length) {
    1542                     this.css.jq.volumeMax.show();
    1543                 }
    1544             }
    1545         },
    1546         volumeMax: function() { // Handles clicks on the volume max
    1547             this.volume(1);
    1548             if(this.options.muted) {
    1549                 this._muted(false);
    1550             }
    1551         },
    1552         _cssSelectorAncestor: function(ancestor) {
    1553             var self = this;
    1554             this.options.cssSelectorAncestor = ancestor;
    1555             this._removeUiClass();
    1556             this.ancestorJq = ancestor ? $(ancestor) : []; // Would use $() instead of [], but it is only 1.4+
    1557             if(ancestor && this.ancestorJq.length !== 1) { // So empty strings do not generate the warning.
    1558                 this._warning( {
    1559                     type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
    1560                     context: ancestor,
    1561                     message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.ancestorJq.length + " found for cssSelectorAncestor.",
    1562                     hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
    1563                 });
    1564             }
    1565             this._addUiClass();
    1566             $.each(this.options.cssSelector, function(fn, cssSel) {
    1567                 self._cssSelector(fn, cssSel);
    1568             });
    1569         },
    1570         _cssSelector: function(fn, cssSel) {
    1571             var self = this;
    1572             if(typeof cssSel === 'string') {
    1573                 if($.jPlayer.prototype.options.cssSelector[fn]) {
    1574                     if(this.css.jq[fn] && this.css.jq[fn].length) {
    1575                         this.css.jq[fn].unbind(".jPlayer");
    1576                     }
    1577                     this.options.cssSelector[fn] = cssSel;
    1578                     this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel;
    1579 
    1580                     if(cssSel) { // Checks for empty string
    1581                         this.css.jq[fn] = $(this.css.cs[fn]);
    1582                     } else {
    1583                         this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set.
    1584                     }
    1585 
    1586                     if(this.css.jq[fn].length) {
    1587                         var handler = function(e) {
    1588                             self[fn](e);
    1589                             $(this).blur();
    1590                             return false;
    1591                         };
    1592                         this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace
    1593                     }
    1594 
    1595                     if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one.
    1596                         this._warning( {
    1597                             type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
    1598                             context: this.css.cs[fn],
    1599                             message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.",
    1600                             hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
    1601                         });
    1602                     }
    1603                 } else {
    1604                     this._warning( {
    1605                         type: $.jPlayer.warning.CSS_SELECTOR_METHOD,
    1606                         context: fn,
    1607                         message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD,
    1608                         hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD
    1609                     });
    1610                 }
    1611             } else {
    1612                 this._warning( {
    1613                     type: $.jPlayer.warning.CSS_SELECTOR_STRING,
    1614                     context: cssSel,
    1615                     message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING,
    1616                     hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING
    1617                 });
    1618             }
    1619         },
    1620         seekBar: function(e) { // Handles clicks on the seekBar
    1621             if(this.css.jq.seekBar) {
    1622                 var offset = this.css.jq.seekBar.offset();
    1623                 var x = e.pageX - offset.left;
    1624                 var w = this.css.jq.seekBar.width();
    1625                 var p = 100*x/w;
    1626                 this.playHead(p);
    1627             }
    1628         },
    1629         playBar: function(e) { // Handles clicks on the playBar
    1630             this.seekBar(e);
    1631         },
    1632         repeat: function() { // Handle clicks on the repeat button
    1633             this._loop(true);
    1634         },
    1635         repeatOff: function() { // Handle clicks on the repeatOff button
    1636             this._loop(false);
    1637         },
    1638         _loop: function(loop) {
    1639             if(this.options.loop !== loop) {
    1640                 this.options.loop = loop;
    1641                 this._updateButtons();
    1642                 this._trigger($.jPlayer.event.repeat);
    1643             }
    1644         },
    1645 
    1646         // Plan to review the cssSelector method to cope with missing associated functions accordingly.
    1647 
    1648         currentTime: function(e) { // Handles clicks on the text
    1649             // Added to avoid errors using cssSelector system for the text
    1650         },
    1651         duration: function(e) { // Handles clicks on the text
    1652             // Added to avoid errors using cssSelector system for the text
    1653         },
    1654         gui: function(e) { // Handles clicks on the gui
    1655             // Added to avoid errors using cssSelector system for the gui
    1656         },
    1657         noSolution: function(e) { // Handles clicks on the error message
    1658             // Added to avoid errors using cssSelector system for no-solution
    1659         },
    1660 
    1661         // Options code adapted from ui.widget.js (1.8.7).  Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1.
    1662         option: function(key, value) {
    1663             var options = key;
    1664 
    1665              // Enables use: options().  Returns a copy of options object
    1666             if ( arguments.length === 0 ) {
    1667                 return $.extend( true, {}, this.options );
    1668             }
    1669 
    1670             if(typeof key === "string") {
    1671                 var keys = key.split(".");
    1672 
    1673                  // Enables use: options("someOption")  Returns a copy of the option. Supports dot notation.
    1674                 if(value === undefined) {
    1675 
    1676                     var opt = $.extend(true, {}, this.options);
    1677                     for(var i = 0; i < keys.length; i++) {
    1678                         if(opt[keys[i]] !== undefined) {
    1679                             opt = opt[keys[i]];
    1680                         } else {
    1681                             this._warning( {
    1682                                 type: $.jPlayer.warning.OPTION_KEY,
    1683                                 context: key,
    1684                                 message: $.jPlayer.warningMsg.OPTION_KEY,
    1685                                 hint: $.jPlayer.warningHint.OPTION_KEY
    1686                             });
    1687                             return undefined;
    1688                         }
    1689                     }
    1690                     return opt;
    1691                 }
    1692 
    1693                  // Enables use: options("someOptionObject", someObject}).  Creates: {someOptionObject:someObject}
    1694                  // Enables use: options("someOption", someValue).  Creates: {someOption:someValue}
    1695                  // Enables use: options("someOptionObject.someOption", someValue).  Creates: {someOptionObject:{someOption:someValue}}
    1696 
    1697                 options = {};
    1698                 var opts = options;
    1699 
    1700                 for(var j = 0; j < keys.length; j++) {
    1701                     if(j < keys.length - 1) {
    1702                         opts[keys[j]] = {};
    1703                         opts = opts[keys[j]];
    1704                     } else {
    1705                         opts[keys[j]] = value;
    1706                     }
    1707                 }
    1708             }
    1709 
    1710              // Otherwise enables use: options(optionObject).  Uses original object (the key)
    1711 
    1712             this._setOptions(options);
    1713 
    1714             return this;
    1715         },
    1716         _setOptions: function(options) {
    1717             var self = this;
    1718             $.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth.
    1719                 self._setOption(key, value);
    1720             });
    1721 
    1722             return this;
    1723         },
    1724         _setOption: function(key, value) {
    1725             var self = this;
    1726 
    1727             // The ability to set options is limited at this time.
    1728 
    1729             switch(key) {
    1730                 case "volume" :
    1731                     this.volume(value);
    1732                     break;
    1733                 case "muted" :
    1734                     this._muted(value);
    1735                     break;
    1736                 case "cssSelectorAncestor" :
    1737                     this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor.
    1738                     break;
    1739                 case "cssSelector" :
    1740                     $.each(value, function(fn, cssSel) {
    1741                         self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks.
    1742                     });
    1743                     break;
    1744                 case "fullScreen" :
    1745                     if(this.options[key] !== value) { // if changed
    1746                         this._removeUiClass();
    1747                         this.options[key] = value;
    1748                         this._refreshSize();
    1749                     }
    1750                     break;
    1751                 case "size" :
    1752                     if(!this.options.fullScreen && this.options[key].cssClass !== value.cssClass) {
    1753                         this._removeUiClass();
    1754                     }
    1755                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1756                     this._refreshSize();
    1757                     break;
    1758                 case "sizeFull" :
    1759                     if(this.options.fullScreen && this.options[key].cssClass !== value.cssClass) {
    1760                         this._removeUiClass();
    1761                     }
    1762                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1763                     this._refreshSize();
    1764                     break;
    1765                 case "autohide" :
    1766                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1767                     this._updateAutohide();
    1768                     break;
    1769                 case "loop" :
    1770                     this._loop(value);
    1771                     break;
    1772                 case "nativeVideoControls" :
    1773                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1774                     this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls);
    1775                     this._restrictNativeVideoControls();
    1776                     this._updateNativeVideoControls();
    1777                     break;
    1778                 case "noFullScreen" :
    1779                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1780                     this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); // Need to check again as noFullScreen can depend on this flag and the restrict() can override it.
    1781                     this.status.noFullScreen = this._uaBlocklist(this.options.noFullScreen);
    1782                     this._restrictNativeVideoControls();
    1783                     this._updateButtons();
    1784                     break;
    1785                 case "noVolume" :
    1786                     this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed.
    1787                     this.status.noVolume = this._uaBlocklist(this.options.noVolume);
    1788                     this._updateVolume();
    1789                     this._updateMute();
    1790                     break;
    1791                 case "emulateHtml" :
    1792                     if(this.options[key] !== value) { // To avoid multiple event handlers being created, if true already.
    1793                         this.options[key] = value;
    1794                         if(value) {
    1795                             this._emulateHtmlBridge();
    1796                         } else {
    1797                             this._destroyHtmlBridge();
    1798                         }
    1799                     }
    1800                     break;
    1801             }
    1802 
    1803             return this;
    1804         },
    1805         // End of: (Options code adapted from ui.widget.js)
    1806 
    1807         _refreshSize: function() {
    1808             this._setSize(); // update status and jPlayer element size
    1809             this._addUiClass(); // update the ui class
    1810             this._updateSize(); // update internal sizes
    1811             this._updateButtons();
    1812             this._updateAutohide();
    1813             this._trigger($.jPlayer.event.resize);
    1814         },
    1815         _setSize: function() {
    1816             // Determine the current size from the options
    1817             if(this.options.fullScreen) {
    1818                 this.status.width = this.options.sizeFull.width;
    1819                 this.status.height = this.options.sizeFull.height;
    1820                 this.status.cssClass = this.options.sizeFull.cssClass;
    1821             } else {
    1822                 this.status.width = this.options.size.width;
    1823                 this.status.height = this.options.size.height;
    1824                 this.status.cssClass = this.options.size.cssClass;
    1825             }
    1826 
    1827             // Set the size of the jPlayer area.
    1828             this.element.css({'width': this.status.width, 'height': this.status.height});
    1829         },
    1830         _addUiClass: function() {
    1831             if(this.ancestorJq.length) {
    1832                 this.ancestorJq.addClass(this.status.cssClass);
    1833             }
    1834         },
    1835         _removeUiClass: function() {
    1836             if(this.ancestorJq.length) {
    1837                 this.ancestorJq.removeClass(this.status.cssClass);
    1838             }
    1839         },
    1840         _updateSize: function() {
    1841             // The poster uses show/hide so can simply resize it.
    1842             this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height});
    1843 
    1844             // Video html or flash resized if necessary at this time, or if native video controls being used.
    1845             if(!this.status.waitForPlay && this.html.active && this.status.video || this.html.video.available && this.html.used && this.status.nativeVideoControls) {
    1846                 this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
    1847             }
    1848             else if(!this.status.waitForPlay && this.flash.active && this.status.video) {
    1849                 this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height});
    1850             }
    1851         },
    1852         _updateAutohide: function() {
    1853             var self = this,
    1854                 event = "mousemove.jPlayer",
    1855                 namespace = ".jPlayerAutohide",
    1856                 eventType = event + namespace,
    1857                 handler = function() {
    1858                     self.css.jq.gui.fadeIn(self.options.autohide.fadeIn, function() {
    1859                         clearTimeout(self.internal.autohideId);
    1860                         self.internal.autohideId = setTimeout( function() {
    1861                             self.css.jq.gui.fadeOut(self.options.autohide.fadeOut);
    1862                         }, self.options.autohide.hold);
    1863                     });
    1864                 };
    1865 
    1866             if(this.css.jq.gui.length) {
    1867 
    1868                 // End animations first so that its callback is executed now.
    1869                 // Otherwise an in progress fadeIn animation still has the callback to fadeOut again.
    1870                 this.css.jq.gui.stop(true, true);
    1871 
    1872                 // Removes the fadeOut operation from the fadeIn callback.
    1873                 clearTimeout(this.internal.autohideId);
    1874 
    1875                 this.element.unbind(namespace);
    1876                 this.css.jq.gui.unbind(namespace);
    1877 
    1878                 if(!this.status.nativeVideoControls) {
    1879                     if(this.options.fullScreen && this.options.autohide.full || !this.options.fullScreen && this.options.autohide.restored) {
    1880                         this.element.bind(eventType, handler);
    1881                         this.css.jq.gui.bind(eventType, handler);
    1882                         this.css.jq.gui.hide();
    1883                     } else {
    1884                         this.css.jq.gui.show();
    1885                     }
    1886                 } else {
    1887                     this.css.jq.gui.hide();
    1888                 }
    1889             }
    1890         },
    1891         fullScreen: function() {
    1892             this._setOption("fullScreen", true);
    1893         },
    1894         restoreScreen: function() {
    1895             this._setOption("fullScreen", false);
    1896         },
    1897         _html_initMedia: function() {
    1898             this.htmlElement.media.src = this.status.src;
    1899 
    1900             if(this.options.preload !== 'none') {
    1901                 this._html_load(); // See function for comments
    1902             }
    1903             this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution.
    1904         },
    1905         _html_setAudio: function(media) {
    1906             var self = this;
    1907             // Always finds a format due to checks in setMedia()
    1908             $.each(this.formats, function(priority, format) {
    1909                 if(self.html.support[format] && media[format]) {
    1910                     self.status.src = media[format];
    1911                     self.status.format[format] = true;
    1912                     self.status.formatType = format;
    1913                     return false;
    1914                 }
    1915             });
    1916             this.htmlElement.media = this.htmlElement.audio;
    1917             this._html_initMedia();
    1918         },
    1919         _html_setVideo: function(media) {
    1920             var self = this;
    1921             // Always finds a format due to checks in setMedia()
    1922             $.each(this.formats, function(priority, format) {
    1923                 if(self.html.support[format] && media[format]) {
    1924                     self.status.src = media[format];
    1925                     self.status.format[format] = true;
    1926                     self.status.formatType = format;
    1927                     return false;
    1928                 }
    1929             });
    1930             if(this.status.nativeVideoControls) {
    1931                 this.htmlElement.video.poster = this._validString(media.poster) ? media.poster : "";
    1932             }
    1933             this.htmlElement.media = this.htmlElement.video;
    1934             this._html_initMedia();
    1935         },
    1936         _html_resetMedia: function() {
    1937             if(this.htmlElement.media) {
    1938                 if(this.htmlElement.media.id === this.internal.video.id && !this.status.nativeVideoControls) {
    1939                     this.internal.video.jq.css({'width':'0px', 'height':'0px'});
    1940                 }
    1941                 this.htmlElement.media.pause();
    1942             }
    1943         },
    1944         _html_clearMedia: function() {
    1945             if(this.htmlElement.media) {
    1946                 this.htmlElement.media.src = "";
    1947                 this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress.
    1948             }
    1949         },
    1950         _html_load: function() {
    1951             // This function remains to allow the early HTML5 browsers to work, such as Firefox 3.6
    1952             // A change in the W3C spec for the media.load() command means that this is no longer necessary.
    1953             // This command should be removed and actually causes minor undesirable effects on some browsers. Such as loading the whole file and not only the metadata.
    1954             if(this.status.waitForLoad) {
    1955                 this.status.waitForLoad = false;
    1956                 this.htmlElement.media.load();
    1957             }
    1958             clearTimeout(this.internal.htmlDlyCmdId);
    1959         },
    1960         _html_play: function(time) {
    1961             var self = this;
    1962             this._html_load(); // Loads if required and clears any delayed commands.
    1963 
    1964             this.htmlElement.media.play(); // Before currentTime attempt otherwise Firefox 4 Beta never loads.
    1965 
    1966             if(!isNaN(time)) {
    1967                 try {
    1968                     this.htmlElement.media.currentTime = time;
    1969                 } catch(err) {
    1970                     this.internal.htmlDlyCmdId = setTimeout(function() {
    1971                         self.play(time);
    1972                     }, 100);
    1973                     return; // Cancel execution and wait for the delayed command.
    1974                 }
    1975             }
    1976             this._html_checkWaitForPlay();
    1977         },
    1978         _html_pause: function(time) {
    1979             var self = this;
    1980            
    1981             if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
    1982                 this._html_load(); // Loads if required and clears any delayed commands.
    1983             } else {
    1984                 clearTimeout(this.internal.htmlDlyCmdId);
    1985             }
    1986 
    1987             // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime.
    1988             this.htmlElement.media.pause();
    1989 
    1990             if(!isNaN(time)) {
    1991                 try {
    1992                     this.htmlElement.media.currentTime = time;
    1993                 } catch(err) {
    1994                     this.internal.htmlDlyCmdId = setTimeout(function() {
    1995                         self.pause(time);
    1996                     }, 100);
    1997                     return; // Cancel execution and wait for the delayed command.
    1998                 }
    1999             }
    2000             if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
    2001                 this._html_checkWaitForPlay();
    2002             }
    2003         },
    2004         _html_playHead: function(percent) {
    2005             var self = this;
    2006             this._html_load(); // Loads if required and clears any delayed commands.
    2007             try {
    2008                 if((typeof this.htmlElement.media.seekable === "object") && (this.htmlElement.media.seekable.length > 0)) {
    2009                     this.htmlElement.media.currentTime = percent * this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1) / 100;
    2010                 } else if(this.htmlElement.media.duration > 0 && !isNaN(this.htmlElement.media.duration)) {
    2011                     this.htmlElement.media.currentTime = percent * this.htmlElement.media.duration / 100;
    2012                 } else {
    2013                     throw "e";
    2014                 }
    2015             } catch(err) {
    2016                 this.internal.htmlDlyCmdId = setTimeout(function() {
    2017                     self.playHead(percent);
    2018                 }, 100);
    2019                 return; // Cancel execution and wait for the delayed command.
    2020             }
    2021             if(!this.status.waitForLoad) {
    2022                 this._html_checkWaitForPlay();
    2023             }
    2024         },
    2025         _html_checkWaitForPlay: function() {
    2026             if(this.status.waitForPlay) {
    2027                 this.status.waitForPlay = false;
    2028                 if(this.css.jq.videoPlay.length) {
    2029                     this.css.jq.videoPlay.hide();
    2030                 }
    2031                 if(this.status.video) {
    2032                     this.internal.poster.jq.hide();
    2033                     this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
    2034                 }
    2035             }
    2036         },
    2037         _html_volume: function(v) {
    2038             if(this.html.audio.available) {
    2039                 this.htmlElement.audio.volume = v;
    2040             }
    2041             if(this.html.video.available) {
    2042                 this.htmlElement.video.volume = v;
    2043             }
    2044         },
    2045         _html_mute: function(m) {
    2046             if(this.html.audio.available) {
    2047                 this.htmlElement.audio.muted = m;
    2048             }
    2049             if(this.html.video.available) {
    2050                 this.htmlElement.video.muted = m;
    2051             }
    2052         },
    2053         _flash_setAudio: function(media) {
    2054             var self = this;
    2055             try {
    2056                 // Always finds a format due to checks in setMedia()
    2057                 $.each(this.formats, function(priority, format) {
    2058                     if(self.flash.support[format] && media[format]) {
    2059                         switch (format) {
    2060                             case "m4a" :
    2061                             case "fla" :
    2062                                 self._getMovie().fl_setAudio_m4a(media[format]);
    2063                                 break;
    2064                             case "mp3" :
    2065                                 self._getMovie().fl_setAudio_mp3(media[format]);
    2066                                 break;
    2067                         }
    2068                         self.status.src = media[format];
    2069                         self.status.format[format] = true;
    2070                         self.status.formatType = format;
    2071                         return false;
    2072                     }
    2073                 });
    2074 
    2075                 if(this.options.preload === 'auto') {
    2076                     this._flash_load();
    2077                     this.status.waitForLoad = false;
    2078                 }
    2079             } catch(err) { this._flashError(err); }
    2080         },
    2081         _flash_setVideo: function(media) {
    2082             var self = this;
    2083             try {
    2084                 // Always finds a format due to checks in setMedia()
    2085                 $.each(this.formats, function(priority, format) {
    2086                     if(self.flash.support[format] && media[format]) {
    2087                         switch (format) {
    2088                             case "m4v" :
    2089                             case "flv" :
    2090                                 self._getMovie().fl_setVideo_m4v(media[format]);
    2091                                 break;
    2092                         }
    2093                         self.status.src = media[format];
    2094                         self.status.format[format] = true;
    2095                         self.status.formatType = format;
    2096                         return false;
    2097                     }
    2098                 });
    2099 
    2100                 if(this.options.preload === 'auto') {
    2101                     this._flash_load();
    2102                     this.status.waitForLoad = false;
    2103                 }
    2104             } catch(err) { this._flashError(err); }
    2105         },
    2106         _flash_resetMedia: function() {
    2107             this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE.
    2108             this._flash_pause(NaN);
    2109         },
    2110         _flash_clearMedia: function() {
    2111             try {
    2112                 this._getMovie().fl_clearMedia();
    2113             } catch(err) { this._flashError(err); }
    2114         },
    2115         _flash_load: function() {
    2116             try {
    2117                 this._getMovie().fl_load();
    2118             } catch(err) { this._flashError(err); }
    2119             this.status.waitForLoad = false;
    2120         },
    2121         _flash_play: function(time) {
    2122             try {
    2123                 this._getMovie().fl_play(time);
    2124             } catch(err) { this._flashError(err); }
    2125             this.status.waitForLoad = false;
    2126             this._flash_checkWaitForPlay();
    2127         },
    2128         _flash_pause: function(time) {
    2129             try {
    2130                 this._getMovie().fl_pause(time);
    2131             } catch(err) { this._flashError(err); }
    2132             if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
    2133                 this.status.waitForLoad = false;
    2134                 this._flash_checkWaitForPlay();
    2135             }
    2136         },
    2137         _flash_playHead: function(p) {
    2138             try {
    2139                 this._getMovie().fl_play_head(p);
    2140             } catch(err) { this._flashError(err); }
    2141             if(!this.status.waitForLoad) {
    2142                 this._flash_checkWaitForPlay();
    2143             }
    2144         },
    2145         _flash_checkWaitForPlay: function() {
    2146             if(this.status.waitForPlay) {
    2147                 this.status.waitForPlay = false;
    2148                 if(this.css.jq.videoPlay.length) {
    2149                     this.css.jq.videoPlay.hide();
    2150                 }
    2151                 if(this.status.video) {
    2152                     this.internal.poster.jq.hide();
    2153                     this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height});
    2154                 }
    2155             }
    2156         },
    2157         _flash_volume: function(v) {
    2158             try {
    2159                 this._getMovie().fl_volume(v);
    2160             } catch(err) { this._flashError(err); }
    2161         },
    2162         _flash_mute: function(m) {
    2163             try {
    2164                 this._getMovie().fl_mute(m);
    2165             } catch(err) { this._flashError(err); }
    2166         },
    2167         _getMovie: function() {
    2168             return document[this.internal.flash.id];
    2169         },
    2170         _checkForFlash: function (version) {
    2171             // Function checkForFlash adapted from FlashReplace by Robert Nyman
    2172             // http://code.google.com/p/flashreplace/
    2173             var flashIsInstalled = false;
    2174             var flash;
    2175             if(window.ActiveXObject){
    2176                 try{
    2177                     flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version));
    2178                     flashIsInstalled = true;
    2179                 }
    2180                 catch(e){
    2181                     // Throws an error if the version isn't available           
    2182                 }
    2183             }
    2184             else if(navigator.plugins && navigator.mimeTypes.length > 0){
    2185                 flash = navigator.plugins["Shockwave Flash"];
    2186                 if(flash){
    2187                     var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1");
    2188                     if(flashVersion >= version){
    2189                         flashIsInstalled = true;
    2190                     }
    2191                 }
    2192             }
    2193             return flashIsInstalled;
    2194         },
    2195         _validString: function(url) {
    2196             return (url && typeof url === "string"); // Empty strings return false
    2197         },
    2198         _limitValue: function(value, min, max) {
    2199             return (value < min) ? min : ((value > max) ? max : value);
    2200         },
    2201         _urlNotSetError: function(context) {
    2202             this._error( {
    2203                 type: $.jPlayer.error.URL_NOT_SET,
    2204                 context: context,
    2205                 message: $.jPlayer.errorMsg.URL_NOT_SET,
    2206                 hint: $.jPlayer.errorHint.URL_NOT_SET
    2207             });
    2208         },
    2209         _flashError: function(error) {
    2210             var errorType;
    2211             if(!this.internal.ready) {
    2212                 errorType = "FLASH";
    2213             } else {
    2214                 errorType = "FLASH_DISABLED";
    2215             }
    2216             this._error( {
    2217                 type: $.jPlayer.error[errorType],
    2218                 context: this.internal.flash.swf,
    2219                 message: $.jPlayer.errorMsg[errorType] + error.message,
    2220                 hint: $.jPlayer.errorHint[errorType]
    2221             });
    2222             // Allow the audio player to recover if display:none and then shown again, or with position:fixed on Firefox.
    2223             // This really only affects audio in a media player, as an audio player could easily move the jPlayer element away from such issues.
    2224             this.internal.flash.jq.css({'width':'1px', 'height':'1px'});
    2225         },
    2226         _error: function(error) {
    2227             this._trigger($.jPlayer.event.error, error);
    2228             if(this.options.errorAlerts) {
    2229                 this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context);
    2230             }
    2231         },
    2232         _warning: function(warning) {
    2233             this._trigger($.jPlayer.event.warning, undefined, warning);
    2234             if(this.options.warningAlerts) {
    2235                 this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context);
    2236             }
    2237         },
    2238         _alert: function(message) {
    2239             alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message);
    2240         },
    2241         _emulateHtmlBridge: function() {
    2242             var self = this,
    2243             methods = $.jPlayer.emulateMethods;
    2244 
    2245             // Emulate methods on jPlayer's DOM element.
    2246             $.each( $.jPlayer.emulateMethods.split(/\s+/g), function(i, name) {
    2247                 self.internal.domNode[name] = function(arg) {
    2248                     self[name](arg);
    2249                 };
    2250 
    2251             });
    2252 
    2253             // Bubble jPlayer events to its DOM element.
    2254             $.each($.jPlayer.event, function(eventName,eventType) {
    2255                 var nativeEvent = true;
    2256                 $.each( $.jPlayer.reservedEvent.split(/\s+/g), function(i, name) {
    2257                     if(name === eventName) {
    2258                         nativeEvent = false;
    2259                         return false;
    2260                     }
    2261                 });
    2262                 if(nativeEvent) {
    2263                     self.element.bind(eventType + ".jPlayer.jPlayerHtml", function() { // With .jPlayer & .jPlayerHtml namespaces.
    2264                         self._emulateHtmlUpdate();
    2265                         var domEvent = document.createEvent("Event");
    2266                         domEvent.initEvent(eventName, false, true);
    2267                         self.internal.domNode.dispatchEvent(domEvent);
    2268                     });
    2269                 }
    2270                 // The error event would require a special case
    2271             });
    2272 
    2273             // IE9 has a readyState property on all elements. The document should have it, but all (except media) elements inherit it in IE9. This conflicts with Popcorn, which polls the readyState.
    2274         },
    2275         _emulateHtmlUpdate: function() {
    2276             var self = this;
    2277 
    2278             $.each( $.jPlayer.emulateStatus.split(/\s+/g), function(i, name) {
    2279                 self.internal.domNode[name] = self.status[name];
    2280             });
    2281             $.each( $.jPlayer.emulateOptions.split(/\s+/g), function(i, name) {
    2282                 self.internal.domNode[name] = self.options[name];
    2283             });
    2284         },
    2285         _destroyHtmlBridge: function() {
    2286             var self = this;
    2287 
    2288             // Bridge event handlers are also removed by destroy() through .jPlayer namespace.
    2289             this.element.unbind(".jPlayerHtml"); // Remove all event handlers created by the jPlayer bridge. So you can change the emulateHtml option.
    2290 
    2291             // Remove the methods and properties
    2292             var emulated = $.jPlayer.emulateMethods + " " + $.jPlayer.emulateStatus + " " + $.jPlayer.emulateOptions;
    2293             $.each( emulated.split(/\s+/g), function(i, name) {
    2294                 delete self.internal.domNode[name];
    2295             });
    2296         }
    2297     };
    2298 
    2299     $.jPlayer.error = {
    2300         FLASH: "e_flash",
    2301         FLASH_DISABLED: "e_flash_disabled",
    2302         NO_SOLUTION: "e_no_solution",
    2303         NO_SUPPORT: "e_no_support",
    2304         URL: "e_url",
    2305         URL_NOT_SET: "e_url_not_set",
    2306         VERSION: "e_version"
    2307     };
    2308 
    2309     $.jPlayer.errorMsg = {
    2310         FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError()
    2311         FLASH_DISABLED: "jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ", // Used in: _flashError()
    2312         NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init()
    2313         NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia()
    2314         URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners()
    2315         URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead()
    2316         VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady()
    2317     };
    2318 
    2319     $.jPlayer.errorHint = {
    2320         FLASH: "Check your swfPath option and that Jplayer.swf is there.",
    2321         FLASH_DISABLED: "Check that you have not display:none; the jPlayer entity or any ancestor.",
    2322         NO_SOLUTION: "Review the jPlayer options: support and supplied.",
    2323         NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.",
    2324         URL: "Check media URL is valid.",
    2325         URL_NOT_SET: "Use setMedia() to set the media URL.",
    2326         VERSION: "Update jPlayer files."
    2327     };
    2328 
    2329     $.jPlayer.warning = {
    2330         CSS_SELECTOR_COUNT: "e_css_selector_count",
    2331         CSS_SELECTOR_METHOD: "e_css_selector_method",
    2332         CSS_SELECTOR_STRING: "e_css_selector_string",
    2333         OPTION_KEY: "e_option_key"
    2334     };
    2335 
    2336     $.jPlayer.warningMsg = {
    2337         CSS_SELECTOR_COUNT: "The number of css selectors found did not equal one: ",
    2338         CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",
    2339         CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",
    2340         OPTION_KEY: "The option requested in jPlayer('option') is undefined."
    2341     };
    2342 
    2343     $.jPlayer.warningHint = {
    2344         CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.",
    2345         CSS_SELECTOR_METHOD: "Check your method name.",
    2346         CSS_SELECTOR_STRING: "Check your css selector is a string.",
    2347         OPTION_KEY: "Check your option name."
    2348     };
    2349 })(jQuery);
     14(function(b,f){"function"===typeof define&&define.amd?define(["jquery"],f):b.jQuery?f(b.jQuery):f(b.Zepto)})(this,function(b,f){b.fn.jPlayer=function(a){var c="string"===typeof a,d=Array.prototype.slice.call(arguments,1),e=this;a=!c&&d.length?b.extend.apply(null,[!0,a].concat(d)):a;if(c&&"_"===a.charAt(0))return e;c?this.each(function(){var c=b(this).data("jPlayer"),h=c&&b.isFunction(c[a])?c[a].apply(c,d):c;if(h!==c&&h!==f)return e=h,!1}):this.each(function(){var c=b(this).data("jPlayer");c?c.option(a||
     15{}):b(this).data("jPlayer",new b.jPlayer(a,this))});return e};b.jPlayer=function(a,c){if(arguments.length){this.element=b(c);this.options=b.extend(!0,{},this.options,a);var d=this;this.element.bind("remove.jPlayer",function(){d.destroy()});this._init()}};"function"!==typeof b.fn.stop&&(b.fn.stop=function(){});b.jPlayer.emulateMethods="load play pause";b.jPlayer.emulateStatus="src readyState networkState currentTime duration paused ended playbackRate";b.jPlayer.emulateOptions="muted volume";b.jPlayer.reservedEvent=
     16"ready flashreset resize repeat error warning";b.jPlayer.event={};b.each("ready flashreset resize repeat click error warning loadstart progress suspend abort emptied stalled play pause loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange".split(" "),function(){b.jPlayer.event[this]="jPlayer_"+this});b.jPlayer.htmlEvent="loadstart abort emptied stalled loadedmetadata loadeddata canplay canplaythrough".split(" ");b.jPlayer.pause=
     17function(){b.each(b.jPlayer.prototype.instances,function(a,c){c.data("jPlayer").status.srcSet&&c.jPlayer("pause")})};b.jPlayer.timeFormat={showHour:!1,showMin:!0,showSec:!0,padHour:!1,padMin:!0,padSec:!0,sepHour:":",sepMin:":",sepSec:""};var m=function(){this.init()};m.prototype={init:function(){this.options={timeFormat:b.jPlayer.timeFormat}},time:function(a){var c=new Date(1E3*(a&&"number"===typeof a?a:0)),b=c.getUTCHours();a=this.options.timeFormat.showHour?c.getUTCMinutes():c.getUTCMinutes()+60*
     18b;c=this.options.timeFormat.showMin?c.getUTCSeconds():c.getUTCSeconds()+60*a;b=this.options.timeFormat.padHour&&10>b?"0"+b:b;a=this.options.timeFormat.padMin&&10>a?"0"+a:a;c=this.options.timeFormat.padSec&&10>c?"0"+c:c;b=""+(this.options.timeFormat.showHour?b+this.options.timeFormat.sepHour:"");b+=this.options.timeFormat.showMin?a+this.options.timeFormat.sepMin:"";return b+=this.options.timeFormat.showSec?c+this.options.timeFormat.sepSec:""}};var n=new m;b.jPlayer.convertTime=function(a){return n.time(a)};
     19b.jPlayer.uaBrowser=function(a){a=a.toLowerCase();var c=/(opera)(?:.*version)?[ \/]([\w.]+)/,b=/(msie) ([\w.]+)/,e=/(mozilla)(?:.*? rv:([\w.]+))?/;a=/(webkit)[ \/]([\w.]+)/.exec(a)||c.exec(a)||b.exec(a)||0>a.indexOf("compatible")&&e.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};b.jPlayer.uaPlatform=function(a){var c=a.toLowerCase(),b=/(android)/,e=/(mobile)/;a=/(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/.exec(c)||[];c=/(ipad|playbook)/.exec(c)||!e.exec(c)&&b.exec(c)||
     20[];a[1]&&(a[1]=a[1].replace(/\s/g,"_"));return{platform:a[1]||"",tablet:c[1]||""}};b.jPlayer.browser={};b.jPlayer.platform={};var k=b.jPlayer.uaBrowser(navigator.userAgent);k.browser&&(b.jPlayer.browser[k.browser]=!0,b.jPlayer.browser.version=k.version);k=b.jPlayer.uaPlatform(navigator.userAgent);k.platform&&(b.jPlayer.platform[k.platform]=!0,b.jPlayer.platform.mobile=!k.tablet,b.jPlayer.platform.tablet=!!k.tablet);b.jPlayer.getDocMode=function(){var a;b.jPlayer.browser.msie&&(document.documentMode?
     21a=document.documentMode:(a=5,document.compatMode&&"CSS1Compat"===document.compatMode&&(a=7)));return a};b.jPlayer.browser.documentMode=b.jPlayer.getDocMode();b.jPlayer.nativeFeatures={init:function(){var a=document,c=a.createElement("video"),b={w3c:"fullscreenEnabled fullscreenElement requestFullscreen exitFullscreen fullscreenchange fullscreenerror".split(" "),moz:"mozFullScreenEnabled mozFullScreenElement mozRequestFullScreen mozCancelFullScreen mozfullscreenchange mozfullscreenerror".split(" "),
     22webkit:" webkitCurrentFullScreenElement webkitRequestFullScreen webkitCancelFullScreen webkitfullscreenchange ".split(" "),webkitVideo:"webkitSupportsFullscreen webkitDisplayingFullscreen webkitEnterFullscreen webkitExitFullscreen  ".split(" ")},e=["w3c","moz","webkit","webkitVideo"],g,h;this.fullscreen=c={support:{w3c:!!a[b.w3c[0]],moz:!!a[b.moz[0]],webkit:"function"===typeof a[b.webkit[3]],webkitVideo:"function"===typeof c[b.webkitVideo[2]]},used:{}};g=0;for(h=e.length;g<h;g++){var f=e[g];if(c.support[f]){c.spec=
     23f;c.used[f]=!0;break}}if(c.spec){var l=b[c.spec];c.api={fullscreenEnabled:!0,fullscreenElement:function(c){c=c?c:a;return c[l[1]]},requestFullscreen:function(a){return a[l[2]]()},exitFullscreen:function(c){c=c?c:a;return c[l[3]]()}};c.event={fullscreenchange:l[4],fullscreenerror:l[5]}}else c.api={fullscreenEnabled:!1,fullscreenElement:function(){return null},requestFullscreen:function(){},exitFullscreen:function(){}},c.event={}}};b.jPlayer.nativeFeatures.init();b.jPlayer.focus=null;b.jPlayer.keyIgnoreElementNames=
     24"INPUT TEXTAREA";var p=function(a){var c=b.jPlayer.focus,d;c&&(b.each(b.jPlayer.keyIgnoreElementNames.split(/\s+/g),function(c,b){if(a.target.nodeName.toUpperCase()===b.toUpperCase())return d=!0,!1}),d||b.each(c.options.keyBindings,function(d,g){if(g&&a.which===g.key&&b.isFunction(g.fn))return a.preventDefault(),g.fn(c),!1}))};b.jPlayer.keys=function(a){b(document.documentElement).unbind("keydown.jPlayer");a&&b(document.documentElement).bind("keydown.jPlayer",p)};b.jPlayer.keys(!0);b.jPlayer.prototype=
     25{count:0,version:{script:"2.5.0",needFlash:"2.5.0",flash:"unknown"},options:{swfPath:"js",solution:"html, flash",supplied:"mp3",preload:"metadata",volume:0.8,muted:!1,playbackRate:1,defaultPlaybackRate:1,minPlaybackRate:0.5,maxPlaybackRate:4,wmode:"opaque",backgroundColor:"#000000",cssSelectorAncestor:"#jp_container_1",cssSelector:{videoPlay:".jp-video-play",play:".jp-play",pause:".jp-pause",stop:".jp-stop",seekBar:".jp-seek-bar",playBar:".jp-play-bar",mute:".jp-mute",unmute:".jp-unmute",volumeBar:".jp-volume-bar",
     26volumeBarValue:".jp-volume-bar-value",volumeMax:".jp-volume-max",playbackRateBar:".jp-playback-rate-bar",playbackRateBarValue:".jp-playback-rate-bar-value",currentTime:".jp-current-time",duration:".jp-duration",fullScreen:".jp-full-screen",restoreScreen:".jp-restore-screen",repeat:".jp-repeat",repeatOff:".jp-repeat-off",gui:".jp-gui",noSolution:".jp-no-solution"},smoothPlayBar:!1,fullScreen:!1,fullWindow:!1,autohide:{restored:!1,full:!0,fadeIn:200,fadeOut:600,hold:1E3},loop:!1,repeat:function(a){a.jPlayer.options.loop?
     27b(this).unbind(".jPlayerRepeat").bind(b.jPlayer.event.ended+".jPlayer.jPlayerRepeat",function(){b(this).jPlayer("play")}):b(this).unbind(".jPlayerRepeat")},nativeVideoControls:{},noFullWindow:{msie:/msie [0-6]\./,ipad:/ipad.*?os [0-4]\./,iphone:/iphone/,ipod:/ipod/,android_pad:/android [0-3]\.(?!.*?mobile)/,android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/},noVolume:{ipad:/ipad/,iphone:/iphone/,ipod:/ipod/,android_pad:/android(?!.*?mobile)/,
     28android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/,playbook:/playbook/},timeFormat:{},keyEnabled:!1,audioFullScreen:!1,keyBindings:{play:{key:32,fn:function(a){a.status.paused?a.play():a.pause()}},fullScreen:{key:13,fn:function(a){(a.status.video||a.options.audioFullScreen)&&a._setOption("fullScreen",!a.options.fullScreen)}},muted:{key:8,fn:function(a){a._muted(!a.options.muted)}},volumeUp:{key:38,fn:function(a){a.volume(a.options.volume+
     290.1)}},volumeDown:{key:40,fn:function(a){a.volume(a.options.volume-0.1)}}},verticalVolume:!1,verticalPlaybackRate:!1,globalVolume:!1,idPrefix:"jp",noConflict:"jQuery",emulateHtml:!1,consoleAlerts:!0,errorAlerts:!1,warningAlerts:!1},optionsAudio:{size:{width:"0px",height:"0px",cssClass:""},sizeFull:{width:"0px",height:"0px",cssClass:""}},optionsVideo:{size:{width:"480px",height:"270px",cssClass:"jp-video-270p"},sizeFull:{width:"100%",height:"100%",cssClass:"jp-video-full"}},instances:{},status:{src:"",
     30media:{},paused:!0,format:{},formatType:"",waitForPlay:!0,waitForLoad:!0,srcSet:!1,video:!1,seekPercent:0,currentPercentRelative:0,currentPercentAbsolute:0,currentTime:0,duration:0,videoWidth:0,videoHeight:0,readyState:0,networkState:0,playbackRate:1,ended:0},internal:{ready:!1},solution:{html:!0,flash:!0},format:{mp3:{codec:'audio/mpeg; codecs="mp3"',flashCanPlay:!0,media:"audio"},m4a:{codec:'audio/mp4; codecs="mp4a.40.2"',flashCanPlay:!0,media:"audio"},m3u8a:{codec:'application/vnd.apple.mpegurl; codecs="mp4a.40.2"',
     31flashCanPlay:!1,media:"audio"},m3ua:{codec:"audio/mpegurl",flashCanPlay:!1,media:"audio"},oga:{codec:'audio/ogg; codecs="vorbis, opus"',flashCanPlay:!1,media:"audio"},flac:{codec:"audio/x-flac",flashCanPlay:!1,media:"audio"},wav:{codec:'audio/wav; codecs="1"',flashCanPlay:!1,media:"audio"},webma:{codec:'audio/webm; codecs="vorbis"',flashCanPlay:!1,media:"audio"},fla:{codec:"audio/x-flv",flashCanPlay:!0,media:"audio"},rtmpa:{codec:'audio/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"audio"},m4v:{codec:'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
     32flashCanPlay:!0,media:"video"},m3u8v:{codec:'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!1,media:"video"},m3uv:{codec:"audio/mpegurl",flashCanPlay:!1,media:"video"},ogv:{codec:'video/ogg; codecs="theora, vorbis"',flashCanPlay:!1,media:"video"},webmv:{codec:'video/webm; codecs="vorbis, vp8"',flashCanPlay:!1,media:"video"},flv:{codec:"video/x-flv",flashCanPlay:!0,media:"video"},rtmpv:{codec:'video/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"video"}},_init:function(){var a=
     33this;this.element.empty();this.status=b.extend({},this.status);this.internal=b.extend({},this.internal);this.options.timeFormat=b.extend({},b.jPlayer.timeFormat,this.options.timeFormat);this.internal.cmdsIgnored=b.jPlayer.platform.ipad||b.jPlayer.platform.iphone||b.jPlayer.platform.ipod;this.internal.domNode=this.element.get(0);this.options.keyEnabled&&!b.jPlayer.focus&&(b.jPlayer.focus=this);this.formats=[];this.solutions=[];this.require={};this.htmlElement={};this.html={};this.html.audio={};this.html.video=
     34{};this.flash={};this.css={};this.css.cs={};this.css.jq={};this.ancestorJq=[];this.options.volume=this._limitValue(this.options.volume,0,1);b.each(this.options.supplied.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.format[e]){var f=!1;b.each(a.formats,function(a,c){if(e===c)return f=!0,!1});f||a.formats.push(e)}});b.each(this.options.solution.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.solution[e]){var f=!1;b.each(a.solutions,function(a,
     35c){if(e===c)return f=!0,!1});f||a.solutions.push(e)}});this.internal.instance="jp_"+this.count;this.instances[this.internal.instance]=this.element;this.element.attr("id")||this.element.attr("id",this.options.idPrefix+"_jplayer_"+this.count);this.internal.self=b.extend({},{id:this.element.attr("id"),jq:this.element});this.internal.audio=b.extend({},{id:this.options.idPrefix+"_audio_"+this.count,jq:f});this.internal.video=b.extend({},{id:this.options.idPrefix+"_video_"+this.count,jq:f});this.internal.flash=
     36b.extend({},{id:this.options.idPrefix+"_flash_"+this.count,jq:f,swf:this.options.swfPath+(".swf"!==this.options.swfPath.toLowerCase().slice(-4)?(this.options.swfPath&&"/"!==this.options.swfPath.slice(-1)?"/":"")+"Jplayer.swf":"")});this.internal.poster=b.extend({},{id:this.options.idPrefix+"_poster_"+this.count,jq:f});b.each(b.jPlayer.event,function(c,b){a.options[c]!==f&&(a.element.bind(b+".jPlayer",a.options[c]),a.options[c]=f)});this.require.audio=!1;this.require.video=!1;b.each(this.formats,function(c,
     37b){a.require[a.format[b].media]=!0});this.options=this.require.video?b.extend(!0,{},this.optionsVideo,this.options):b.extend(!0,{},this.optionsAudio,this.options);this._setSize();this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullWindow=this._uaBlocklist(this.options.noFullWindow);this.status.noVolume=this._uaBlocklist(this.options.noVolume);b.jPlayer.nativeFeatures.fullscreen.api.fullscreenEnabled&&this._fullscreenAddEventListeners();this._restrictNativeVideoControls();
     38this.htmlElement.poster=document.createElement("img");this.htmlElement.poster.id=this.internal.poster.id;this.htmlElement.poster.onload=function(){a.status.video&&!a.status.waitForPlay||a.internal.poster.jq.show()};this.element.append(this.htmlElement.poster);this.internal.poster.jq=b("#"+this.internal.poster.id);this.internal.poster.jq.css({width:this.status.width,height:this.status.height});this.internal.poster.jq.hide();this.internal.poster.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)});
     39this.html.audio.available=!1;this.require.audio&&(this.htmlElement.audio=document.createElement("audio"),this.htmlElement.audio.id=this.internal.audio.id,this.html.audio.available=!!this.htmlElement.audio.canPlayType&&this._testCanPlayType(this.htmlElement.audio));this.html.video.available=!1;this.require.video&&(this.htmlElement.video=document.createElement("video"),this.htmlElement.video.id=this.internal.video.id,this.html.video.available=!!this.htmlElement.video.canPlayType&&this._testCanPlayType(this.htmlElement.video));
     40this.flash.available=this._checkForFlash(10.1);this.html.canPlay={};this.flash.canPlay={};b.each(this.formats,function(c,b){a.html.canPlay[b]=a.html[a.format[b].media].available&&""!==a.htmlElement[a.format[b].media].canPlayType(a.format[b].codec);a.flash.canPlay[b]=a.format[b].flashCanPlay&&a.flash.available});this.html.desired=!1;this.flash.desired=!1;b.each(this.solutions,function(c,d){if(0===c)a[d].desired=!0;else{var e=!1,f=!1;b.each(a.formats,function(c,b){a[a.solutions[0]].canPlay[b]&&("video"===
     41a.format[b].media?f=!0:e=!0)});a[d].desired=a.require.audio&&!e||a.require.video&&!f}});this.html.support={};this.flash.support={};b.each(this.formats,function(c,b){a.html.support[b]=a.html.canPlay[b]&&a.html.desired;a.flash.support[b]=a.flash.canPlay[b]&&a.flash.desired});this.html.used=!1;this.flash.used=!1;b.each(this.solutions,function(c,d){b.each(a.formats,function(c,b){if(a[d].support[b])return a[d].used=!0,!1})});this._resetActive();this._resetGate();this._cssSelectorAncestor(this.options.cssSelectorAncestor);
     42this.html.used||this.flash.used?this.css.jq.noSolution.length&&this.css.jq.noSolution.hide():(this._error({type:b.jPlayer.error.NO_SOLUTION,context:"{solution:'"+this.options.solution+"', supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SOLUTION,hint:b.jPlayer.errorHint.NO_SOLUTION}),this.css.jq.noSolution.length&&this.css.jq.noSolution.show());if(this.flash.used){var c,d="jQuery="+encodeURI(this.options.noConflict)+"&id="+encodeURI(this.internal.self.id)+"&vol="+this.options.volume+
     43"&muted="+this.options.muted;if(b.jPlayer.browser.msie&&(9>Number(b.jPlayer.browser.version)||9>b.jPlayer.browser.documentMode)){d=['<param name="movie" value="'+this.internal.flash.swf+'" />','<param name="FlashVars" value="'+d+'" />','<param name="allowScriptAccess" value="always" />','<param name="bgcolor" value="'+this.options.backgroundColor+'" />','<param name="wmode" value="'+this.options.wmode+'" />'];c=document.createElement('<object id="'+this.internal.flash.id+'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0" tabindex="-1"></object>');
     44for(var e=0;e<d.length;e++)c.appendChild(document.createElement(d[e]))}else e=function(a,c,b){var d=document.createElement("param");d.setAttribute("name",c);d.setAttribute("value",b);a.appendChild(d)},c=document.createElement("object"),c.setAttribute("id",this.internal.flash.id),c.setAttribute("name",this.internal.flash.id),c.setAttribute("data",this.internal.flash.swf),c.setAttribute("type","application/x-shockwave-flash"),c.setAttribute("width","1"),c.setAttribute("height","1"),c.setAttribute("tabindex",
     45"-1"),e(c,"flashvars",d),e(c,"allowscriptaccess","always"),e(c,"bgcolor",this.options.backgroundColor),e(c,"wmode",this.options.wmode);this.element.append(c);this.internal.flash.jq=b(c)}this.status.playbackRateEnabled=this.html.used&&!this.flash.used?this._testPlaybackRate("audio"):!1;this._updatePlaybackRate();this.html.used&&(this.html.audio.available&&(this._addHtmlEventListeners(this.htmlElement.audio,this.html.audio),this.element.append(this.htmlElement.audio),this.internal.audio.jq=b("#"+this.internal.audio.id)),
     46this.html.video.available&&(this._addHtmlEventListeners(this.htmlElement.video,this.html.video),this.element.append(this.htmlElement.video),this.internal.video.jq=b("#"+this.internal.video.id),this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):this.internal.video.jq.css({width:"0px",height:"0px"}),this.internal.video.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)})));this.options.emulateHtml&&this._emulateHtmlBridge();
     47this.html.used&&!this.flash.used&&setTimeout(function(){a.internal.ready=!0;a.version.flash="n/a";a._trigger(b.jPlayer.event.repeat);a._trigger(b.jPlayer.event.ready)},100);this._updateNativeVideoControls();this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();b.jPlayer.prototype.count++},destroy:function(){this.clearMedia();this._removeUiClass();this.css.jq.currentTime.length&&this.css.jq.currentTime.text("");this.css.jq.duration.length&&this.css.jq.duration.text("");b.each(this.css.jq,function(a,
     48c){c.length&&c.unbind(".jPlayer")});this.internal.poster.jq.unbind(".jPlayer");this.internal.video.jq&&this.internal.video.jq.unbind(".jPlayer");this._fullscreenRemoveEventListeners();this===b.jPlayer.focus&&(b.jPlayer.focus=null);this.options.emulateHtml&&this._destroyHtmlBridge();this.element.removeData("jPlayer");this.element.unbind(".jPlayer");this.element.empty();delete this.instances[this.internal.instance]},enable:function(){},disable:function(){},_testCanPlayType:function(a){try{return a.canPlayType(this.format.mp3.codec),
     49!0}catch(c){return!1}},_testPlaybackRate:function(a){a=document.createElement("string"===typeof a?a:"audio");try{return"playbackRate"in a?(a.playbackRate=0.5,0.5===a.playbackRate):!1}catch(c){return!1}},_uaBlocklist:function(a){var c=navigator.userAgent.toLowerCase(),d=!1;b.each(a,function(a,b){if(b&&b.test(c))return d=!0,!1});return d},_restrictNativeVideoControls:function(){this.require.audio&&this.status.nativeVideoControls&&(this.status.nativeVideoControls=!1,this.status.noFullWindow=!0)},_updateNativeVideoControls:function(){this.html.video.available&&
     50this.html.used&&(this.htmlElement.video.controls=this.status.nativeVideoControls,this._updateAutohide(),this.status.nativeVideoControls&&this.require.video?(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})):this.status.waitForPlay&&this.status.video&&(this.internal.poster.jq.show(),this.internal.video.jq.css({width:"0px",height:"0px"})))},_addHtmlEventListeners:function(a,c){var d=this;a.preload=this.options.preload;a.muted=this.options.muted;
     51a.volume=this.options.volume;this.status.playbackRateEnabled&&(a.defaultPlaybackRate=this.options.defaultPlaybackRate,a.playbackRate=this.options.playbackRate);a.addEventListener("progress",function(){c.gate&&(d.internal.cmdsIgnored&&0<this.readyState&&(d.internal.cmdsIgnored=!1),d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.progress))},!1);a.addEventListener("timeupdate",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.timeupdate))},!1);
     52a.addEventListener("durationchange",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.durationchange))},!1);a.addEventListener("play",function(){c.gate&&(d._updateButtons(!0),d._html_checkWaitForPlay(),d._trigger(b.jPlayer.event.play))},!1);a.addEventListener("playing",function(){c.gate&&(d._updateButtons(!0),d._seeked(),d._trigger(b.jPlayer.event.playing))},!1);a.addEventListener("pause",function(){c.gate&&(d._updateButtons(!1),d._trigger(b.jPlayer.event.pause))},
     53!1);a.addEventListener("waiting",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.waiting))},!1);a.addEventListener("seeking",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.seeking))},!1);a.addEventListener("seeked",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.seeked))},!1);a.addEventListener("volumechange",function(){c.gate&&(d.options.volume=a.volume,d.options.muted=a.muted,d._updateMute(),d._updateVolume(),d._trigger(b.jPlayer.event.volumechange))},!1);a.addEventListener("ratechange",
     54function(){c.gate&&(d.options.defaultPlaybackRate=a.defaultPlaybackRate,d.options.playbackRate=a.playbackRate,d._updatePlaybackRate(),d._trigger(b.jPlayer.event.ratechange))},!1);a.addEventListener("suspend",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.suspend))},!1);a.addEventListener("ended",function(){c.gate&&(b.jPlayer.browser.webkit||(d.htmlElement.media.currentTime=0),d.htmlElement.media.pause(),d._updateButtons(!1),d._getHtmlStatus(a,!0),d._updateInterface(),d._trigger(b.jPlayer.event.ended))},
     55!1);a.addEventListener("error",function(){c.gate&&(d._updateButtons(!1),d._seeked(),d.status.srcSet&&(clearTimeout(d.internal.htmlDlyCmdId),d.status.waitForLoad=!0,d.status.waitForPlay=!0,d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"}),d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show(),d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show(),d._error({type:b.jPlayer.error.URL,context:d.status.src,message:b.jPlayer.errorMsg.URL,
     56hint:b.jPlayer.errorHint.URL})))},!1);b.each(b.jPlayer.htmlEvent,function(e,g){a.addEventListener(this,function(){c.gate&&d._trigger(b.jPlayer.event[g])},!1)})},_getHtmlStatus:function(a,c){var b=0,e=0,g=0,f=0;isFinite(a.duration)&&(this.status.duration=a.duration);b=a.currentTime;e=0<this.status.duration?100*b/this.status.duration:0;"object"===typeof a.seekable&&0<a.seekable.length?(g=0<this.status.duration?100*a.seekable.end(a.seekable.length-1)/this.status.duration:100,f=0<this.status.duration?
     57100*a.currentTime/a.seekable.end(a.seekable.length-1):0):(g=100,f=e);c&&(e=f=b=0);this.status.seekPercent=g;this.status.currentPercentRelative=f;this.status.currentPercentAbsolute=e;this.status.currentTime=b;this.status.videoWidth=a.videoWidth;this.status.videoHeight=a.videoHeight;this.status.readyState=a.readyState;this.status.networkState=a.networkState;this.status.playbackRate=a.playbackRate;this.status.ended=a.ended},_resetStatus:function(){this.status=b.extend({},this.status,b.jPlayer.prototype.status)},
     58_trigger:function(a,c,d){a=b.Event(a);a.jPlayer={};a.jPlayer.version=b.extend({},this.version);a.jPlayer.options=b.extend(!0,{},this.options);a.jPlayer.status=b.extend(!0,{},this.status);a.jPlayer.html=b.extend(!0,{},this.html);a.jPlayer.flash=b.extend(!0,{},this.flash);c&&(a.jPlayer.error=b.extend({},c));d&&(a.jPlayer.warning=b.extend({},d));this.element.trigger(a)},jPlayerFlashEvent:function(a,c){if(a===b.jPlayer.event.ready)if(!this.internal.ready)this.internal.ready=!0,this.internal.flash.jq.css({width:"0px",
     59height:"0px"}),this.version.flash=c.version,this.version.needFlash!==this.version.flash&&this._error({type:b.jPlayer.error.VERSION,context:this.version.flash,message:b.jPlayer.errorMsg.VERSION+this.version.flash,hint:b.jPlayer.errorHint.VERSION}),this._trigger(b.jPlayer.event.repeat),this._trigger(a);else if(this.flash.gate){if(this.status.srcSet){var d=this.status.currentTime,e=this.status.paused;this.setMedia(this.status.media);this.volumeWorker(this.options.volume);0<d&&(e?this.pause(d):this.play(d))}this._trigger(b.jPlayer.event.flashreset)}if(this.flash.gate)switch(a){case b.jPlayer.event.progress:this._getFlashStatus(c);
     60this._updateInterface();this._trigger(a);break;case b.jPlayer.event.timeupdate:this._getFlashStatus(c);this._updateInterface();this._trigger(a);break;case b.jPlayer.event.play:this._seeked();this._updateButtons(!0);this._trigger(a);break;case b.jPlayer.event.pause:this._updateButtons(!1);this._trigger(a);break;case b.jPlayer.event.ended:this._updateButtons(!1);this._trigger(a);break;case b.jPlayer.event.click:this._trigger(a);break;case b.jPlayer.event.error:this.status.waitForLoad=!0;this.status.waitForPlay=
     61!0;this.status.video&&this.internal.flash.jq.css({width:"0px",height:"0px"});this._validString(this.status.media.poster)&&this.internal.poster.jq.show();this.css.jq.videoPlay.length&&this.status.video&&this.css.jq.videoPlay.show();this.status.video?this._flash_setVideo(this.status.media):this._flash_setAudio(this.status.media);this._updateButtons(!1);this._error({type:b.jPlayer.error.URL,context:c.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL});break;case b.jPlayer.event.seeking:this._seeking();
     62this._trigger(a);break;case b.jPlayer.event.seeked:this._seeked();this._trigger(a);break;case b.jPlayer.event.ready:break;default:this._trigger(a)}return!1},_getFlashStatus:function(a){this.status.seekPercent=a.seekPercent;this.status.currentPercentRelative=a.currentPercentRelative;this.status.currentPercentAbsolute=a.currentPercentAbsolute;this.status.currentTime=a.currentTime;this.status.duration=a.duration;this.status.videoWidth=a.videoWidth;this.status.videoHeight=a.videoHeight;this.status.readyState=
     634;this.status.networkState=0;this.status.playbackRate=1;this.status.ended=!1},_updateButtons:function(a){a===f?a=!this.status.paused:this.status.paused=!a;this.css.jq.play.length&&this.css.jq.pause.length&&(a?(this.css.jq.play.hide(),this.css.jq.pause.show()):(this.css.jq.play.show(),this.css.jq.pause.hide()));this.css.jq.restoreScreen.length&&this.css.jq.fullScreen.length&&(this.status.noFullWindow?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.hide()):this.options.fullWindow?(this.css.jq.fullScreen.hide(),
     64this.css.jq.restoreScreen.show()):(this.css.jq.fullScreen.show(),this.css.jq.restoreScreen.hide()));this.css.jq.repeat.length&&this.css.jq.repeatOff.length&&(this.options.loop?(this.css.jq.repeat.hide(),this.css.jq.repeatOff.show()):(this.css.jq.repeat.show(),this.css.jq.repeatOff.hide()))},_updateInterface:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.width(this.status.seekPercent+"%");this.css.jq.playBar.length&&(this.options.smoothPlayBar?this.css.jq.playBar.stop().animate({width:this.status.currentPercentAbsolute+
     65"%"},250,"linear"):this.css.jq.playBar.width(this.status.currentPercentRelative+"%"));this.css.jq.currentTime.length&&this.css.jq.currentTime.text(this._convertTime(this.status.currentTime));this.css.jq.duration.length&&this.css.jq.duration.text(this._convertTime(this.status.duration))},_convertTime:m.prototype.time,_seeking:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.addClass("jp-seeking-bg")},_seeked:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.removeClass("jp-seeking-bg")},
     66_resetGate:function(){this.html.audio.gate=!1;this.html.video.gate=!1;this.flash.gate=!1},_resetActive:function(){this.html.active=!1;this.flash.active=!1},_escapeHtml:function(a){return a.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;").split('"').join("&quot;")},_qualifyURL:function(a){var c=document.createElement("div");c.innerHTML='<a href="'+this._escapeHtml(a)+'">x</a>';return c.firstChild.href},_absoluteMediaUrls:function(a){var c=this;b.each(a,function(b,e){c.format[b]&&
     67(a[b]=c._qualifyURL(e))});return a},setMedia:function(a){var c=this,d=!1,e=this.status.media.poster!==a.poster;this._resetMedia();this._resetGate();this._resetActive();a=this._absoluteMediaUrls(a);b.each(this.formats,function(e,f){var k="video"===c.format[f].media;b.each(c.solutions,function(b,e){if(c[e].support[f]&&c._validString(a[f])){var g="html"===e;k?(g?(c.html.video.gate=!0,c._html_setVideo(a),c.html.active=!0):(c.flash.gate=!0,c._flash_setVideo(a),c.flash.active=!0),c.css.jq.videoPlay.length&&
     68c.css.jq.videoPlay.show(),c.status.video=!0):(g?(c.html.audio.gate=!0,c._html_setAudio(a),c.html.active=!0):(c.flash.gate=!0,c._flash_setAudio(a),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.hide(),c.status.video=!1);d=!0;return!1}});if(d)return!1});d?(this.status.nativeVideoControls&&this.html.video.gate||!this._validString(a.poster)||(e?this.htmlElement.poster.src=a.poster:this.internal.poster.jq.show()),this.status.srcSet=!0,this.status.media=b.extend({},a),this._updateButtons(!1),
     69this._updateInterface()):this._error({type:b.jPlayer.error.NO_SUPPORT,context:"{supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SUPPORT,hint:b.jPlayer.errorHint.NO_SUPPORT})},_resetMedia:function(){this._resetStatus();this._updateButtons(!1);this._updateInterface();this._seeked();this.internal.poster.jq.hide();clearTimeout(this.internal.htmlDlyCmdId);this.html.active?this._html_resetMedia():this.flash.active&&this._flash_resetMedia()},clearMedia:function(){this._resetMedia();
     70this.html.active?this._html_clearMedia():this.flash.active&&this._flash_clearMedia();this._resetGate();this._resetActive()},load:function(){this.status.srcSet?this.html.active?this._html_load():this.flash.active&&this._flash_load():this._urlNotSetError("load")},focus:function(){this.options.keyEnabled&&(b.jPlayer.focus=this)},play:function(a){a="number"===typeof a?a:NaN;this.status.srcSet?(this.focus(),this.html.active?this._html_play(a):this.flash.active&&this._flash_play(a)):this._urlNotSetError("play")},
     71videoPlay:function(){this.play()},pause:function(a){a="number"===typeof a?a:NaN;this.status.srcSet?this.html.active?this._html_pause(a):this.flash.active&&this._flash_pause(a):this._urlNotSetError("pause")},tellOthers:function(a,c){var d=this,e="function"===typeof c,g=Array.prototype.slice.call(arguments);"string"===typeof a&&(e&&g.splice(1,1),b.each(this.instances,function(){d.element!==this&&(e&&!c.call(this.data("jPlayer"),d)||this.jPlayer.apply(this,g))}))},pauseOthers:function(a){this.tellOthers("pause",
     72function(){return this.status.srcSet},a)},stop:function(){this.status.srcSet?this.html.active?this._html_pause(0):this.flash.active&&this._flash_pause(0):this._urlNotSetError("stop")},playHead:function(a){a=this._limitValue(a,0,100);this.status.srcSet?this.html.active?this._html_playHead(a):this.flash.active&&this._flash_playHead(a):this._urlNotSetError("playHead")},_muted:function(a){this.mutedWorker(a);this.options.globalVolume&&this.tellOthers("mutedWorker",function(){return this.options.globalVolume},
     73a)},mutedWorker:function(a){this.options.muted=a;this.html.used&&this._html_setProperty("muted",a);this.flash.used&&this._flash_mute(a);this.html.video.gate||this.html.audio.gate||(this._updateMute(a),this._updateVolume(this.options.volume),this._trigger(b.jPlayer.event.volumechange))},mute:function(a){a=a===f?!0:!!a;this._muted(a)},unmute:function(a){a=a===f?!0:!!a;this._muted(!a)},_updateMute:function(a){a===f&&(a=this.options.muted);this.css.jq.mute.length&&this.css.jq.unmute.length&&(this.status.noVolume?
     74(this.css.jq.mute.hide(),this.css.jq.unmute.hide()):a?(this.css.jq.mute.hide(),this.css.jq.unmute.show()):(this.css.jq.mute.show(),this.css.jq.unmute.hide()))},volume:function(a){this.volumeWorker(a);this.options.globalVolume&&this.tellOthers("volumeWorker",function(){return this.options.globalVolume},a)},volumeWorker:function(a){a=this._limitValue(a,0,1);this.options.volume=a;this.html.used&&this._html_setProperty("volume",a);this.flash.used&&this._flash_volume(a);this.html.video.gate||this.html.audio.gate||
     75(this._updateVolume(a),this._trigger(b.jPlayer.event.volumechange))},volumeBar:function(a){if(this.css.jq.volumeBar.length){var c=b(a.currentTarget),d=c.offset(),e=a.pageX-d.left,g=c.width();a=c.height()-a.pageY+d.top;c=c.height();this.options.verticalVolume?this.volume(a/c):this.volume(e/g)}this.options.muted&&this._muted(!1)},volumeBarValue:function(){},_updateVolume:function(a){a===f&&(a=this.options.volume);a=this.options.muted?0:a;this.status.noVolume?(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.hide(),
     76this.css.jq.volumeBarValue.length&&this.css.jq.volumeBarValue.hide(),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.hide()):(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.show(),this.css.jq.volumeBarValue.length&&(this.css.jq.volumeBarValue.show(),this.css.jq.volumeBarValue[this.options.verticalVolume?"height":"width"](100*a+"%")),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.show())},volumeMax:function(){this.volume(1);this.options.muted&&this._muted(!1)},_cssSelectorAncestor:function(a){var c=
     77this;this.options.cssSelectorAncestor=a;this._removeUiClass();this.ancestorJq=a?b(a):[];a&&1!==this.ancestorJq.length&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.ancestorJq.length+" found for cssSelectorAncestor.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT});this._addUiClass();b.each(this.options.cssSelector,function(a,b){c._cssSelector(a,b)});this._updateInterface();this._updateButtons();this._updateAutohide();this._updateVolume();
     78this._updateMute()},_cssSelector:function(a,c){var d=this;"string"===typeof c?b.jPlayer.prototype.options.cssSelector[a]?(this.css.jq[a]&&this.css.jq[a].length&&this.css.jq[a].unbind(".jPlayer"),this.options.cssSelector[a]=c,this.css.cs[a]=this.options.cssSelectorAncestor+" "+c,this.css.jq[a]=c?b(this.css.cs[a]):[],this.css.jq[a].length&&this.css.jq[a].bind("click.jPlayer",function(c){c.preventDefault();d[a](c);b(this).blur()}),c&&1!==this.css.jq[a].length&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,
     79context:this.css.cs[a],message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.css.jq[a].length+" found for "+a+" method.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT})):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_METHOD,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_METHOD,hint:b.jPlayer.warningHint.CSS_SELECTOR_METHOD}):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_STRING,context:c,message:b.jPlayer.warningMsg.CSS_SELECTOR_STRING,hint:b.jPlayer.warningHint.CSS_SELECTOR_STRING})},
     80seekBar:function(a){if(this.css.jq.seekBar.length){var c=b(a.currentTarget),d=c.offset();a=a.pageX-d.left;c=c.width();this.playHead(100*a/c)}},playBar:function(){},playbackRate:function(a){this._setOption("playbackRate",a)},playbackRateBar:function(a){if(this.css.jq.playbackRateBar.length){var c=b(a.currentTarget),d=c.offset(),e=a.pageX-d.left,g=c.width();a=c.height()-a.pageY+d.top;c=c.height();this.playbackRate((this.options.verticalPlaybackRate?a/c:e/g)*(this.options.maxPlaybackRate-this.options.minPlaybackRate)+
     81this.options.minPlaybackRate)}},playbackRateBarValue:function(){},_updatePlaybackRate:function(){var a=(this.options.playbackRate-this.options.minPlaybackRate)/(this.options.maxPlaybackRate-this.options.minPlaybackRate);this.status.playbackRateEnabled?(this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.show(),this.css.jq.playbackRateBarValue.length&&(this.css.jq.playbackRateBarValue.show(),this.css.jq.playbackRateBarValue[this.options.verticalPlaybackRate?"height":"width"](100*a+"%"))):
     82(this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.hide(),this.css.jq.playbackRateBarValue.length&&this.css.jq.playbackRateBarValue.hide())},repeat:function(){this._loop(!0)},repeatOff:function(){this._loop(!1)},_loop:function(a){this.options.loop!==a&&(this.options.loop=a,this._updateButtons(),this._trigger(b.jPlayer.event.repeat))},currentTime:function(){},duration:function(){},gui:function(){},noSolution:function(){},option:function(a,c){var d=a;if(0===arguments.length)return b.extend(!0,
     83{},this.options);if("string"===typeof a){var e=a.split(".");if(c===f){for(var d=b.extend(!0,{},this.options),g=0;g<e.length;g++)if(d[e[g]]!==f)d=d[e[g]];else return this._warning({type:b.jPlayer.warning.OPTION_KEY,context:a,message:b.jPlayer.warningMsg.OPTION_KEY,hint:b.jPlayer.warningHint.OPTION_KEY}),f;return d}for(var g=d={},h=0;h<e.length;h++)h<e.length-1?(g[e[h]]={},g=g[e[h]]):g[e[h]]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(a,b){c._setOption(a,
     84b)});return this},_setOption:function(a,c){var d=this;switch(a){case "volume":this.volume(c);break;case "muted":this._muted(c);break;case "globalVolume":this.options[a]=c;break;case "cssSelectorAncestor":this._cssSelectorAncestor(c);break;case "cssSelector":b.each(c,function(a,c){d._cssSelector(a,c)});break;case "playbackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate,this.options.maxPlaybackRate);this.html.used&&this._html_setProperty("playbackRate",c);this._updatePlaybackRate();
     85break;case "defaultPlaybackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate,this.options.maxPlaybackRate);this.html.used&&this._html_setProperty("defaultPlaybackRate",c);this._updatePlaybackRate();break;case "minPlaybackRate":this.options[a]=c=this._limitValue(c,0.1,this.options.maxPlaybackRate-0.1);this._updatePlaybackRate();break;case "maxPlaybackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate+0.1,16);this._updatePlaybackRate();break;case "fullScreen":if(this.options[a]!==
     86c){var e=b.jPlayer.nativeFeatures.fullscreen.used.webkitVideo;if(!e||e&&!this.status.waitForPlay)e||(this.options[a]=c),c?this._requestFullscreen():this._exitFullscreen(),e||this._setOption("fullWindow",c)}break;case "fullWindow":this.options[a]!==c&&(this._removeUiClass(),this.options[a]=c,this._refreshSize());break;case "size":this.options.fullWindow||this.options[a].cssClass===c.cssClass||this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "sizeFull":this.options.fullWindow&&
     87this.options[a].cssClass!==c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "autohide":this.options[a]=b.extend({},this.options[a],c);this._updateAutohide();break;case "loop":this._loop(c);break;case "nativeVideoControls":this.options[a]=b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this._restrictNativeVideoControls();this._updateNativeVideoControls();break;case "noFullWindow":this.options[a]=
     88b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullWindow=this._uaBlocklist(this.options.noFullWindow);this._restrictNativeVideoControls();this._updateButtons();break;case "noVolume":this.options[a]=b.extend({},this.options[a],c);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._updateVolume();this._updateMute();break;case "emulateHtml":this.options[a]!==c&&((this.options[a]=c)?this._emulateHtmlBridge():
     89this._destroyHtmlBridge());break;case "timeFormat":this.options[a]=b.extend({},this.options[a],c);break;case "keyEnabled":this.options[a]=c;c||this!==b.jPlayer.focus||(b.jPlayer.focus=null);break;case "keyBindings":this.options[a]=b.extend(!0,{},this.options[a],c);break;case "audioFullScreen":this.options[a]=c}return this},_refreshSize:function(){this._setSize();this._addUiClass();this._updateSize();this._updateButtons();this._updateAutohide();this._trigger(b.jPlayer.event.resize)},_setSize:function(){this.options.fullWindow?
     90(this.status.width=this.options.sizeFull.width,this.status.height=this.options.sizeFull.height,this.status.cssClass=this.options.sizeFull.cssClass):(this.status.width=this.options.size.width,this.status.height=this.options.size.height,this.status.cssClass=this.options.size.cssClass);this.element.css({width:this.status.width,height:this.status.height})},_addUiClass:function(){this.ancestorJq.length&&this.ancestorJq.addClass(this.status.cssClass)},_removeUiClass:function(){this.ancestorJq.length&&this.ancestorJq.removeClass(this.status.cssClass)},
     91_updateSize:function(){this.internal.poster.jq.css({width:this.status.width,height:this.status.height});!this.status.waitForPlay&&this.html.active&&this.status.video||this.html.video.available&&this.html.used&&this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):!this.status.waitForPlay&&this.flash.active&&this.status.video&&this.internal.flash.jq.css({width:this.status.width,height:this.status.height})},_updateAutohide:function(){var a=this,
     92c=function(){a.css.jq.gui.fadeIn(a.options.autohide.fadeIn,function(){clearTimeout(a.internal.autohideId);a.internal.autohideId=setTimeout(function(){a.css.jq.gui.fadeOut(a.options.autohide.fadeOut)},a.options.autohide.hold)})};this.css.jq.gui.length&&(this.css.jq.gui.stop(!0,!0),clearTimeout(this.internal.autohideId),this.element.unbind(".jPlayerAutohide"),this.css.jq.gui.unbind(".jPlayerAutohide"),this.status.nativeVideoControls?this.css.jq.gui.hide():this.options.fullWindow&&this.options.autohide.full||
     93!this.options.fullWindow&&this.options.autohide.restored?(this.element.bind("mousemove.jPlayer.jPlayerAutohide",c),this.css.jq.gui.bind("mousemove.jPlayer.jPlayerAutohide",c),this.css.jq.gui.hide()):this.css.jq.gui.show())},fullScreen:function(){this._setOption("fullScreen",!0)},restoreScreen:function(){this._setOption("fullScreen",!1)},_fullscreenAddEventListeners:function(){var a=this,c=b.jPlayer.nativeFeatures.fullscreen;c.api.fullscreenEnabled&&c.event.fullscreenchange&&("function"!==typeof this.internal.fullscreenchangeHandler&&
     94(this.internal.fullscreenchangeHandler=function(){a._fullscreenchange()}),document.addEventListener(c.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1))},_fullscreenRemoveEventListeners:function(){var a=b.jPlayer.nativeFeatures.fullscreen;this.internal.fullscreenchangeHandler&&document.addEventListener(a.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1)},_fullscreenchange:function(){this.options.fullScreen&&!b.jPlayer.nativeFeatures.fullscreen.api.fullscreenElement()&&
     95this._setOption("fullScreen",!1)},_requestFullscreen:function(){var a=this.ancestorJq.length?this.ancestorJq[0]:this.element[0],c=b.jPlayer.nativeFeatures.fullscreen;c.used.webkitVideo&&(a=this.htmlElement.video);c.api.fullscreenEnabled&&c.api.requestFullscreen(a)},_exitFullscreen:function(){var a=b.jPlayer.nativeFeatures.fullscreen,c;a.used.webkitVideo&&(c=this.htmlElement.video);a.api.fullscreenEnabled&&a.api.exitFullscreen(c)},_html_initMedia:function(a){var c=b(this.htmlElement.media).empty();
     96b.each(a.track||[],function(a,b){var g=document.createElement("track");g.setAttribute("kind",b.kind?b.kind:"");g.setAttribute("src",b.src?b.src:"");g.setAttribute("srclang",b.srclang?b.srclang:"");g.setAttribute("label",b.label?b.label:"");b.def&&g.setAttribute("default",b.def);c.append(g)});this.htmlElement.media.src=this.status.src;"none"!==this.options.preload&&this._html_load();this._trigger(b.jPlayer.event.timeupdate)},_html_setFormat:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&&
     97a[e])return c.status.src=a[e],c.status.format[e]=!0,c.status.formatType=e,!1})},_html_setAudio:function(a){this._html_setFormat(a);this.htmlElement.media=this.htmlElement.audio;this._html_initMedia(a)},_html_setVideo:function(a){this._html_setFormat(a);this.status.nativeVideoControls&&(this.htmlElement.video.poster=this._validString(a.poster)?a.poster:"");this.htmlElement.media=this.htmlElement.video;this._html_initMedia(a)},_html_resetMedia:function(){this.htmlElement.media&&(this.htmlElement.media.id!==
     98this.internal.video.id||this.status.nativeVideoControls||this.internal.video.jq.css({width:"0px",height:"0px"}),this.htmlElement.media.pause())},_html_clearMedia:function(){this.htmlElement.media&&(this.htmlElement.media.src="about:blank",this.htmlElement.media.load())},_html_load:function(){this.status.waitForLoad&&(this.status.waitForLoad=!1,this.htmlElement.media.load());clearTimeout(this.internal.htmlDlyCmdId)},_html_play:function(a){var b=this,d=this.htmlElement.media;this._html_load();if(isNaN(a))d.play();
     99else{this.internal.cmdsIgnored&&d.play();try{if(!d.seekable||"object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a,d.play();else throw 1;}catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.play(a)},250);return}}this._html_checkWaitForPlay()},_html_pause:function(a){var b=this,d=this.htmlElement.media;0<a?this._html_load():clearTimeout(this.internal.htmlDlyCmdId);d.pause();if(!isNaN(a))try{if(!d.seekable||"object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a;else throw 1;
     100}catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.pause(a)},250);return}0<a&&this._html_checkWaitForPlay()},_html_playHead:function(a){var b=this,d=this.htmlElement.media;this._html_load();try{if("object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a*d.seekable.end(d.seekable.length-1)/100;else if(0<d.duration&&!isNaN(d.duration))d.currentTime=a*d.duration/100;else throw"e";}catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.playHead(a)},250);return}this.status.waitForLoad||
     101this._html_checkWaitForPlay()},_html_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})))},_html_setProperty:function(a,b){this.html.audio.available&&(this.htmlElement.audio[a]=b);this.html.video.available&&(this.htmlElement.video[a]=b)},_flash_setAudio:function(a){var c=this;try{b.each(this.formats,
     102function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4a":case "fla":c._getMovie().fl_setAudio_m4a(a[d]);break;case "mp3":c._getMovie().fl_setAudio_mp3(a[d]);break;case "rtmpa":c._getMovie().fl_setAudio_rtmp(a[d])}c.status.src=a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_setVideo:function(a){var c=this;try{b.each(this.formats,function(b,d){if(c.flash.support[d]&&
     103a[d]){switch(d){case "m4v":case "flv":c._getMovie().fl_setVideo_m4v(a[d]);break;case "rtmpv":c._getMovie().fl_setVideo_rtmp(a[d])}c.status.src=a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_resetMedia:function(){this.internal.flash.jq.css({width:"0px",height:"0px"});this._flash_pause(NaN)},_flash_clearMedia:function(){try{this._getMovie().fl_clearMedia()}catch(a){this._flashError(a)}},
     104_flash_load:function(){try{this._getMovie().fl_load()}catch(a){this._flashError(a)}this.status.waitForLoad=!1},_flash_play:function(a){try{this._getMovie().fl_play(a)}catch(b){this._flashError(b)}this.status.waitForLoad=!1;this._flash_checkWaitForPlay()},_flash_pause:function(a){try{this._getMovie().fl_pause(a)}catch(b){this._flashError(b)}0<a&&(this.status.waitForLoad=!1,this._flash_checkWaitForPlay())},_flash_playHead:function(a){try{this._getMovie().fl_play_head(a)}catch(b){this._flashError(b)}this.status.waitForLoad||
     105this._flash_checkWaitForPlay()},_flash_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.flash.jq.css({width:this.status.width,height:this.status.height})))},_flash_volume:function(a){try{this._getMovie().fl_volume(a)}catch(b){this._flashError(b)}},_flash_mute:function(a){try{this._getMovie().fl_mute(a)}catch(b){this._flashError(b)}},_getMovie:function(){return document[this.internal.flash.id]},
     106_getFlashPluginVersion:function(){var a=0,b;if(window.ActiveXObject)try{if(b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")){var d=b.GetVariable("$version");d&&(d=d.split(" ")[1].split(","),a=parseInt(d[0],10)+"."+parseInt(d[1],10))}}catch(e){}else navigator.plugins&&0<navigator.mimeTypes.length&&(b=navigator.plugins["Shockwave Flash"])&&(a=navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/,"$1"));return 1*a},_checkForFlash:function(a){var b=!1;this._getFlashPluginVersion()>=
     107a&&(b=!0);return b},_validString:function(a){return a&&"string"===typeof a},_limitValue:function(a,b,d){return a<b?b:a>d?d:a},_urlNotSetError:function(a){this._error({type:b.jPlayer.error.URL_NOT_SET,context:a,message:b.jPlayer.errorMsg.URL_NOT_SET,hint:b.jPlayer.errorHint.URL_NOT_SET})},_flashError:function(a){var c;c=this.internal.ready?"FLASH_DISABLED":"FLASH";this._error({type:b.jPlayer.error[c],context:this.internal.flash.swf,message:b.jPlayer.errorMsg[c]+a.message,hint:b.jPlayer.errorHint[c]});
     108this.internal.flash.jq.css({width:"1px",height:"1px"})},_error:function(a){this._trigger(b.jPlayer.event.error,a);this.options.errorAlerts&&this._alert("Error!"+(a.message?"\n"+a.message:"")+(a.hint?"\n"+a.hint:"")+"\nContext: "+a.context)},_warning:function(a){this._trigger(b.jPlayer.event.warning,f,a);this.options.warningAlerts&&this._alert("Warning!"+(a.message?"\n"+a.message:"")+(a.hint?"\n"+a.hint:"")+"\nContext: "+a.context)},_alert:function(a){a="jPlayer "+this.version.script+" : id='"+this.internal.self.id+
     109"' : "+a;this.options.consoleAlerts?console&&console.log&&console.log(a):alert(a)},_emulateHtmlBridge:function(){var a=this;b.each(b.jPlayer.emulateMethods.split(/\s+/g),function(b,d){a.internal.domNode[d]=function(b){a[d](b)}});b.each(b.jPlayer.event,function(c,d){var e=!0;b.each(b.jPlayer.reservedEvent.split(/\s+/g),function(a,b){if(b===c)return e=!1});e&&a.element.bind(d+".jPlayer.jPlayerHtml",function(){a._emulateHtmlUpdate();var b=document.createEvent("Event");b.initEvent(c,!1,!0);a.internal.domNode.dispatchEvent(b)})})},
     110_emulateHtmlUpdate:function(){var a=this;b.each(b.jPlayer.emulateStatus.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.status[d]});b.each(b.jPlayer.emulateOptions.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.options[d]})},_destroyHtmlBridge:function(){var a=this;this.element.unbind(".jPlayerHtml");b.each((b.jPlayer.emulateMethods+" "+b.jPlayer.emulateStatus+" "+b.jPlayer.emulateOptions).split(/\s+/g),function(b,d){delete a.internal.domNode[d]})}};b.jPlayer.error={FLASH:"e_flash",FLASH_DISABLED:"e_flash_disabled",
     111NO_SOLUTION:"e_no_solution",NO_SUPPORT:"e_no_support",URL:"e_url",URL_NOT_SET:"e_url_not_set",VERSION:"e_version"};b.jPlayer.errorMsg={FLASH:"jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ",FLASH_DISABLED:"jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ",NO_SOLUTION:"No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.",NO_SUPPORT:"It is not possible to play any media format provided in setMedia() on this browser using your current options.",
     112URL:"Media URL could not be loaded.",URL_NOT_SET:"Attempt to issue media playback commands, while no media url is set.",VERSION:"jPlayer "+b.jPlayer.prototype.version.script+" needs Jplayer.swf version "+b.jPlayer.prototype.version.needFlash+" but found "};b.jPlayer.errorHint={FLASH:"Check your swfPath option and that Jplayer.swf is there.",FLASH_DISABLED:"Check that you have not display:none; the jPlayer entity or any ancestor.",NO_SOLUTION:"Review the jPlayer options: support and supplied.",NO_SUPPORT:"Video or audio formats defined in the supplied option are missing.",
     113URL:"Check media URL is valid.",URL_NOT_SET:"Use setMedia() to set the media URL.",VERSION:"Update jPlayer files."};b.jPlayer.warning={CSS_SELECTOR_COUNT:"e_css_selector_count",CSS_SELECTOR_METHOD:"e_css_selector_method",CSS_SELECTOR_STRING:"e_css_selector_string",OPTION_KEY:"e_option_key"};b.jPlayer.warningMsg={CSS_SELECTOR_COUNT:"The number of css selectors found did not equal one: ",CSS_SELECTOR_METHOD:"The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",CSS_SELECTOR_STRING:"The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",
     114OPTION_KEY:"The option requested in jPlayer('option') is undefined."};b.jPlayer.warningHint={CSS_SELECTOR_COUNT:"Check your css selector and the ancestor.",CSS_SELECTOR_METHOD:"Check your method name.",CSS_SELECTOR_STRING:"Check your css selector is a string.",OPTION_KEY:"Check your option name."}});
Note: See TracChangeset for help on using the changeset viewer.