o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1388436815.4900632: @value"ñ {I" class:EFI"BundledAsset;FI"logical_path;FI" wafflemix/admin/admin_js.js;TI" pathname;FI"V/Users/jrissler/code/wafflemix/app/assets/javascripts/wafflemix/admin/admin_js.js;FI"content_type;FI"application/javascript;FI" mtime;FI"2013-12-30T15:53:27-05:00;FI" length;Fi  I" digest;F"%fd3ebace8aee27b1142685885b2c3338I" source;FI"  /*! * jQuery JavaScript Library v1.9.1 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2013-2-4 */ (function( window, undefined ) { // Can't do this because several apps including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) // Support: Firefox 18+ //"use strict"; var // The deferred used on DOM ready readyList, // A central reference to the root jQuery(document) rootjQuery, // Support: IE<9 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, // Use the correct document accordingly with window argument (sandbox) document = window.document, location = window.location, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, // [[Class]] -> type pairs class2type = {}, // List of deleted data cache ids, so we can reuse them core_deletedIds = [], core_version = "1.9.1", // Save a reference to some core methods core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim, // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, // Used for matching numbers core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, // Used for splitting on whitespace core_rnotwhite = /\S+/g, // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, // JSON RegExp rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { return letter.toUpperCase(); }, // The ready event handler completed = function( event ) { // readyState === "complete" is good enough for us to call the dom ready in oldIE if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { detach(); jQuery.ready(); } }, // Clean-up method for dom ready events detach = function() { if ( document.addEventListener ) { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); } else { document.detachEvent( "onreadystatechange", completed ); window.detachEvent( "onload", completed ); } }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: core_version, constructor: jQuery, init: function( selector, context, rootjQuery ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Handle HTML strings if ( typeof selector === "string" ) { if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; // scripts is true for back-compat jQuery.merge( this, jQuery.parseHTML( match[1], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[2] ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } // Otherwise, we inject the element directly into the jQuery object this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } if ( selector.selector !== undefined ) { this.selector = selector.selector; this.context = selector.context; } return jQuery.makeArray( selector, this ); }, // Start with an empty selector selector: "", // The default length of a jQuery object is 0 length: 0, // The number of elements contained in the matched element set size: function() { return this.length; }, toArray: function() { return core_slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { return num == null ? // Return a 'clean' array this.toArray() : // Return just the object ( num < 0 ? this[ this.length + num ] : this[ num ] ); }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. // (You can seed the arguments with an array of args, but this is // only used internally.) each: function( callback, args ) { return jQuery.each( this, callback, args ); }, ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; }, slice: function() { return this.pushStack( core_slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); }, map: function( callback ) { return this.pushStack( jQuery.map(this, function( elem, i ) { return callback.call( elem, i, elem ); })); }, end: function() { return this.prevObject || this.constructor(null); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: core_push, sort: [].sort, splice: [].splice }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend({ noConflict: function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; }, // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready ); } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); // Trigger any bound ready events if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); } }, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return jQuery.type(obj) === "function"; }, isArray: Array.isArray || function( obj ) { return jQuery.type(obj) === "array"; }, isWindow: function( obj ) { return obj != null && obj == obj.window; }, isNumeric: function( obj ) { return !isNaN( parseFloat(obj) ) && isFinite( obj ); }, type: function( obj ) { if ( obj == null ) { return String( obj ); } return typeof obj === "object" || typeof obj === "function" ? class2type[ core_toString.call(obj) ] || "object" : typeof obj; }, isPlainObject: function( obj ) { // Must be an Object. // Because of IE, we also have to check the presence of the constructor property. // Make sure that DOM nodes and window objects don't pass through, as well if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { return false; } try { // Not own constructor property must be Object if ( obj.constructor && !core_hasOwn.call(obj, "constructor") && !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } } catch ( e ) { // IE8,9 Will throw exceptions on certain host objects #9897 return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for ( key in obj ) {} return key === undefined || core_hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { var name; for ( name in obj ) { return false; } return true; }, error: function( msg ) { throw new Error( msg ); }, // data: string of html // context (optional): If specified, the fragment will be created in this context, defaults to document // keepScripts (optional): If true, will include scripts passed in the html string parseHTML: function( data, context, keepScripts ) { if ( !data || typeof data !== "string" ) { return null; } if ( typeof context === "boolean" ) { keepScripts = context; context = false; } context = context || document; var parsed = rsingleTag.exec( data ), scripts = !keepScripts && []; // Single tag if ( parsed ) { return [ context.createElement( parsed[1] ) ]; } parsed = jQuery.buildFragment( [ data ], context, scripts ); if ( scripts ) { jQuery( scripts ).remove(); } return jQuery.merge( [], parsed.childNodes ); }, parseJSON: function( data ) { // Attempt to parse using the native JSON parser first if ( window.JSON && window.JSON.parse ) { return window.JSON.parse( data ); } if ( data === null ) { return data; } if ( typeof data === "string" ) { // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); if ( data ) { // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js if ( rvalidchars.test( data.replace( rvalidescape, "@" ) .replace( rvalidtokens, "]" ) .replace( rvalidbraces, "")) ) { return ( new Function( "return " + data ) )(); } } } jQuery.error( "Invalid JSON: " + data ); }, // Cross-browser xml parsing parseXML: function( data ) { var xml, tmp; if ( !data || typeof data !== "string" ) { return null; } try { if ( window.DOMParser ) { // Standard tmp = new DOMParser(); xml = tmp.parseFromString( data , "text/xml" ); } else { // IE xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = "false"; xml.loadXML( data ); } } catch( e ) { xml = undefined; } if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }, noop: function() {}, // Evaluates a script in a global context // Workarounds based on findings by Jim Driscoll // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context globalEval: function( data ) { if ( data && jQuery.trim( data ) ) { // We use execScript on Internet Explorer // We use an anonymous function so that context is window // rather than jQuery in Firefox ( window.execScript || function( data ) { window[ "eval" ].call( window, data ); } )( data ); } }, // Convert dashed to camelCase; used by the css and data modules // Microsoft forgot to hump their vendor prefix (#9572) camelCase: function( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); }, nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, // args is for internal usage only each: function( obj, callback, args ) { var value, i = 0, length = obj.length, isArray = isArraylike( obj ); if ( args ) { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } // A special, fast, case for the most common use of each } else { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } } return obj; }, // Use native String.trim function wherever possible trim: core_trim && !core_trim.call("\uFEFF\xA0") ? function( text ) { return text == null ? "" : core_trim.call( text ); } : // Otherwise use our own trimming functionality function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArraylike( Object(arr) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { core_push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { var len; if ( arr ) { if ( core_indexOf ) { return core_indexOf.call( arr, elem, i ); } len = arr.length; i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; for ( ; i < len; i++ ) { // Skip accessing in sparse arrays if ( i in arr && arr[ i ] === elem ) { return i; } } } return -1; }, merge: function( first, second ) { var l = second.length, i = first.length, j = 0; if ( typeof l === "number" ) { for ( ; j < l; j++ ) { first[ i++ ] = second[ j ]; } } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } } first.length = i; return first; }, grep: function( elems, callback, inv ) { var retVal, ret = [], i = 0, length = elems.length; inv = !!inv; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { retVal = !!callback( elems[ i ], i ); if ( inv !== retVal ) { ret.push( elems[ i ] ); } } return ret; }, // arg is for internal usage only map: function( elems, callback, arg ) { var value, i = 0, length = elems.length, isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their if ( isArray ) { for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } } // Flatten any nested arrays return core_concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { var args, proxy, tmp; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !jQuery.isFunction( fn ) ) { return undefined; } // Simulated bind args = core_slice.call( arguments, 2 ); proxy = function() { return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }, // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function access: function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, length = elems.length, bulk = key == null; // Sets many values if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !jQuery.isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < length; i++ ) { fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); } } } return chainable ? elems : // Gets bulk ? fn.call( elems ) : length ? fn( elems[0], key ) : emptyGet; }, now: function() { return ( new Date() ).getTime(); } }); jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready ); // Standards-based browsers support DOMContentLoaded } else if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed, false ); // If IE event model is used } else { // Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // detach all dom ready events detach(); // and execute any waiting functions jQuery.ready(); } })(); } } } return readyList.promise( obj ); }; // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); }); function isArraylike( obj ) { var length = obj.length, type = jQuery.type( obj ); if ( jQuery.isWindow( obj ) ) { return false; } if ( obj.nodeType === 1 && length ) { return true; } return type === "array" || type !== "function" && ( length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj ); } // All jQuery objects should point back to these rootjQuery = jQuery(document); // String to Object options format cache var optionsCache = {}; // Convert String-formatted options into Object-formatted ones and store in cache function createOptions( options ) { var object = optionsCache[ options ] = {}; jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { object[ flag ] = true; }); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? ( optionsCache[ options ] || createOptions( options ) ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired fired, // End of the loop when firing firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, // First callback to fire (used internally by add and fireWith) firingStart, // Actual callback list list = [], // Stack of fire calls for repeatable lists stack = !options.once && [], // Fire callbacks fire = function( data ) { memory = options.memory && data; fired = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; firing = true; for ( ; list && firingIndex < firingLength; firingIndex++ ) { if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { memory = false; // To prevent further calls using add break; } } firing = false; if ( list ) { if ( stack ) { if ( stack.length ) { fire( stack.shift() ); } } else if ( memory ) { list = []; } else { self.disable(); } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // First, we save the current length var start = list.length; (function add( args ) { jQuery.each( args, function( _, arg ) { var type = jQuery.type( arg ); if ( type === "function" ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && type !== "string" ) { // Inspect recursively add( arg ); } }); })( arguments ); // Do we need to add the callbacks to the // current firing batch? if ( firing ) { firingLength = list.length; // With memory, if we're not firing then // we should call right away } else if ( memory ) { firingStart = start; fire( memory ); } } return this; }, // Remove a callback from the list remove: function() { if ( list ) { jQuery.each( arguments, function( _, arg ) { var index; while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( firing ) { if ( index <= firingLength ) { firingLength--; } if ( index <= firingIndex ) { firingIndex--; } } } }); } return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); }, // Remove all callbacks from the list empty: function() { list = []; return this; }, // Have the list do nothing anymore disable: function() { list = stack = memory = undefined; return this; }, // Is it disabled? disabled: function() { return !list; }, // Lock the list in its current state lock: function() { stack = undefined; if ( !memory ) { self.disable(); } return this; }, // Is it locked? locked: function() { return !stack; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; if ( list && ( !fired || stack ) ) { if ( firing ) { stack.push( args ); } else { fire( args ); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; jQuery.extend({ Deferred: function( func ) { var tuples = [ // action, add listener, listener list, final state [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Keep pipe for back-compat promise.pipe = promise.then; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 3 ]; // promise[ done | fail | progress ] = list.add promise[ tuple[1] ] = list.add; // Handle state if ( stateString ) { list.add(function() { // state = [ resolved | rejected ] state = stateString; // [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); } // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; }); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( subordinate /* , ..., subordinateN */ ) { var i = 0, resolveValues = core_slice.call( arguments ), length = resolveValues.length, // the count of uncompleted subordinates remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values updateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; if( values === progressValues ) { deferred.notifyWith( contexts, values ); } else if ( !( --remaining ) ) { deferred.resolveWith( contexts, values ); } }; }, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { progressValues = new Array( length ); progressContexts = new Array( length ); resolveContexts = new Array( length ); for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise() .done( updateFunc( i, resolveContexts, resolveValues ) ) .fail( deferred.reject ) .progress( updateFunc( i, progressContexts, progressValues ) ); } else { --remaining; } } } // if we're not waiting on anything, resolve the master if ( !remaining ) { deferred.resolveWith( resolveContexts, resolveValues ); } return deferred.promise(); } }); jQuery.support = (function() { var support, all, a, input, select, fragment, opt, eventName, isSupported, i, div = document.createElement("div"); // Setup div.setAttribute( "className", "t" ); div.innerHTML = "
a"; // Support tests won't run in some limited or non-browser environments all = div.getElementsByTagName("*"); a = div.getElementsByTagName("a")[ 0 ]; if ( !all || !a || !all.length ) { return {}; } // First batch of tests select = document.createElement("select"); opt = select.appendChild( document.createElement("option") ); input = div.getElementsByTagName("input")[ 0 ]; a.style.cssText = "top:1px;float:left;opacity:.5"; support = { // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", // IE strips leading whitespace when .innerHTML is used leadingWhitespace: div.firstChild.nodeType === 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: a.getAttribute("href") === "/a", // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 opacity: /^0.5/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) checkOn: !!input.value, // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, // Tests for enctype support on a form (#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode boxModel: document.compatMode === "CSS1Compat", // Will be defined later deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, boxSizingReliable: true, pixelPosition: false }; // Make sure checked status is properly cloned input.checked = true; support.noCloneChecked = input.cloneNode( true ).checked; // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as disabled) select.disabled = true; support.optDisabled = !opt.disabled; // Support: IE<9 try { delete div.test; } catch( e ) { support.deleteExpando = false; } // Check if we can trust getAttribute("value") input = document.createElement("input"); input.setAttribute( "value", "" ); support.input = input.getAttribute( "value" ) === ""; // Check if an input maintains its value after becoming a radio input.value = "t"; input.setAttribute( "type", "radio" ); support.radioValue = input.value === "t"; // #11217 - WebKit loses check when the name is after the checked attribute input.setAttribute( "checked", "t" ); input.setAttribute( "name", "t" ); fragment = document.createDocumentFragment(); fragment.appendChild( input ); // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; // WebKit doesn't clone checked state correctly in fragments support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE<9 // Opera does not clone events (and typeof div.attachEvent === undefined). // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() if ( div.attachEvent ) { div.attachEvent( "onclick", function() { support.noCloneEvent = false; }); div.cloneNode( true ).click(); } // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php for ( i in { submit: true, change: true, focusin: true }) { div.setAttribute( eventName = "on" + i, "t" ); support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; } div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; // Run tests that need a body at doc ready jQuery(function() { var container, marginDiv, tds, divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", body = document.getElementsByTagName("body")[0]; if ( !body ) { // Return for frameset docs that don't have a body return; } container = document.createElement("div"); container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; body.appendChild( container ).appendChild( div ); // Support: IE8 // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). div.innerHTML = "
t
"; tds = div.getElementsByTagName("td"); tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; isSupported = ( tds[ 0 ].offsetHeight === 0 ); tds[ 0 ].style.display = ""; tds[ 1 ].style.display = "none"; // Support: IE8 // Check if empty table cells still have offsetWidth/Height support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); // Check box-sizing and margin behavior div.innerHTML = ""; div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); // Use window.getComputedStyle because jsdom on node.js will break without it. if ( window.getComputedStyle ) { support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. (#3333) // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right marginDiv = div.appendChild( document.createElement("div") ); marginDiv.style.cssText = div.style.cssText = divReset; marginDiv.style.marginRight = marginDiv.style.width = "0"; div.style.width = "1px"; support.reliableMarginRight = !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); } if ( typeof div.style.zoom !== core_strundefined ) { // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout div.innerHTML = ""; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Support: IE6 // Check if elements with layout shrink-wrap their children div.style.display = "block"; div.innerHTML = "
"; div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); if ( support.inlineBlockNeedsLayout ) { // Prevent IE 6 from affecting layout for positioned elements #11048 // Prevent IE from shrinking the body in IE 7 mode #12869 // Support: IE<8 body.style.zoom = 1; } } body.removeChild( container ); // Null elements to avoid leaks in IE container = div = tds = marginDiv = null; }); // Null elements to avoid leaks in IE all = select = fragment = opt = a = input = null; return support; })(); var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; function internalData( elem, name, data, pvt /* Internal Use Only */ ){ if ( !jQuery.acceptData( elem ) ) { return; } var thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", // We have to handle DOM nodes and JS objects differently because IE6-7 // can't GC object references properly across the DOM-JS boundary isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is // attached directly to the object so GC can occur automatically cache = isNode ? jQuery.cache : elem, // Only defining an ID for JS objects if its cache already exists allows // the code to shortcut on the same path as a DOM node with no cache id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; // Avoid doing any more work than we need to when trying to get data on an // object that has no data at all if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { return; } if ( !id ) { // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } } if ( !cache[ id ] ) { cache[ id ] = {}; // Avoids exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify if ( !isNode ) { cache[ id ].toJSON = jQuery.noop; } } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache if ( typeof name === "object" || typeof name === "function" ) { if ( pvt ) { cache[ id ] = jQuery.extend( cache[ id ], name ); } else { cache[ id ].data = jQuery.extend( cache[ id ].data, name ); } } thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data // cache in order to avoid key collisions between internal data and user-defined // data. if ( !pvt ) { if ( !thisCache.data ) { thisCache.data = {}; } thisCache = thisCache.data; } if ( data !== undefined ) { thisCache[ jQuery.camelCase( name ) ] = data; } // Check for both converted-to-camel and non-converted data property names // If a data property was specified if ( getByName ) { // First Try to find as-is property data ret = thisCache[ name ]; // Test for null|undefined property data if ( ret == null ) { // Try to find the camelCased property ret = thisCache[ jQuery.camelCase( name ) ]; } } else { ret = thisCache; } return ret; } function internalRemoveData( elem, name, pvt ) { if ( !jQuery.acceptData( elem ) ) { return; } var i, l, thisCache, isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, id = isNode ? elem[ jQuery.expando ] : jQuery.expando; // If there is already no cache entry for this object, there is no // purpose in continuing if ( !cache[ id ] ) { return; } if ( name ) { thisCache = pvt ? cache[ id ] : cache[ id ].data; if ( thisCache ) { // Support array or space separated string names for data keys if ( !jQuery.isArray( name ) ) { // try the string as a key before any manipulation if ( name in thisCache ) { name = [ name ]; } else { // split the camel cased version by spaces unless a key with the spaces exists name = jQuery.camelCase( name ); if ( name in thisCache ) { name = [ name ]; } else { name = name.split(" "); } } } else { // If "name" is an array of keys... // When data is initially created, via ("key", "val") signature, // keys will be converted to camelCase. // Since there is no way to tell _how_ a key was added, remove // both plain key and camelCase key. #12786 // This will only penalize the array argument path. name = name.concat( jQuery.map( name, jQuery.camelCase ) ); } for ( i = 0, l = name.length; i < l; i++ ) { delete thisCache[ name[i] ]; } // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { return; } } } // See jQuery.data for more information if ( !pvt ) { delete cache[ id ].data; // Don't destroy the parent cache unless the internal data object // had been the only thing left in it if ( !isEmptyDataObject( cache[ id ] ) ) { return; } } // Destroy the cache if ( isNode ) { jQuery.cleanData( [ elem ], true ); // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) } else if ( jQuery.support.deleteExpando || cache != cache.window ) { delete cache[ id ]; // When all else fails, null } else { cache[ id ] = null; } } jQuery.extend({ cache: {}, // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data ) { return internalData( elem, name, data ); }, removeData: function( elem, name ) { return internalRemoveData( elem, name ); }, // For internal use only. _data: function( elem, name, data ) { return internalData( elem, name, data, true ); }, _removeData: function( elem, name ) { return internalRemoveData( elem, name, true ); }, // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { // Do not set data on non-element because it will not be cleared (#8335). if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { return false; } var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; // nodes accept data unless otherwise specified; rejection can be conditional return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); jQuery.fn.extend({ data: function( key, value ) { var attrs, name, elem = this[0], i = 0, data = null; // Gets all values if ( key === undefined ) { if ( this.length ) { data = jQuery.data( elem ); if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { attrs = elem.attributes; for ( ; i < attrs.length; i++ ) { name = attrs[i].name; if ( !name.indexOf( "data-" ) ) { name = jQuery.camelCase( name.slice(5) ); dataAttr( elem, name, data[ name ] ); } } jQuery._data( elem, "parsedAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } return jQuery.access( this, function( value ) { if ( value === undefined ) { // Try to fetch any internally stored data first return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; } this.each(function() { jQuery.data( this, key, value ); }); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each(function() { jQuery.removeData( this, key ); }); } }); function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : // Only convert to a number if it doesn't change the string +data + "" === data ? +data : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; } catch( e ) {} // Make sure we set the data so it isn't changed later jQuery.data( elem, key, data ); } else { data = undefined; } } return data; } // checks a cache object for emptiness function isEmptyDataObject( obj ) { var name; for ( name in obj ) { // if the public data object is empty, the private is still empty if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { continue; } if ( name !== "toJSON" ) { return false; } } return true; } jQuery.extend({ queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = jQuery._data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray(data) ) { queue = jQuery._data( elem, type, jQuery.makeArray(data) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } hooks.cur = fn; if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // not intended for public consumption - generates a queueHooks object, or returns the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return jQuery._data( elem, key ) || jQuery._data( elem, key, { empty: jQuery.Callbacks("once memory").add(function() { jQuery._removeData( elem, type + "queue" ); jQuery._removeData( elem, key ); }) }); } }); jQuery.fn.extend({ queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); } return data === undefined ? this : this.each(function() { var queue = jQuery.queue( this, type, data ); // ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[0] !== "inprogress" ) { jQuery.dequeue( this, type ); } }); }, dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); }, // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = setTimeout( next, time ); hooks.stop = function() { clearTimeout( timeout ); }; }); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while( i-- ) { tmp = jQuery._data( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } }); var nodeHook, boolHook, rclass = /[\t\r\n]/g, rreturn = /\r/g, rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i, rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, ruseDefault = /^(?:checked|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, getSetInput = jQuery.support.input; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each(function() { jQuery.removeAttr( this, name ); }); }, prop: function( name, value ) { return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, addClass: function( value ) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).addClass( value.call( this, j, this.className ) ); }); } if ( proceed ) { // The disjunction here is for better compressibility (see removeClass) classes = ( value || "" ).match( core_rnotwhite ) || []; for ( ; i < len; i++ ) { elem = this[ i ]; cur = elem.nodeType === 1 && ( elem.className ? ( " " + elem.className + " " ).replace( rclass, " " ) : " " ); if ( cur ) { j = 0; while ( (clazz = classes[j++]) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } elem.className = jQuery.trim( cur ); } } } return this; }, removeClass: function( value ) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = arguments.length === 0 || typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).removeClass( value.call( this, j, this.className ) ); }); } if ( proceed ) { classes = ( value || "" ).match( core_rnotwhite ) || []; for ( ; i < len; i++ ) { elem = this[ i ]; // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( elem.className ? ( " " + elem.className + " " ).replace( rclass, " " ) : "" ); if ( cur ) { j = 0; while ( (clazz = classes[j++]) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { cur = cur.replace( " " + clazz + " ", " " ); } } elem.className = value ? jQuery.trim( cur ) : ""; } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { return this.each(function( i ) { jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); }); } return this.each(function() { if ( type === "string" ) { // toggle individual class names var className, i = 0, self = jQuery( this ), state = stateVal, classNames = value.match( core_rnotwhite ) || []; while ( (className = classNames[ i++ ]) ) { // check each className given, space separated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } // Toggle whole class name } else if ( type === core_strundefined || type === "boolean" ) { if ( this.className ) { // store className if set jQuery._data( this, "__className__", this.className ); } // If the element has a class name or if we're passed "false", // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; } }); }, hasClass: function( selector ) { var className = " " + selector + " ", i = 0, l = this.length; for ( ; i < l; i++ ) { if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { return true; } } return false; }, val: function( value ) { var ret, hooks, isFunction, elem = this[0]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { return ret; } ret = elem.value; return typeof ret === "string" ? // handle most common string cases ret.replace(rreturn, "") : // handle cases where value is null/undef or number ret == null ? "" : ret; } return; } isFunction = jQuery.isFunction( value ); return this.each(function( i ) { var val, self = jQuery(this); if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, self.val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( jQuery.isArray( val ) ) { val = jQuery.map(val, function ( value ) { return value == null ? "" : value + ""; }); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } }); } }); jQuery.extend({ valHooks: { option: { get: function( elem ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : elem.text; } }, select: { get: function( elem ) { var value, option, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one" || index < 0, values = one ? null : [], max = one ? index + 1 : options.length, i = index < 0 ? max : one ? index : 0; // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // oldIE doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var values = jQuery.makeArray( value ); jQuery(elem).find("option").each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { elem.selectedIndex = -1; } return values; } } }, attr: function( elem, name, value ) { var hooks, notxml, ret, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === core_strundefined ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, value + "" ); return value; } } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; } }, removeAttr: function( elem, value ) { var name, propName, i = 0, attrNames = value && value.match( core_rnotwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( (name = attrNames[i++]) ) { propName = jQuery.propFix[ name ] || name; // Boolean attributes get special treatment (#10870) if ( rboolean.test( name ) ) { // Set corresponding property to false for boolean attributes // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { elem[ propName ] = false; } // See #9699 for explanation of this approach (setting first, then removal) } else { jQuery.attr( elem, name, "" ); } elem.removeAttribute( getSetAttribute ? name : propName ); } } }, attrHooks: { type: { set: function( elem, value ) { if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to default in case type is set after value during creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, propFix: { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" }, prop: function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set properties on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } }, propHooks: { tabIndex: { get: function( elem ) { // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ var attributeNode = elem.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? parseInt( attributeNode.value, 10 ) : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } } } }); // Hook for boolean attributes boolHook = { get: function( elem, name ) { var // Use .prop to determine if this attribute is understood as boolean prop = jQuery.prop( elem, name ), // Fetch it accordingly attr = typeof prop === "boolean" && elem.getAttribute( name ), detail = typeof prop === "boolean" ? getSetInput && getSetAttribute ? attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ? elem[ jQuery.camelCase( "default-" + name ) ] : !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); return detail && detail.value !== false ? name.toLowerCase() : undefined; }, set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { // IE<8 needs the *property* name elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); // Use defaultChecked and defaultSelected for oldIE } else { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; } return name; } }; // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, set: function( elem, value, name ) { if ( jQuery.nodeName( elem, "input" ) ) { // Does not return so that setAttribute is also used elem.defaultValue = value; } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set( elem, value, name ); } } }; } // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute( name )) ); } ret.value = value += ""; // Break association with cloned elements by also using setAttribute (#9646) return name === "value" || value === elem.getAttribute( name ) ? value : undefined; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { nodeHook.set( elem, value === "" ? false : value, name ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); } // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // href/src property should get the full normalized URL (#10299/#12915) jQuery.each([ "href", "src" ], function( i, name ) { jQuery.propHooks[ name ] = { get: function( elem ) { return elem.getAttribute( name, 4 ); } }; }); } if ( !jQuery.support.style ) { jQuery.attrHooks.style = { get: function( elem ) { // Return undefined in the case of empty string // Note: IE uppercases css property names, but if we were to .toLowerCase() // .cssText, that would destroy case senstitivity in URL's, like in "background" return elem.style.cssText || undefined; }, set: function( elem, value ) { return ( elem.style.cssText = value + "" ); } }; } // Safari mis-reports the default selected property of an option // Accessing the parent's selectedIndex property fixes it if ( !jQuery.support.optSelected ) { jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { get: function( elem ) { var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; // Make sure that it also works with optgroups, see #5701 if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } return null; } }); } // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } // Radios and checkboxes getter/setter if ( !jQuery.support.checkOn ) { jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { get: function( elem ) { // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; } }; }); } jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); } } }); }); var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; function returnTrue() { return true; } function returnFalse() { return false; } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery._data( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !(events = elemData.events) ) { events = elemData.events = {}; } if ( !(eventHandle = elemData.handle) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem; } // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = ( types || "" ).match( core_rnotwhite ) || [""]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; type = origType = tmp[1]; namespaces = ( tmp[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join(".") }, handleObjIn ); // Init the event handler queue if we're the first if ( !(handlers = events[ type ]) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener/attachEvent if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { // Bind the global event handler to the element if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle, false ); } else if ( elem.attachEvent ) { elem.attachEvent( "on" + type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } // Nullify elem to prevent memory leaks in IE elem = null; }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( core_rnotwhite ) || [""]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; type = origType = tmp[1]; namespaces = ( tmp[2] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { delete elemData.handle; // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete jQuery._removeData( elem, "events" ); } }, trigger: function( event, data, elem, onlyHandlers ) { var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem || document ], type = core_hasOwn.call( event, "type" ) ? event.type : event, namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; cur = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf(".") >= 0 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); event.isTrigger = true; event.namespace = namespaces.join("."); event.namespace_re = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === (elem.ownerDocument || document) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; try { elem[ type ](); } catch ( e ) { // IE<9 dies on focus/blur to hidden element (#1486,#12518) // only reproducible on winXP IE8 native, not IE9 in IE8 mode } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, dispatch: function( event ) { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); var i, ret, handleObj, matched, j, handlerQueue = [], args = core_slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); if ( ret !== undefined ) { if ( (event.result = ret) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var sel, handleObj, matches, i, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers // Black-hole SVG instance trees (#13180) // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { for ( ; cur != this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matches[ sel ] === undefined ) { matches[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) >= 0 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matches[ sel ] ) { matches.push( handleObj ); } } if ( matches.length ) { handlerQueue.push({ elem: cur, handlers: matches }); } } } } // Add the remaining (directly-bound) handlers if ( delegateCount < handlers.length ) { handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); } return handlerQueue; }, fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; } // Create a writable copy of the event object and normalize some properties var i, prop, copy, type = event.type, originalEvent = event, fixHook = this.fixHooks[ type ]; if ( !fixHook ) { this.fixHooks[ type ] = fixHook = rmouseEvent.test( type ) ? this.mouseHooks : rkeyEvent.test( type ) ? this.keyHooks : {}; } copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; event = new jQuery.Event( originalEvent ); i = copy.length; while ( i-- ) { prop = copy[ i ]; event[ prop ] = originalEvent[ prop ]; } // Support: IE<9 // Fix target property (#1925) if ( !event.target ) { event.target = originalEvent.srcElement || document; } // Support: Chrome 23+, Safari? // Target should not be a text node (#504, #13143) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } // Support: IE<9 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) event.metaKey = !!event.metaKey; return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; }, // Includes some event props shared by KeyEvent and MouseEvent props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split(" "), filter: function( event, original ) { // Add which for key events if ( event.which == null ) { event.which = original.charCode != null ? original.charCode : original.keyCode; } return event; } }, mouseHooks: { props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function( event, original ) { var body, eventDoc, doc, button = original.button, fromElement = original.fromElement; // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && original.clientX != null ) { eventDoc = event.target.ownerDocument || document; doc = eventDoc.documentElement; body = eventDoc.body; event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); } // Add relatedTarget, if necessary if ( !event.relatedTarget && fromElement ) { event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; } // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if ( !event.which && button !== undefined ) { event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); } return event; } }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // For checkbox, fire native event so checked state will be right trigger: function() { if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { this.click(); return false; } } }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== document.activeElement && this.focus ) { try { this.focus(); return false; } catch ( e ) { // Support: IE<9 // If we error on focus to hidden element (#1486, #12518), // let .trigger() run the handlers } } }, delegateType: "focusin" }, blur: { trigger: function() { if ( this === document.activeElement && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, beforeunload: { postDispatch: function( event ) { // Even when returnValue equals to undefined Firefox will still show alert if ( event.result !== undefined ) { event.originalEvent.returnValue = event.result; } } } }, simulate: function( type, elem, event, bubble ) { // Piggyback on a donor event to simulate a different one. // Fake originalEvent to avoid donor's stopPropagation, but if the // simulated event prevents default then we do the same on the donor. var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true, originalEvent: {} } ); if ( bubble ) { jQuery.event.trigger( e, null, elem ); } else { jQuery.event.dispatch.call( elem, e ); } if ( e.isDefaultPrevented() ) { event.preventDefault(); } } }; jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { elem.removeEventListener( type, handle, false ); } } : function( elem, type, handle ) { var name = "on" + type; if ( elem.detachEvent ) { // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC if ( typeof elem[ name ] === core_strundefined ) { elem[ name ] = null; } elem.detachEvent( name, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !(this instanceof jQuery.Event) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || jQuery.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( !e ) { return; } // If preventDefault exists, run it on the original event if ( e.preventDefault ) { e.preventDefault(); // Support: IE // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false; } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( !e ) { return; } // If stopPropagation exists, run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } // Support: IE // Set the cancelBubble property of the original event to true e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); } }; // Create mouseenter/leave events using mouseover/out and event-time checks jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || (related !== target && !jQuery.contains( target, related )) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; }); // IE submit delegation if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Lazy-add a submit handler when a descendant form may potentially be submitted jQuery.event.add( this, "click._submit keypress._submit", function( e ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; if ( form && !jQuery._data( form, "submitBubbles" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); jQuery._data( form, "submitBubbles", true ); } }); // return undefined since we don't need an event listener }, postDispatch: function( event ) { // If form was submitted by the user, bubble the event up the tree if ( event._submit_bubble ) { delete event._submit_bubble; if ( this.parentNode && !event.isTrigger ) { jQuery.event.simulate( "submit", this.parentNode, event, true ); } } }, teardown: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Remove delegated handlers; cleanData eventually reaps submit handlers attached above jQuery.event.remove( this, "._submit" ); } }; } // IE change delegation and checkbox/radio fix if ( !jQuery.support.changeBubbles ) { jQuery.event.special.change = { setup: function() { if ( rformElems.test( this.nodeName ) ) { // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; } // Allow triggered, simulated change events (#11500) jQuery.event.simulate( "change", this, event, true ); }); } return false; } // Delegated event; lazy-add a change handler on descendant inputs jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); jQuery._data( elem, "changeBubbles", true ); } }); }, handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, teardown: function() { jQuery.event.remove( this, "._change" ); return !rformElems.test( this.nodeName ); } }; } // Create "bubbling" focus and blur events if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0, handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); }; jQuery.event.special[ fix ] = { setup: function() { if ( attaches++ === 0 ) { document.addEventListener( orig, handler, true ); } }, teardown: function() { if ( --attaches === 0 ) { document.removeEventListener( orig, handler, true ); } } }; }); } jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { this.on( type, selector, data, types[ type ], one ); } return this; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return this; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return this.each( function() { jQuery.event.add( this, types, fn, data, selector ); }); }, one: function( types, selector, data, fn ) { return this.on( types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each(function() { jQuery.event.remove( this, types, fn, selector ); }); }, bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { var elem = this[0]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } }); /*! * Sizzle CSS Selector Engine * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://sizzlejs.com/ */ (function( window, undefined ) { var i, cachedruns, Expr, getText, isXML, compile, hasDuplicate, outermostContext, // Local document vars setDocument, document, docElem, documentIsXML, rbuggyQSA, rbuggyMatches, matches, contains, sortOrder, // Instance-specific data expando = "sizzle" + -(new Date()), preferredDoc = window.document, support = {}, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), // General-purpose constants strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, // Array methods arr = [], pop = arr.pop, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf if we can't use a native one indexOf = arr.indexOf || function( elem ) { var i = 0, len = this.length; for ( ; i < len; i++ ) { if ( this[i] === elem ) { return i; } } return -1; }, // Regular expressions // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/css3-syntax/#characters characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", // Loosely modeled on CSS identifier characters // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = characterEncoding.replace( "w", "w#" ), // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", // Prefer arguments quoted, // then not containing pseudos/brackets, // then attribute selectors/non-parenthetical expressions, // then anything else // These preferences are here to reduce the number of selectors // needing tokenize in the PSEUDO preFilter pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + characterEncoding + ")" ), "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rsibling = /[\x20\t\r\n\f]*[+~]/, rnative = /^[^{]+\{\s*\[native code/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rescape = /'|\\/g, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, funescape = function( _, escaped ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint return high !== high ? escaped : // BMP codepoint high < 0 ? String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }; // Use a stripped-down slice if we can't use a native one try { slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType; } catch ( e ) { slice = function( i ) { var elem, results = []; while ( (elem = this[i++]) ) { results.push( elem ); } return results; }; } /** * For feature detection * @param {Function} fn The function to test for native support */ function isNative( fn ) { return rnative.test( fn + "" ); } /** * Create key-value caches of limited size * @returns {Function(string, Object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var cache, keys = []; return (cache = function( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key += " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key ] = value); }); } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created div and expects a boolean result */ function assert( fn ) { var div = document.createElement("div"); try { return fn( div ); } catch (e) { return false; } finally { // release memory in IE div = null; } } function Sizzle( selector, context, results, seed ) { var match, elem, m, nodeType, // QSA vars i, groups, old, nid, newContext, newSelector; if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } context = context || document; results = results || []; if ( !selector || typeof selector !== "string" ) { return results; } if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { return []; } if ( !documentIsXML && !seed ) { // Shortcuts if ( (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Speed-up: Sizzle("TAG") } else if ( match[2] ) { push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); return results; // Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); return results; } } // QSA path if ( support.qsa && !rbuggyQSA.test(selector) ) { old = true; nid = expando; newContext = context; newSelector = nodeType === 9 && selector; // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { groups = tokenize( selector ); if ( (old = context.getAttribute("id")) ) { nid = old.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } nid = "[id='" + nid + "'] "; i = groups.length; while ( i-- ) { groups[i] = nid + toSelector( groups[i] ); } newContext = rsibling.test( selector ) && context.parentNode || context; newSelector = groups.join(","); } if ( newSelector ) { try { push.apply( results, slice.call( newContext.querySelectorAll( newSelector ), 0 ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Detect xml * @param {Element|Object} elem An element or a document */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var doc = node ? node.ownerDocument || node : preferredDoc; // If no document and documentElement is available, return if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Set our document document = doc; docElem = doc.documentElement; // Support tests documentIsXML = isXML( doc ); // Check if getElementsByTagName("*") returns only elements support.tagNameNoComments = assert(function( div ) { div.appendChild( doc.createComment("") ); return !div.getElementsByTagName("*").length; }); // Check if attributes should be retrieved by attribute nodes support.attributes = assert(function( div ) { div.innerHTML = ""; var type = typeof div.lastChild.getAttribute("multiple"); // IE8 returns a string for some attributes even when not present return type !== "boolean" && type !== "string"; }); // Check if getElementsByClassName can be trusted support.getByClassName = assert(function( div ) { // Opera can't find a second classname (in 9.6) div.innerHTML = ""; if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { return false; } // Safari 3.2 caches class attributes and doesn't catch changes div.lastChild.className = "e"; return div.getElementsByClassName("e").length === 2; }); // Check if getElementById returns elements by name // Check if getElementsByName privileges form controls or returns elements by ID support.getByName = assert(function( div ) { // Inject content div.id = expando + 0; div.innerHTML = "
"; docElem.insertBefore( div, docElem.firstChild ); // Test var pass = doc.getElementsByName && // buggy browsers will return fewer than the correct 2 doc.getElementsByName( expando ).length === 2 + // buggy browsers will return more than the correct 0 doc.getElementsByName( expando + 0 ).length; support.getIdNotName = !doc.getElementById( expando ); // Cleanup docElem.removeChild( div ); return pass; }); // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = ""; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; // ID find and filter if ( support.getIdNotName ) { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { var m = context.getElementById( id ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 return m && m.parentNode ? [m] : []; } }; Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; }; } else { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { var m = context.getElementById( id ); return m ? m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? [m] : undefined : []; } }; Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; } // Tag Expr.find["TAG"] = support.tagNameNoComments ? function( tag, context ) { if ( typeof context.getElementsByTagName !== strundefined ) { return context.getElementsByTagName( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( (elem = results[i++]) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Name Expr.find["NAME"] = support.getByName && function( tag, context ) { if ( typeof context.getElementsByName !== strundefined ) { return context.getElementsByName( name ); } }; // Class Expr.find["CLASS"] = support.getByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { return context.getElementsByClassName( className ); } }; // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21), // no need to also add to buggyMatches since matches checks buggyQSA // A support test would require too much code (would include document ready) rbuggyQSA = [ ":focus" ]; if ( (support.qsa = isNative(doc.querySelectorAll)) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { // Select is set to empty string on purpose // This is to test IE's treatment of not explictly // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 div.innerHTML = ""; // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } }); assert(function( div ) { // Opera 10-12/IE8 - ^= $= *= and empty values // Should not select anything div.innerHTML = ""; if ( div.querySelectorAll("[i^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Opera 10-11 does not throw on post-comma invalid pseudos div.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector || docElem.mozMatchesSelector || docElem.webkitMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector) )) ) { assert(function( div ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( div, "div" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( div, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } rbuggyQSA = new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 )); } : function( a, b ) { if ( b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } } return false; }; // Document order sorting sortOrder = docElem.compareDocumentPosition ? function( a, b ) { var compare; if ( a === b ) { hasDuplicate = true; return 0; } if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { if ( a === doc || contains( preferredDoc, a ) ) { return -1; } if ( b === doc || contains( preferredDoc, b ) ) { return 1; } return 0; } return compare & 4 ? -1 : 1; } return a.compareDocumentPosition ? -1 : 1; } : function( a, b ) { var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; // Parentless nodes are either documents or disconnected } else if ( !aup || !bup ) { return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( (cur = cur.parentNode) ) { ap.unshift( cur ); } cur = b; while ( (cur = cur.parentNode) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[i] === bp[i] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[i], bp[i] ) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; // Always assume the presence of duplicates if sort doesn't // pass them to our comparison function (as in Google Chrome). hasDuplicate = false; [0, 0].sort( sortOrder ); support.detectDuplicates = hasDuplicate; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); // rbuggyQSA always contains :focus, so no need for an existence check if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch(e) {} } return Sizzle( expr, document, null, [elem] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { var val; // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } if ( !documentIsXML ) { name = name.toLowerCase(); } if ( (val = Expr.attrHandle[ name ]) ) { return val( elem ); } if ( documentIsXML || support.attributes ) { return elem.getAttribute( name ); } return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? name : val && val.specified ? val.value : null; }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; // Document sorting and removing duplicates Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], i = 1, j = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; results.sort( sortOrder ); if ( hasDuplicate ) { for ( ; (elem = results[i]); i++ ) { if ( elem === results[ i - 1 ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } return results; }; function siblingCheck( a, b ) { var cur = b && a, diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( (cur = cur.nextSibling) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } // Returns a function to use in pseudos for input types function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } // Returns a function to use in pseudos for buttons function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } // Returns a function to use in pseudos for positionals function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array for ( ; (node = elem[i]); i++ ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (see #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[3] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); // other types prohibit arguments } else if ( match[3] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[5] && match[2]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Accept quoted arguments as-is if ( match[4] ) { match[2] = match[4]; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) (excess = tokenize( unquoted, true )) && // advance to the next closing parenthesis (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { // excess is a negative index match[0] = match[0].slice( 0, excess ); match[2] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeName ) { if ( nodeName === "*" ) { return function() { return true; }; } nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); return function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); }); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; }, "CHILD": function( type, what, argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, context, xml ) { var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index outerCache = parent[ expando ] || (parent[ expando ] = {}); cache = outerCache[ type ] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = cache[0] === dirruns && cache[2]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start (diff = nodeIndex = 0) || start.pop()) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { outerCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } // Use previously-cached element index if available } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { diff = cache[1]; // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) } else { // Use the same loop as above to seek `elem` from the start while ( (node = ++nodeIndex && node && node[ dir ] || (diff = nodeIndex = 0) || start.pop()) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction(function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf.call( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction(function( seed, matches, context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( (elem = unmatched[i]) ) { seed[i] = !(matches[i] = elem); } } }) : function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); return !results.pop(); }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "contains": markFunction(function( text ) { return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifider if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsXML ? elem.getAttribute("xml:lang") || elem.getAttribute("lang") : elem.lang) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); return false; }; }), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": function( elem ) { return elem.disabled === false; }, "disabled": function( elem ) { return elem.disabled === true; }, "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), // not comment, processing instructions, or others // Thanks to Diego Perini for the nodeName shortcut // Greater than "@" means alpha characters (specifically not starting with "#" or "?") for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); }, // Position-in-collection "first": createPositionalPseudo(function() { return [ 0 ]; }), "last": createPositionalPseudo(function( matchIndexes, length ) { return [ length - 1 ]; }), "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; }), "even": createPositionalPseudo(function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "odd": createPositionalPseudo(function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; }), "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; }) } }; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } function tokenize( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || (match = rcomma.exec( soFar )) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } groups.push( tokens = [] ); } matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { matched = match.shift(); tokens.push( { value: matched, // Cast descendant combinators to space type: match[0].replace( rtrim, " " ) } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matched = match.shift(); tokens.push( { value: matched, type: type, matches: match } ); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); } function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[i].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, checkNonElements = base && dir === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var data, cache, outerCache, dirkey = dirruns + " " + doneName; // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { if ( (data = cache[1]) === true || data === cachedruns ) { return data === true; } } else { cache = outerCache[ dir ] = [ dirkey ]; cache[1] = matcher( elem, context, xml ) || cachedruns; if ( cache[1] === true ) { return true; } } } } } }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[i]( elem, context, xml ) ) { return false; } } return true; } : matchers[0]; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( (elem = unmatched[i]) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction(function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( (elem = temp[i]) ) { matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) ) { // Restore matcherIn since elem is not yet a final match temp.push( (matcherIn[i] = elem) ); } } postFinder( null, (matcherOut = []), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } }); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[0].type ], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf.call( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); } ]; for ( ; i < len; i++ ) { if ( (matcher = Expr.relative[ tokens[i].type ]) ) { matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; } else { matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[j].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { // A counter to specify which element is currently being matched var matcherCachedRuns = 0, bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, expandContext ) { var elem, j, matcher, setMatched = [], matchedCount = 0, i = "0", unmatched = seed && [], outermost = expandContext != null, contextBackup = outermostContext, // We must always have either seed elements or context elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); if ( outermost ) { outermostContext = context !== document && context; cachedruns = matcherCachedRuns; } // Add elements passing elementMatchers directly to results // Keep `i` a string if there are no elements so `matchedCount` will be "00" below for ( ; (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; while ( (matcher = elementMatchers[j++]) ) { if ( matcher( elem, context, xml ) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; cachedruns = ++matcherCachedRuns; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( (elem = !matcher && elem) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // Apply set filters to unmatched elements matchedCount += i; if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !(unmatched[i] || setMatched[i]) ) { setMatched[i] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !group ) { group = tokenize( selector ); } i = group.length; while ( i-- ) { cached = matcherFromTokens( group[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); } return cached; }; function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } function select( selector, context, results, seed ) { var i, tokens, token, type, find, match = tokenize( selector ); if ( !seed ) { // Try to minimize operations if there is only one group if ( match.length === 1 ) { // Take a shortcut and set the context if the root selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && !documentIsXML && Expr.relative[ tokens[1].type ] ) { context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; if ( !context ) { return results; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[i]; // Abort if we hit a combinator if ( Expr.relative[ (type = token.type) ] ) { break; } if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && context.parentNode || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, slice.call( seed, 0 ) ); return results; } break; } } } } } // Compile and execute a filtering function // Provide `match` to avoid retokenization if we modified the selector above compile( selector, match )( seed, context, documentIsXML, results, rsibling.test( selector ) ); return results; } // Deprecated Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Easy API for creating new setFilters function setFilters() {} Expr.filters = setFilters.prototype = Expr.pseudos; Expr.setFilters = new setFilters(); // Initialize with the default document setDocument(); // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; })( window ); var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ find: function( selector ) { var i, ret, self, len = this.length; if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }) ); } ret = []; for ( i = 0; i < len; i++ ) { jQuery.find( selector, this[ i ], ret ); } // Needed because $( selector, context ) becomes $( context ).find( selector ) ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; return ret; }, has: function( target ) { var i, targets = jQuery( target, this ), len = targets.length; return this.filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false) ); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true) ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, ret = [], pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0; for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } cur = cur.parentNode; } } return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; } // index in selector if ( typeof elem === "string" ) { return jQuery.inArray( this[0], jQuery( elem ) ); } // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem, this ); }, add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( jQuery.unique(all) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ); } }); jQuery.fn.andSelf = jQuery.fn.addBack; function sibling( cur, dir ) { do { cur = cur[ dir ]; } while ( cur && cur.nodeType !== 1 ); return cur; } jQuery.each({ parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return jQuery.dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return jQuery.dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return jQuery.dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return jQuery.dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return jQuery.dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return jQuery.dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return jQuery.sibling( elem.firstChild ); }, contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, dir: function( elem, dir, until ) { var matched = [], cur = elem[ dir ]; while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { if ( cur.nodeType === 1 ) { matched.push( cur ); } cur = cur[dir]; } return matched; }, sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } }); // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem ) { return ( elem === qualifier ) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); if ( safeFrag.createElement ) { while ( list.length ) { safeFrag.createElement( list.pop() ); } } return safeFrag; } var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /\s*$/g, // We have to close these tags to support XHTML (#13200) wrapMap = { option: [ 1, "" ], legend: [ 1, "
", "
" ], area: [ 1, "", "" ], param: [ 1, "", "" ], thead: [ 1, "", "
" ], tr: [ 2, "", "
" ], col: [ 2, "", "
" ], td: [ 3, "", "
" ], // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; jQuery.fn.extend({ text: function( value ) { return jQuery.access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); }, null, value, arguments.length ); }, wrapAll: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapAll( html.call(this, i) ); }); } if ( this[0] ) { // The elements to wrap the target around var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); if ( this[0].parentNode ) { wrap.insertBefore( this[0] ); } wrap.map(function() { var elem = this; while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { elem = elem.firstChild; } return elem; }).append( this ); } return this; }, wrapInner: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapInner( html.call(this, i) ); }); } return this.each(function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } }); }, wrap: function( html ) { var isFunction = jQuery.isFunction( html ); return this.each(function(i) { jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); }); }, unwrap: function() { return this.parent().each(function() { if ( !jQuery.nodeName( this, "body" ) ) { jQuery( this ).replaceWith( this.childNodes ); } }).end(); }, append: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.appendChild( elem ); } }); }, prepend: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.insertBefore( elem, this.firstChild ); } }); }, before: function() { return this.domManip( arguments, false, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } }); }, after: function() { return this.domManip( arguments, false, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } }); }, // keepData is for internal use only--do not document remove: function( selector, keepData ) { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { if ( !keepData && elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem ) ); } if ( elem.parentNode ) { if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { setGlobalEval( getAll( elem, "script" ) ); } elem.parentNode.removeChild( elem ); } } } return this; }, empty: function() { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); } // Remove any remaining nodes while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } // If this is a select, ensure that it displays empty (#12336) // Support: IE<9 if ( elem.options && jQuery.nodeName( elem, "select" ) ) { elem.options.length = 0; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function () { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); }); }, html: function( value ) { return jQuery.access( this, function( value ) { var elem = this[0] || {}, i = 0, l = this.length; if ( value === undefined ) { return elem.nodeType === 1 ? elem.innerHTML.replace( rinlinejQuery, "" ) : undefined; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { value = value.replace( rxhtmlTag, "<$1>" ); try { for (; i < l; i++ ) { // Remove element nodes and prevent memory leaks elem = this[i] || {}; if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch(e) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function( value ) { var isFunc = jQuery.isFunction( value ); // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( !isFunc && typeof value !== "string" ) { value = jQuery( value ).not( this ).detach(); } return this.domManip( [ value ], true, function( elem ) { var next = this.nextSibling, parent = this.parentNode; if ( parent ) { jQuery( this ).remove(); parent.insertBefore( elem, next ); } }); }, detach: function( selector ) { return this.remove( selector, true ); }, domManip: function( args, table, callback ) { // Flatten any nested arrays args = core_concat.apply( [], args ); var first, node, hasScripts, scripts, doc, fragment, i = 0, l = this.length, set = this, iNoClone = l - 1, value = args[0], isFunction = jQuery.isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { return this.each(function( index ) { var self = set.eq( index ); if ( isFunction ) { args[0] = value.call( this, index, table ? self.html() : undefined ); } self.domManip( args, table, callback ); }); } if ( l ) { fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( table && jQuery.nodeName( this[i], "table" ) ? findOrAppend( this[i], "tbody" ) : this[i], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src ) { // Hope ajax is available... jQuery.ajax({ url: node.src, type: "GET", dataType: "script", async: false, global: false, "throws": true }); } else { jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); } } } } // Fix #11809: Avoid leaking memory fragment = first = null; } } return this; } }); function findOrAppend( elem, tag ) { return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { var attr = elem.getAttributeNode("type"); elem.type = ( attr && attr.specified ) + "/" + elem.type; return elem; } function restoreScript( elem ) { var match = rscriptTypeMasked.exec( elem.type ); if ( match ) { elem.type = match[1]; } else { elem.removeAttribute("type"); } return elem; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var elem, i = 0; for ( ; (elem = elems[i]) != null; i++ ) { jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); } } function cloneCopyEvent( src, dest ) { if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { return; } var type, i, l, oldData = jQuery._data( src ), curData = jQuery._data( dest, oldData ), events = oldData.events; if ( events ) { delete curData.handle; curData.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } // make the cloned public data object a copy from the original if ( curData.data ) { curData.data = jQuery.extend( {}, curData.data ); } } function fixCloneNodeIssues( src, dest ) { var nodeName, e, data; // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } nodeName = dest.nodeName.toLowerCase(); // IE6-8 copies events bound via attachEvent when using cloneNode. if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { data = jQuery._data( dest ); for ( e in data.events ) { jQuery.removeEvent( dest, e, data.handle ); } // Event data gets referenced instead of copied if the expando gets copied too dest.removeAttribute( jQuery.expando ); } // IE blanks contents when cloning scripts, and tries to evaluate newly-set text if ( nodeName === "script" && dest.text !== src.text ) { disableScript( dest ).text = src.text; restoreScript( dest ); // IE6-10 improperly clones children of object elements using classid. // IE10 throws NoModificationAllowedError if parent is null, #12132. } else if ( nodeName === "object" ) { if ( dest.parentNode ) { dest.outerHTML = src.outerHTML; } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { dest.innerHTML = src.innerHTML; } } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set dest.defaultChecked = dest.checked = src.checked; // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" if ( dest.value !== src.value ) { dest.value = src.value; } // IE6-8 fails to return the selected option to the default selected // state when cloning options } else if ( nodeName === "option" ) { dest.defaultSelected = dest.selected = src.defaultSelected; // IE6-8 fails to set the defaultValue to the correct value when // cloning other types of input fields } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } jQuery.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, i = 0, ret = [], insert = jQuery( selector ), last = insert.length - 1; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone(true); jQuery( insert[i] )[ original ]( elems ); // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() core_push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; }); function getAll( context, tag ) { var elems, elem, i = 0, found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : undefined; if ( !found ) { for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { if ( !tag || jQuery.nodeName( elem, tag ) ) { found.push( elem ); } else { jQuery.merge( found, getAll( elem, tag ) ); } } } return tag === undefined || tag && jQuery.nodeName( context, tag ) ? jQuery.merge( [ context ], found ) : found; } // Used in buildFragment, fixes the defaultChecked property function fixDefaultChecked( elem ) { if ( manipulation_rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; } } jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var destElements, node, clone, i, srcElements, inPage = jQuery.contains( elem.ownerDocument, elem ); if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); } if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); // Fix all IE cloning issues for ( i = 0; (node = srcElements[i]) != null; ++i ) { // Ensure that the destination node is not null; Fixes #9587 if ( destElements[i] ) { fixCloneNodeIssues( node, destElements[i] ); } } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0; (node = srcElements[i]) != null; i++ ) { cloneCopyEvent( node, destElements[i] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } destElements = srcElements = node = null; // Return the cloned set return clone; }, buildFragment: function( elems, context, scripts, selection ) { var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length, // Ensure a safe fragment safe = createSafeFragment( context ), nodes = [], i = 0; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( jQuery.type( elem ) === "object" ) { jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || safe.appendChild( context.createElement("div") ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; while ( j-- ) { tmp = tmp.lastChild; } // Manually add leading whitespace removed by IE if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); } // Remove IE's autoinserted from table fragments if ( !jQuery.support.tbody ) { // String was a , *may* have spurious elem = tag === "table" && !rtbody.test( elem ) ? tmp.firstChild : // String was a bare or wrap[1] === "
" && !rtbody.test( elem ) ? tmp : 0; j = elem && elem.childNodes.length; while ( j-- ) { if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { elem.removeChild( tbody ); } } } jQuery.merge( nodes, tmp.childNodes ); // Fix #12392 for WebKit and IE > 9 tmp.textContent = ""; // Fix #12392 for oldIE while ( tmp.firstChild ) { tmp.removeChild( tmp.firstChild ); } // Remember the top-level container for proper cleanup tmp = safe.lastChild; } } } // Fix #11356: Clear elements from fragment if ( tmp ) { safe.removeChild( tmp ); } // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } i = 0; while ( (elem = nodes[ i++ ]) ) { // #4087 - If origin and destination elements are the same, and this is // that element, do not do anything if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { continue; } contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment tmp = getAll( safe.appendChild( elem ), "script" ); // Preserve script evaluation history if ( contains ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( (elem = tmp[ j++ ]) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } tmp = null; return safe; }, cleanData: function( elems, /* internal */ acceptData ) { var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, deleteExpando = jQuery.support.deleteExpando, special = jQuery.event.special; for ( ; (elem = elems[i]) != null; i++ ) { if ( acceptData || jQuery.acceptData( elem ) ) { id = elem[ internalKey ]; data = id && cache[ id ]; if ( data ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Remove cache only if it was not already removed by jQuery.event.remove if ( cache[ id ] ) { delete cache[ id ]; // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } core_deletedIds.push( id ); } } } } } }); var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, rposition = /^(top|right|bottom|left)$/, // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rmargin = /^margin/, rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), elemdisplay = { BODY: "block" }, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: 0, fontWeight: 400 }, cssExpand = [ "Top", "Right", "Bottom", "Left" ], cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; // return a css property mapped to a potentially vendor prefixed property function vendorPropName( style, name ) { // shortcut for names that are not vendor prefixed if ( name in style ) { return name; } // check for vendor prefixed names var capName = name.charAt(0).toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in style ) { return name; } } return origName; } function isHidden( elem, el ) { // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); } function showHide( elements, show ) { var display, elem, hidden, values = [], index = 0, length = elements.length; for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } values[ index ] = jQuery._data( elem, "olddisplay" ); display = elem.style.display; if ( show ) { // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not if ( !values[ index ] && display === "none" ) { elem.style.display = ""; } // Set elements which have been overridden with display: none // in a stylesheet to whatever the default browser style is // for such an element if ( elem.style.display === "" && isHidden( elem ) ) { values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); } } else { if ( !values[ index ] ) { hidden = isHidden( elem ); if ( display && display !== "none" || !hidden ) { jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); } } } } // Set the display of most of the elements in a second loop // to avoid the constant reflow for ( index = 0; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } if ( !show || elem.style.display === "none" || elem.style.display === "" ) { elem.style.display = show ? values[ index ] || "" : "none"; } } return elements; } jQuery.fn.extend({ css: function( name, value ) { return jQuery.access( this, function( elem, name, value ) { var len, styles, map = {}, i = 0; if ( jQuery.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); }, show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { var bool = typeof state === "boolean"; return this.each(function() { if ( bool ? state : isHidden( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } }); } }); jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Exclude the following css properties to add px cssNumber: { "columnCount": true, "fillOpacity": true, "fontWeight": true, "lineHeight": true, "opacity": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { // normalize float css property "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" }, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase( name ), style = elem.style; name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // convert relative number strings (+= or -=) to relative numbers. #7345 if ( type === "string" && (ret = rrelNum.exec( value )) ) { value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); // Fixes bug #9237 type = "number"; } // Make sure that NaN and null values aren't set. See: #7116 if ( value == null || type === "number" && isNaN( value ) ) { return; } // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { style[ name ] = value; } catch(e) {} } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var num, val, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } //convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Return, converting to number if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; } return val; }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback, args ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.apply( elem, args || [] ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; } }); // NOTE: we've included the "window" in window.getComputedStyle // because jsdom on node.js will break without it. if ( window.getComputedStyle ) { getStyles = function( elem ) { return window.getComputedStyle( elem, null ); }; curCSS = function( elem, name, _computed ) { var width, minWidth, maxWidth, computed = _computed || getStyles( elem ), // getPropertyValue is only needed for .css('filter') in IE9, see #12537 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, style = elem.style; if ( computed ) { if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret; }; } else if ( document.documentElement.currentStyle ) { getStyles = function( elem ) { return elem.currentStyle; }; curCSS = function( elem, name, _computed ) { var left, rs, rsLeft, computed = _computed || getStyles( elem ), ret = computed ? computed[ name ] : undefined, style = elem.style; // Avoid setting ret to empty string here // so we don't default to auto if ( ret == null && style && style[ name ] ) { ret = style[ name ]; } // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels // but not position css attributes, as those are proportional to the parent element instead // and we can't measure the parent instead because it might trigger a "stacking dolls" problem if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { // Remember the original values left = style.left; rs = elem.runtimeStyle; rsLeft = rs && rs.left; // Put in the new values to get a computed value out if ( rsLeft ) { rs.left = elem.currentStyle.left; } style.left = name === "fontSize" ? "1em" : ret; ret = style.pixelLeft + "px"; // Revert the changed values style.left = left; if ( rsLeft ) { rs.left = rsLeft; } } return ret === "" ? "auto" : ret; }; } function setPositiveNumber( elem, value, subtract ) { var matches = rnumsplit.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : value; } function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { var i = extra === ( isBorderBox ? "border" : "content" ) ? // If we already have the right measurement, avoid augmentation 4 : // Otherwise initialize for horizontal or vertical properties name === "width" ? 1 : 0, val = 0; for ( ; i < 4; i += 2 ) { // both box models exclude margin, so add it if we want it if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } if ( isBorderBox ) { // border-box includes padding, so remove it if we want content if ( extra === "content" ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // at this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { // at this point, extra isn't content, so add padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // at this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } return val; } function getWidthOrHeight( elem, name, extra ) { // Start with offset property, which is equivalent to the border-box value var valueIsBorderBox = true, val = name === "width" ? elem.offsetWidth : elem.offsetHeight, styles = getStyles( elem ), isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if ( val <= 0 || val == null ) { // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name, styles ); if ( val < 0 || val == null ) { val = elem.style[ name ]; } // Computed unit is not pixels. Stop here and return. if ( rnumnonpx.test(val) ) { return val; } // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); // Normalize "", auto, and prepare for extra val = parseFloat( val ) || 0; } // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles ) ) + "px"; } // Try to determine the default display value of an element function css_defaultDisplay( nodeName ) { var doc = document, display = elemdisplay[ nodeName ]; if ( !display ) { display = actualDisplay( nodeName, doc ); // If the simple way fails, read from inside an iframe if ( display === "none" || !display ) { // Use the already-created iframe if possible iframe = ( iframe || jQuery("' : ''); inst._keyEvent = false; return html; }, /* Generate the month and year header. */ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, secondary, monthNames, monthNamesShort) { var changeMonth = this._get(inst, 'changeMonth'); var changeYear = this._get(inst, 'changeYear'); var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); var html = '
'; var monthHtml = ''; // month selection if (secondary || !changeMonth) monthHtml += '' + monthNames[drawMonth] + ''; else { var inMinYear = (minDate && minDate.getFullYear() == drawYear); var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); monthHtml += ''; } if (!showMonthAfterYear) html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); // year selection if ( !inst.yearshtml ) { inst.yearshtml = ''; if (secondary || !changeYear) html += '' + drawYear + ''; else { // determine range of years to display var years = this._get(inst, 'yearRange').split(':'); var thisYear = new Date().getFullYear(); var determineYear = function(value) { var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : parseInt(value, 10))); return (isNaN(year) ? thisYear : year); }; var year = determineYear(years[0]); var endYear = Math.max(year, determineYear(years[1] || '')); year = (minDate ? Math.max(year, minDate.getFullYear()) : year); endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); inst.yearshtml += ''; html += inst.yearshtml; inst.yearshtml = null; } } html += this._get(inst, 'yearSuffix'); if (showMonthAfterYear) html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; html += '
'; // Close datepicker_header return html; }, /* Adjust one of the date sub-fields. */ _adjustInstDate: function(inst, offset, period) { var year = inst.drawYear + (period == 'Y' ? offset : 0); var month = inst.drawMonth + (period == 'M' ? offset : 0); var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period == 'D' ? offset : 0); var date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); inst.selectedDay = date.getDate(); inst.drawMonth = inst.selectedMonth = date.getMonth(); inst.drawYear = inst.selectedYear = date.getFullYear(); if (period == 'M' || period == 'Y') this._notifyChange(inst); }, /* Ensure a date is within any min/max bounds. */ _restrictMinMax: function(inst, date) { var minDate = this._getMinMaxDate(inst, 'min'); var maxDate = this._getMinMaxDate(inst, 'max'); var newDate = (minDate && date < minDate ? minDate : date); newDate = (maxDate && newDate > maxDate ? maxDate : newDate); return newDate; }, /* Notify change of month/year. */ _notifyChange: function(inst) { var onChange = this._get(inst, 'onChangeMonthYear'); if (onChange) onChange.apply((inst.input ? inst.input[0] : null), [inst.selectedYear, inst.selectedMonth + 1, inst]); }, /* Determine the number of months to show. */ _getNumberOfMonths: function(inst) { var numMonths = this._get(inst, 'numberOfMonths'); return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); }, /* Determine the current maximum date - ensure no time components are set. */ _getMinMaxDate: function(inst, minMax) { return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); }, /* Find the number of days in a given month. */ _getDaysInMonth: function(year, month) { return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); }, /* Find the day of the week of the first of a month. */ _getFirstDayOfMonth: function(year, month) { return new Date(year, month, 1).getDay(); }, /* Determines if we should allow a "next/prev" month display change. */ _canAdjustMonth: function(inst, offset, curYear, curMonth) { var numMonths = this._getNumberOfMonths(inst); var date = this._daylightSavingAdjust(new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); if (offset < 0) date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); return this._isInRange(inst, date); }, /* Is the given date in the accepted range? */ _isInRange: function(inst, date) { var minDate = this._getMinMaxDate(inst, 'min'); var maxDate = this._getMinMaxDate(inst, 'max'); return ((!minDate || date.getTime() >= minDate.getTime()) && (!maxDate || date.getTime() <= maxDate.getTime())); }, /* Provide the configuration settings for formatting/parsing. */ _getFormatConfig: function(inst) { var shortYearCutoff = this._get(inst, 'shortYearCutoff'); shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); return {shortYearCutoff: shortYearCutoff, dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; }, /* Format the given date for display. */ _formatDate: function(inst, day, month, year) { if (!day) { inst.currentDay = inst.selectedDay; inst.currentMonth = inst.selectedMonth; inst.currentYear = inst.selectedYear; } var date = (day ? (typeof day == 'object' ? day : this._daylightSavingAdjust(new Date(year, month, day))) : this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); } }); /* * Bind hover events for datepicker elements. * Done via delegate so the binding only occurs once in the lifetime of the parent div. * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. */ function bindHover(dpDiv) { var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; return dpDiv.delegate(selector, 'mouseout', function() { $(this).removeClass('ui-state-hover'); if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); }) .delegate(selector, 'mouseover', function(){ if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); $(this).addClass('ui-state-hover'); if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); } }); } /* jQuery extend now ignores nulls! */ function extendRemove(target, props) { $.extend(target, props); for (var name in props) if (props[name] == null || props[name] == undefined) target[name] = props[name]; return target; }; /* Invoke the datepicker functionality. @param options string - a command, optionally followed by additional parameters or Object - settings for attaching new datepicker functionality @return jQuery object */ $.fn.datepicker = function(options){ /* Verify an empty collection wasn't passed - Fixes #6976 */ if ( !this.length ) { return this; } /* Initialise the date picker. */ if (!$.datepicker.initialized) { $(document).mousedown($.datepicker._checkExternalClick). find(document.body).append($.datepicker.dpDiv); $.datepicker.initialized = true; } var otherArgs = Array.prototype.slice.call(arguments, 1); if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) return $.datepicker['_' + options + 'Datepicker']. apply($.datepicker, [this[0]].concat(otherArgs)); if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') return $.datepicker['_' + options + 'Datepicker']. apply($.datepicker, [this[0]].concat(otherArgs)); return this.each(function() { typeof options == 'string' ? $.datepicker['_' + options + 'Datepicker']. apply($.datepicker, [this].concat(otherArgs)) : $.datepicker._attachDatepicker(this, options); }); }; $.datepicker = new Datepicker(); // singleton instance $.datepicker.initialized = false; $.datepicker.uuid = new Date().getTime(); $.datepicker.version = "1.9.2"; // Workaround for #4055 // Add another global to avoid noConflict issues with inline event handlers window['DP_jQuery_' + dpuuid] = $; })(jQuery); (function( $, undefined ) { var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", sizeRelatedOptions = { buttons: true, height: true, maxHeight: true, maxWidth: true, minHeight: true, minWidth: true, width: true }, resizableRelatedOptions = { maxHeight: true, maxWidth: true, minHeight: true, minWidth: true }; $.widget("ui.dialog", { version: "1.9.2", options: { autoOpen: true, buttons: {}, closeOnEscape: true, closeText: "close", dialogClass: "", draggable: true, hide: null, height: "auto", maxHeight: false, maxWidth: false, minHeight: 150, minWidth: 150, modal: false, position: { my: "center", at: "center", of: window, collision: "fit", // ensure that the titlebar is never outside the document using: function( pos ) { var topOffset = $( this ).css( pos ).offset().top; if ( topOffset < 0 ) { $( this ).css( "top", pos.top - topOffset ); } } }, resizable: true, show: null, stack: true, title: "", width: 300, zIndex: 1000 }, _create: function() { this.originalTitle = this.element.attr( "title" ); // #5742 - .attr() might return a DOMElement if ( typeof this.originalTitle !== "string" ) { this.originalTitle = ""; } this.oldPosition = { parent: this.element.parent(), index: this.element.parent().children().index( this.element ) }; this.options.title = this.options.title || this.originalTitle; var that = this, options = this.options, title = options.title || " ", uiDialog, uiDialogTitlebar, uiDialogTitlebarClose, uiDialogTitle, uiDialogButtonPane; uiDialog = ( this.uiDialog = $( "
" ) ) .addClass( uiDialogClasses + options.dialogClass ) .css({ display: "none", outline: 0, // TODO: move to stylesheet zIndex: options.zIndex }) // setting tabIndex makes the div focusable .attr( "tabIndex", -1) .keydown(function( event ) { if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && event.keyCode === $.ui.keyCode.ESCAPE ) { that.close( event ); event.preventDefault(); } }) .mousedown(function( event ) { that.moveToTop( false, event ); }) .appendTo( "body" ); this.element .show() .removeAttr( "title" ) .addClass( "ui-dialog-content ui-widget-content" ) .appendTo( uiDialog ); uiDialogTitlebar = ( this.uiDialogTitlebar = $( "
" ) ) .addClass( "ui-dialog-titlebar ui-widget-header " + "ui-corner-all ui-helper-clearfix" ) .bind( "mousedown", function() { // Dialog isn't getting focus when dragging (#8063) uiDialog.focus(); }) .prependTo( uiDialog ); uiDialogTitlebarClose = $( "" ) .addClass( "ui-dialog-titlebar-close ui-corner-all" ) .attr( "role", "button" ) .click(function( event ) { event.preventDefault(); that.close( event ); }) .appendTo( uiDialogTitlebar ); ( this.uiDialogTitlebarCloseText = $( "" ) ) .addClass( "ui-icon ui-icon-closethick" ) .text( options.closeText ) .appendTo( uiDialogTitlebarClose ); uiDialogTitle = $( "" ) .uniqueId() .addClass( "ui-dialog-title" ) .html( title ) .prependTo( uiDialogTitlebar ); uiDialogButtonPane = ( this.uiDialogButtonPane = $( "
" ) ) .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); ( this.uiButtonSet = $( "
" ) ) .addClass( "ui-dialog-buttonset" ) .appendTo( uiDialogButtonPane ); uiDialog.attr({ role: "dialog", "aria-labelledby": uiDialogTitle.attr( "id" ) }); uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); this._hoverable( uiDialogTitlebarClose ); this._focusable( uiDialogTitlebarClose ); if ( options.draggable && $.fn.draggable ) { this._makeDraggable(); } if ( options.resizable && $.fn.resizable ) { this._makeResizable(); } this._createButtons( options.buttons ); this._isOpen = false; if ( $.fn.bgiframe ) { uiDialog.bgiframe(); } // prevent tabbing out of modal dialogs this._on( uiDialog, { keydown: function( event ) { if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { return; } var tabbables = $( ":tabbable", uiDialog ), first = tabbables.filter( ":first" ), last = tabbables.filter( ":last" ); if ( event.target === last[0] && !event.shiftKey ) { first.focus( 1 ); return false; } else if ( event.target === first[0] && event.shiftKey ) { last.focus( 1 ); return false; } }}); }, _init: function() { if ( this.options.autoOpen ) { this.open(); } }, _destroy: function() { var next, oldPosition = this.oldPosition; if ( this.overlay ) { this.overlay.destroy(); } this.uiDialog.hide(); this.element .removeClass( "ui-dialog-content ui-widget-content" ) .hide() .appendTo( "body" ); this.uiDialog.remove(); if ( this.originalTitle ) { this.element.attr( "title", this.originalTitle ); } next = oldPosition.parent.children().eq( oldPosition.index ); // Don't try to place the dialog next to itself (#8613) if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { next.before( this.element ); } else { oldPosition.parent.append( this.element ); } }, widget: function() { return this.uiDialog; }, close: function( event ) { var that = this, maxZ, thisZ; if ( !this._isOpen ) { return; } if ( false === this._trigger( "beforeClose", event ) ) { return; } this._isOpen = false; if ( this.overlay ) { this.overlay.destroy(); } if ( this.options.hide ) { this._hide( this.uiDialog, this.options.hide, function() { that._trigger( "close", event ); }); } else { this.uiDialog.hide(); this._trigger( "close", event ); } $.ui.dialog.overlay.resize(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) if ( this.options.modal ) { maxZ = 0; $( ".ui-dialog" ).each(function() { if ( this !== that.uiDialog[0] ) { thisZ = $( this ).css( "z-index" ); if ( !isNaN( thisZ ) ) { maxZ = Math.max( maxZ, thisZ ); } } }); $.ui.dialog.maxZ = maxZ; } return this; }, isOpen: function() { return this._isOpen; }, // the force parameter allows us to move modal dialogs to their correct // position on open moveToTop: function( force, event ) { var options = this.options, saveScroll; if ( ( options.modal && !force ) || ( !options.stack && !options.modal ) ) { return this._trigger( "focus", event ); } if ( options.zIndex > $.ui.dialog.maxZ ) { $.ui.dialog.maxZ = options.zIndex; } if ( this.overlay ) { $.ui.dialog.maxZ += 1; $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); } // Save and then restore scroll // Opera 9.5+ resets when parent z-index is changed. // http://bugs.jqueryui.com/ticket/3193 saveScroll = { scrollTop: this.element.scrollTop(), scrollLeft: this.element.scrollLeft() }; $.ui.dialog.maxZ += 1; this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); this.element.attr( saveScroll ); this._trigger( "focus", event ); return this; }, open: function() { if ( this._isOpen ) { return; } var hasFocus, options = this.options, uiDialog = this.uiDialog; this._size(); this._position( options.position ); uiDialog.show( options.show ); this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; this.moveToTop( true ); // set focus to the first tabbable element in the content area or the first button // if there are no tabbable elements, set focus on the dialog itself hasFocus = this.element.find( ":tabbable" ); if ( !hasFocus.length ) { hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); if ( !hasFocus.length ) { hasFocus = uiDialog; } } hasFocus.eq( 0 ).focus(); this._isOpen = true; this._trigger( "open" ); return this; }, _createButtons: function( buttons ) { var that = this, hasButtons = false; // if we already have a button pane, remove it this.uiDialogButtonPane.remove(); this.uiButtonSet.empty(); if ( typeof buttons === "object" && buttons !== null ) { $.each( buttons, function() { return !(hasButtons = true); }); } if ( hasButtons ) { $.each( buttons, function( name, props ) { var button, click; props = $.isFunction( props ) ? { click: props, text: name } : props; // Default to a non-submitting button props = $.extend( { type: "button" }, props ); // Change the context for the click callback to be the main element click = props.click; props.click = function() { click.apply( that.element[0], arguments ); }; button = $( "", props ) .appendTo( that.uiButtonSet ); if ( $.fn.button ) { button.button(); } }); this.uiDialog.addClass( "ui-dialog-buttons" ); this.uiDialogButtonPane.appendTo( this.uiDialog ); } else { this.uiDialog.removeClass( "ui-dialog-buttons" ); } }, _makeDraggable: function() { var that = this, options = this.options; function filteredUi( ui ) { return { position: ui.position, offset: ui.offset }; } this.uiDialog.draggable({ cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", handle: ".ui-dialog-titlebar", containment: "document", start: function( event, ui ) { $( this ) .addClass( "ui-dialog-dragging" ); that._trigger( "dragStart", event, filteredUi( ui ) ); }, drag: function( event, ui ) { that._trigger( "drag", event, filteredUi( ui ) ); }, stop: function( event, ui ) { options.position = [ ui.position.left - that.document.scrollLeft(), ui.position.top - that.document.scrollTop() ]; $( this ) .removeClass( "ui-dialog-dragging" ); that._trigger( "dragStop", event, filteredUi( ui ) ); $.ui.dialog.overlay.resize(); } }); }, _makeResizable: function( handles ) { handles = (handles === undefined ? this.options.resizable : handles); var that = this, options = this.options, // .ui-resizable has position: relative defined in the stylesheet // but dialogs have to use absolute or fixed positioning position = this.uiDialog.css( "position" ), resizeHandles = typeof handles === 'string' ? handles : "n,e,s,w,se,sw,ne,nw"; function filteredUi( ui ) { return { originalPosition: ui.originalPosition, originalSize: ui.originalSize, position: ui.position, size: ui.size }; } this.uiDialog.resizable({ cancel: ".ui-dialog-content", containment: "document", alsoResize: this.element, maxWidth: options.maxWidth, maxHeight: options.maxHeight, minWidth: options.minWidth, minHeight: this._minHeight(), handles: resizeHandles, start: function( event, ui ) { $( this ).addClass( "ui-dialog-resizing" ); that._trigger( "resizeStart", event, filteredUi( ui ) ); }, resize: function( event, ui ) { that._trigger( "resize", event, filteredUi( ui ) ); }, stop: function( event, ui ) { $( this ).removeClass( "ui-dialog-resizing" ); options.height = $( this ).height(); options.width = $( this ).width(); that._trigger( "resizeStop", event, filteredUi( ui ) ); $.ui.dialog.overlay.resize(); } }) .css( "position", position ) .find( ".ui-resizable-se" ) .addClass( "ui-icon ui-icon-grip-diagonal-se" ); }, _minHeight: function() { var options = this.options; if ( options.height === "auto" ) { return options.minHeight; } else { return Math.min( options.minHeight, options.height ); } }, _position: function( position ) { var myAt = [], offset = [ 0, 0 ], isVisible; if ( position ) { // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( // if (typeof position == 'string' || $.isArray(position)) { // myAt = $.isArray(position) ? position : position.split(' '); if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; if ( myAt.length === 1 ) { myAt[ 1 ] = myAt[ 0 ]; } $.each( [ "left", "top" ], function( i, offsetPosition ) { if ( +myAt[ i ] === myAt[ i ] ) { offset[ i ] = myAt[ i ]; myAt[ i ] = offsetPosition; } }); position = { my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), at: myAt.join( " " ) }; } position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); } else { position = $.ui.dialog.prototype.options.position; } // need to show the dialog to get the actual offset in the position plugin isVisible = this.uiDialog.is( ":visible" ); if ( !isVisible ) { this.uiDialog.show(); } this.uiDialog.position( position ); if ( !isVisible ) { this.uiDialog.hide(); } }, _setOptions: function( options ) { var that = this, resizableOptions = {}, resize = false; $.each( options, function( key, value ) { that._setOption( key, value ); if ( key in sizeRelatedOptions ) { resize = true; } if ( key in resizableRelatedOptions ) { resizableOptions[ key ] = value; } }); if ( resize ) { this._size(); } if ( this.uiDialog.is( ":data(resizable)" ) ) { this.uiDialog.resizable( "option", resizableOptions ); } }, _setOption: function( key, value ) { var isDraggable, isResizable, uiDialog = this.uiDialog; switch ( key ) { case "buttons": this._createButtons( value ); break; case "closeText": // ensure that we always pass a string this.uiDialogTitlebarCloseText.text( "" + value ); break; case "dialogClass": uiDialog .removeClass( this.options.dialogClass ) .addClass( uiDialogClasses + value ); break; case "disabled": if ( value ) { uiDialog.addClass( "ui-dialog-disabled" ); } else { uiDialog.removeClass( "ui-dialog-disabled" ); } break; case "draggable": isDraggable = uiDialog.is( ":data(draggable)" ); if ( isDraggable && !value ) { uiDialog.draggable( "destroy" ); } if ( !isDraggable && value ) { this._makeDraggable(); } break; case "position": this._position( value ); break; case "resizable": // currently resizable, becoming non-resizable isResizable = uiDialog.is( ":data(resizable)" ); if ( isResizable && !value ) { uiDialog.resizable( "destroy" ); } // currently resizable, changing handles if ( isResizable && typeof value === "string" ) { uiDialog.resizable( "option", "handles", value ); } // currently non-resizable, becoming resizable if ( !isResizable && value !== false ) { this._makeResizable( value ); } break; case "title": // convert whatever was passed in o a string, for html() to not throw up $( ".ui-dialog-title", this.uiDialogTitlebar ) .html( "" + ( value || " " ) ); break; } this._super( key, value ); }, _size: function() { /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content * divs will both have width and height set, so we need to reset them */ var nonContentHeight, minContentHeight, autoHeight, options = this.options, isVisible = this.uiDialog.is( ":visible" ); // reset content sizing this.element.show().css({ width: "auto", minHeight: 0, height: 0 }); if ( options.minWidth > options.width ) { options.width = options.minWidth; } // reset wrapper sizing // determine the height of all the non-content elements nonContentHeight = this.uiDialog.css({ height: "auto", width: options.width }) .outerHeight(); minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); if ( options.height === "auto" ) { // only needed for IE6 support if ( $.support.minHeight ) { this.element.css({ minHeight: minContentHeight, height: "auto" }); } else { this.uiDialog.show(); autoHeight = this.element.css( "height", "auto" ).height(); if ( !isVisible ) { this.uiDialog.hide(); } this.element.height( Math.max( autoHeight, minContentHeight ) ); } } else { this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); } if (this.uiDialog.is( ":data(resizable)" ) ) { this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); } } }); $.extend($.ui.dialog, { uuid: 0, maxZ: 0, getTitleId: function($el) { var id = $el.attr( "id" ); if ( !id ) { this.uuid += 1; id = this.uuid; } return "ui-dialog-title-" + id; }, overlay: function( dialog ) { this.$el = $.ui.dialog.overlay.create( dialog ); } }); $.extend( $.ui.dialog.overlay, { instances: [], // reuse old instances due to IE memory leak with alpha transparency (see #5185) oldInstances: [], maxZ: 0, events: $.map( "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), function( event ) { return event + ".dialog-overlay"; } ).join( " " ), create: function( dialog ) { if ( this.instances.length === 0 ) { // prevent use of anchors and inputs // we use a setTimeout in case the overlay is created from an // event that we're going to be cancelling (see #2804) setTimeout(function() { // handle $(el).dialog().dialog('close') (see #4065) if ( $.ui.dialog.overlay.instances.length ) { $( document ).bind( $.ui.dialog.overlay.events, function( event ) { // stop events if the z-index of the target is < the z-index of the overlay // we cannot return true when we don't want to cancel the event (#3523) if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { return false; } }); } }, 1 ); // handle window resize $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); } var $el = ( this.oldInstances.pop() || $( "
" ).addClass( "ui-widget-overlay" ) ); // allow closing by pressing the escape key $( document ).bind( "keydown.dialog-overlay", function( event ) { var instances = $.ui.dialog.overlay.instances; // only react to the event if we're the top overlay if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el && dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && event.keyCode === $.ui.keyCode.ESCAPE ) { dialog.close( event ); event.preventDefault(); } }); $el.appendTo( document.body ).css({ width: this.width(), height: this.height() }); if ( $.fn.bgiframe ) { $el.bgiframe(); } this.instances.push( $el ); return $el; }, destroy: function( $el ) { var indexOf = $.inArray( $el, this.instances ), maxZ = 0; if ( indexOf !== -1 ) { this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); } if ( this.instances.length === 0 ) { $( [ document, window ] ).unbind( ".dialog-overlay" ); } $el.height( 0 ).width( 0 ).remove(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) $.each( this.instances, function() { maxZ = Math.max( maxZ, this.css( "z-index" ) ); }); this.maxZ = maxZ; }, height: function() { var scrollHeight, offsetHeight; // handle IE if ( $.ui.ie ) { scrollHeight = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight ); offsetHeight = Math.max( document.documentElement.offsetHeight, document.body.offsetHeight ); if ( scrollHeight < offsetHeight ) { return $( window ).height() + "px"; } else { return scrollHeight + "px"; } // handle "good" browsers } else { return $( document ).height() + "px"; } }, width: function() { var scrollWidth, offsetWidth; // handle IE if ( $.ui.ie ) { scrollWidth = Math.max( document.documentElement.scrollWidth, document.body.scrollWidth ); offsetWidth = Math.max( document.documentElement.offsetWidth, document.body.offsetWidth ); if ( scrollWidth < offsetWidth ) { return $( window ).width() + "px"; } else { return scrollWidth + "px"; } // handle "good" browsers } else { return $( document ).width() + "px"; } }, resize: function() { /* If the dialog is draggable and the user drags it past the * right edge of the window, the document becomes wider so we * need to stretch the overlay. If the user then drags the * dialog back to the left, the document will become narrower, * so we need to shrink the overlay to the appropriate size. * This is handled by shrinking the overlay before setting it * to the full document size. */ var $overlays = $( [] ); $.each( $.ui.dialog.overlay.instances, function() { $overlays = $overlays.add( this ); }); $overlays.css({ width: 0, height: 0 }).css({ width: $.ui.dialog.overlay.width(), height: $.ui.dialog.overlay.height() }); } }); $.extend( $.ui.dialog.overlay.prototype, { destroy: function() { $.ui.dialog.overlay.destroy( this.$el ); } }); }( jQuery ) ); (function( $, undefined ) { var rvertical = /up|down|vertical/, rpositivemotion = /up|left|vertical|horizontal/; $.effects.effect.blind = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.effects.setMode( el, o.mode || "hide" ), direction = o.direction || "up", vertical = rvertical.test( direction ), ref = vertical ? "height" : "width", ref2 = vertical ? "top" : "left", motion = rpositivemotion.test( direction ), animation = {}, show = mode === "show", wrapper, distance, margin; // if already wrapped, the wrapper's properties are my property. #6245 if ( el.parent().is( ".ui-effects-wrapper" ) ) { $.effects.save( el.parent(), props ); } else { $.effects.save( el, props ); } el.show(); wrapper = $.effects.createWrapper( el ).css({ overflow: "hidden" }); distance = wrapper[ ref ](); margin = parseFloat( wrapper.css( ref2 ) ) || 0; animation[ ref ] = show ? distance : 0; if ( !motion ) { el .css( vertical ? "bottom" : "right", 0 ) .css( vertical ? "top" : "left", "auto" ) .css({ position: "absolute" }); animation[ ref2 ] = show ? margin : distance + margin; } // start at 0 if we are showing if ( show ) { wrapper.css( ref, 0 ); if ( ! motion ) { wrapper.css( ref2, margin + distance ); } } // Animate wrapper.animate( animation, { duration: o.duration, easing: o.easing, queue: false, complete: function() { if ( mode === "hide" ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.bounce = function( o, done ) { var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], // defaults: mode = $.effects.setMode( el, o.mode || "effect" ), hide = mode === "hide", show = mode === "show", direction = o.direction || "up", distance = o.distance, times = o.times || 5, // number of internal animations anims = times * 2 + ( show || hide ? 1 : 0 ), speed = o.duration / anims, easing = o.easing, // utility: ref = ( direction === "up" || direction === "down" ) ? "top" : "left", motion = ( direction === "up" || direction === "left" ), i, upAnim, downAnim, // we will need to re-assemble the queue to stack our animations in place queue = el.queue(), queuelen = queue.length; // Avoid touching opacity to prevent clearType and PNG issues in IE if ( show || hide ) { props.push( "opacity" ); } $.effects.save( el, props ); el.show(); $.effects.createWrapper( el ); // Create Wrapper // default distance for the BIGGEST bounce is the outer Distance / 3 if ( !distance ) { distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; } if ( show ) { downAnim = { opacity: 1 }; downAnim[ ref ] = 0; // if we are showing, force opacity 0 and set the initial position // then do the "first" animation el.css( "opacity", 0 ) .css( ref, motion ? -distance * 2 : distance * 2 ) .animate( downAnim, speed, easing ); } // start at the smallest distance if we are hiding if ( hide ) { distance = distance / Math.pow( 2, times - 1 ); } downAnim = {}; downAnim[ ref ] = 0; // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here for ( i = 0; i < times; i++ ) { upAnim = {}; upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; el.animate( upAnim, speed, easing ) .animate( downAnim, speed, easing ); distance = hide ? distance * 2 : distance / 2; } // Last Bounce when Hiding if ( hide ) { upAnim = { opacity: 0 }; upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; el.animate( upAnim, speed, easing ); } el.queue(function() { if ( hide ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); }); // inject all the animations we just queued to be first in line (after "inprogress") if ( queuelen > 1) { queue.splice.apply( queue, [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); } el.dequeue(); }; })(jQuery); (function( $, undefined ) { $.effects.effect.clip = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.effects.setMode( el, o.mode || "hide" ), show = mode === "show", direction = o.direction || "vertical", vert = direction === "vertical", size = vert ? "height" : "width", position = vert ? "top" : "left", animation = {}, wrapper, animate, distance; // Save & Show $.effects.save( el, props ); el.show(); // Create Wrapper wrapper = $.effects.createWrapper( el ).css({ overflow: "hidden" }); animate = ( el[0].tagName === "IMG" ) ? wrapper : el; distance = animate[ size ](); // Shift if ( show ) { animate.css( size, 0 ); animate.css( position, distance / 2 ); } // Create Animation Object: animation[ size ] = show ? distance : 0; animation[ position ] = show ? 0 : distance / 2; // Animate animate.animate( animation, { queue: false, duration: o.duration, easing: o.easing, complete: function() { if ( !show ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.drop = function( o, done ) { var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], mode = $.effects.setMode( el, o.mode || "hide" ), show = mode === "show", direction = o.direction || "left", ref = ( direction === "up" || direction === "down" ) ? "top" : "left", motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", animation = { opacity: show ? 1 : 0 }, distance; // Adjust $.effects.save( el, props ); el.show(); $.effects.createWrapper( el ); distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; if ( show ) { el .css( "opacity", 0 ) .css( ref, motion === "pos" ? -distance : distance ); } // Animation animation[ ref ] = ( show ? ( motion === "pos" ? "+=" : "-=" ) : ( motion === "pos" ? "-=" : "+=" ) ) + distance; // Animate el.animate( animation, { queue: false, duration: o.duration, easing: o.easing, complete: function() { if ( mode === "hide" ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.explode = function( o, done ) { var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, cells = rows, el = $( this ), mode = $.effects.setMode( el, o.mode || "hide" ), show = mode === "show", // show and then visibility:hidden the element before calculating offset offset = el.show().css( "visibility", "hidden" ).offset(), // width and height of a piece width = Math.ceil( el.outerWidth() / cells ), height = Math.ceil( el.outerHeight() / rows ), pieces = [], // loop i, j, left, top, mx, my; // children animate complete: function childComplete() { pieces.push( this ); if ( pieces.length === rows * cells ) { animComplete(); } } // clone the element for each row and cell. for( i = 0; i < rows ; i++ ) { // ===> top = offset.top + i * height; my = i - ( rows - 1 ) / 2 ; for( j = 0; j < cells ; j++ ) { // ||| left = offset.left + j * width; mx = j - ( cells - 1 ) / 2 ; // Create a clone of the now hidden main element that will be absolute positioned // within a wrapper div off the -left and -top equal to size of our pieces el .clone() .appendTo( "body" ) .wrap( "
" ) .css({ position: "absolute", visibility: "visible", left: -j * width, top: -i * height }) // select the wrapper - make it overflow: hidden and absolute positioned based on // where the original was located +left and +top equal to the size of pieces .parent() .addClass( "ui-effects-explode" ) .css({ position: "absolute", overflow: "hidden", width: width, height: height, left: left + ( show ? mx * width : 0 ), top: top + ( show ? my * height : 0 ), opacity: show ? 0 : 1 }).animate({ left: left + ( show ? 0 : mx * width ), top: top + ( show ? 0 : my * height ), opacity: show ? 1 : 0 }, o.duration || 500, o.easing, childComplete ); } } function animComplete() { el.css({ visibility: "visible" }); $( pieces ).remove(); if ( !show ) { el.hide(); } done(); } }; })(jQuery); (function( $, undefined ) { $.effects.effect.fade = function( o, done ) { var el = $( this ), mode = $.effects.setMode( el, o.mode || "toggle" ); el.animate({ opacity: mode }, { queue: false, duration: o.duration, easing: o.easing, complete: done }); }; })( jQuery ); (function( $, undefined ) { $.effects.effect.fold = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.effects.setMode( el, o.mode || "hide" ), show = mode === "show", hide = mode === "hide", size = o.size || 15, percent = /([0-9]+)%/.exec( size ), horizFirst = !!o.horizFirst, widthFirst = show !== horizFirst, ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], duration = o.duration / 2, wrapper, distance, animation1 = {}, animation2 = {}; $.effects.save( el, props ); el.show(); // Create Wrapper wrapper = $.effects.createWrapper( el ).css({ overflow: "hidden" }); distance = widthFirst ? [ wrapper.width(), wrapper.height() ] : [ wrapper.height(), wrapper.width() ]; if ( percent ) { size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; } if ( show ) { wrapper.css( horizFirst ? { height: 0, width: size } : { height: size, width: 0 }); } // Animation animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; // Animate wrapper .animate( animation1, duration, o.easing ) .animate( animation2, duration, o.easing, function() { if ( hide ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.highlight = function( o, done ) { var elem = $( this ), props = [ "backgroundImage", "backgroundColor", "opacity" ], mode = $.effects.setMode( elem, o.mode || "show" ), animation = { backgroundColor: elem.css( "backgroundColor" ) }; if (mode === "hide") { animation.opacity = 0; } $.effects.save( elem, props ); elem .show() .css({ backgroundImage: "none", backgroundColor: o.color || "#ffff99" }) .animate( animation, { queue: false, duration: o.duration, easing: o.easing, complete: function() { if ( mode === "hide" ) { elem.hide(); } $.effects.restore( elem, props ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.pulsate = function( o, done ) { var elem = $( this ), mode = $.effects.setMode( elem, o.mode || "show" ), show = mode === "show", hide = mode === "hide", showhide = ( show || mode === "hide" ), // showing or hiding leaves of the "last" animation anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), duration = o.duration / anims, animateTo = 0, queue = elem.queue(), queuelen = queue.length, i; if ( show || !elem.is(":visible")) { elem.css( "opacity", 0 ).show(); animateTo = 1; } // anims - 1 opacity "toggles" for ( i = 1; i < anims; i++ ) { elem.animate({ opacity: animateTo }, duration, o.easing ); animateTo = 1 - animateTo; } elem.animate({ opacity: animateTo }, duration, o.easing); elem.queue(function() { if ( hide ) { elem.hide(); } done(); }); // We just queued up "anims" animations, we need to put them next in the queue if ( queuelen > 1 ) { queue.splice.apply( queue, [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); } elem.dequeue(); }; })(jQuery); (function( $, undefined ) { $.effects.effect.puff = function( o, done ) { var elem = $( this ), mode = $.effects.setMode( elem, o.mode || "hide" ), hide = mode === "hide", percent = parseInt( o.percent, 10 ) || 150, factor = percent / 100, original = { height: elem.height(), width: elem.width(), outerHeight: elem.outerHeight(), outerWidth: elem.outerWidth() }; $.extend( o, { effect: "scale", queue: false, fade: true, mode: mode, complete: done, percent: hide ? percent : 100, from: hide ? original : { height: original.height * factor, width: original.width * factor, outerHeight: original.outerHeight * factor, outerWidth: original.outerWidth * factor } }); elem.effect( o ); }; $.effects.effect.scale = function( o, done ) { // Create element var el = $( this ), options = $.extend( true, {}, o ), mode = $.effects.setMode( el, o.mode || "effect" ), percent = parseInt( o.percent, 10 ) || ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), direction = o.direction || "both", origin = o.origin, original = { height: el.height(), width: el.width(), outerHeight: el.outerHeight(), outerWidth: el.outerWidth() }, factor = { y: direction !== "horizontal" ? (percent / 100) : 1, x: direction !== "vertical" ? (percent / 100) : 1 }; // We are going to pass this effect to the size effect: options.effect = "size"; options.queue = false; options.complete = done; // Set default origin and restore for show/hide if ( mode !== "effect" ) { options.origin = origin || ["middle","center"]; options.restore = true; } options.from = o.from || ( mode === "show" ? { height: 0, width: 0, outerHeight: 0, outerWidth: 0 } : original ); options.to = { height: original.height * factor.y, width: original.width * factor.x, outerHeight: original.outerHeight * factor.y, outerWidth: original.outerWidth * factor.x }; // Fade option to support puff if ( options.fade ) { if ( mode === "show" ) { options.from.opacity = 0; options.to.opacity = 1; } if ( mode === "hide" ) { options.from.opacity = 1; options.to.opacity = 0; } } // Animate el.effect( options ); }; $.effects.effect.size = function( o, done ) { // Create element var original, baseline, factor, el = $( this ), props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], // Always restore props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], // Copy for children props2 = [ "width", "height", "overflow" ], cProps = [ "fontSize" ], vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], // Set options mode = $.effects.setMode( el, o.mode || "effect" ), restore = o.restore || mode !== "effect", scale = o.scale || "both", origin = o.origin || [ "middle", "center" ], position = el.css( "position" ), props = restore ? props0 : props1, zero = { height: 0, width: 0, outerHeight: 0, outerWidth: 0 }; if ( mode === "show" ) { el.show(); } original = { height: el.height(), width: el.width(), outerHeight: el.outerHeight(), outerWidth: el.outerWidth() }; if ( o.mode === "toggle" && mode === "show" ) { el.from = o.to || zero; el.to = o.from || original; } else { el.from = o.from || ( mode === "show" ? zero : original ); el.to = o.to || ( mode === "hide" ? zero : original ); } // Set scaling factor factor = { from: { y: el.from.height / original.height, x: el.from.width / original.width }, to: { y: el.to.height / original.height, x: el.to.width / original.width } }; // Scale the css box if ( scale === "box" || scale === "both" ) { // Vertical props scaling if ( factor.from.y !== factor.to.y ) { props = props.concat( vProps ); el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); } // Horizontal props scaling if ( factor.from.x !== factor.to.x ) { props = props.concat( hProps ); el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); } } // Scale the content if ( scale === "content" || scale === "both" ) { // Vertical props scaling if ( factor.from.y !== factor.to.y ) { props = props.concat( cProps ).concat( props2 ); el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); } } $.effects.save( el, props ); el.show(); $.effects.createWrapper( el ); el.css( "overflow", "hidden" ).css( el.from ); // Adjust if (origin) { // Calculate baseline shifts baseline = $.effects.getBaseline( origin, original ); el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; } el.css( el.from ); // set top & left // Animate if ( scale === "content" || scale === "both" ) { // Scale the children // Add margins/font-size vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); hProps = hProps.concat([ "marginLeft", "marginRight" ]); props2 = props0.concat(vProps).concat(hProps); el.find( "*[width]" ).each( function(){ var child = $( this ), c_original = { height: child.height(), width: child.width(), outerHeight: child.outerHeight(), outerWidth: child.outerWidth() }; if (restore) { $.effects.save(child, props2); } child.from = { height: c_original.height * factor.from.y, width: c_original.width * factor.from.x, outerHeight: c_original.outerHeight * factor.from.y, outerWidth: c_original.outerWidth * factor.from.x }; child.to = { height: c_original.height * factor.to.y, width: c_original.width * factor.to.x, outerHeight: c_original.height * factor.to.y, outerWidth: c_original.width * factor.to.x }; // Vertical props scaling if ( factor.from.y !== factor.to.y ) { child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); } // Horizontal props scaling if ( factor.from.x !== factor.to.x ) { child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); } // Animate children child.css( child.from ); child.animate( child.to, o.duration, o.easing, function() { // Restore children if ( restore ) { $.effects.restore( child, props2 ); } }); }); } // Animate el.animate( el.to, { queue: false, duration: o.duration, easing: o.easing, complete: function() { if ( el.to.opacity === 0 ) { el.css( "opacity", el.from.opacity ); } if( mode === "hide" ) { el.hide(); } $.effects.restore( el, props ); if ( !restore ) { // we need to calculate our new positioning based on the scaling if ( position === "static" ) { el.css({ position: "relative", top: el.to.top, left: el.to.left }); } else { $.each([ "top", "left" ], function( idx, pos ) { el.css( pos, function( _, str ) { var val = parseInt( str, 10 ), toRef = idx ? el.to.left : el.to.top; // if original was "auto", recalculate the new value from wrapper if ( str === "auto" ) { return toRef + "px"; } return val + toRef + "px"; }); }); } } $.effects.removeWrapper( el ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.shake = function( o, done ) { var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.effects.setMode( el, o.mode || "effect" ), direction = o.direction || "left", distance = o.distance || 20, times = o.times || 3, anims = times * 2 + 1, speed = Math.round(o.duration/anims), ref = (direction === "up" || direction === "down") ? "top" : "left", positiveMotion = (direction === "up" || direction === "left"), animation = {}, animation1 = {}, animation2 = {}, i, // we will need to re-assemble the queue to stack our animations in place queue = el.queue(), queuelen = queue.length; $.effects.save( el, props ); el.show(); $.effects.createWrapper( el ); // Animation animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; // Animate el.animate( animation, speed, o.easing ); // Shakes for ( i = 1; i < times; i++ ) { el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); } el .animate( animation1, speed, o.easing ) .animate( animation, speed / 2, o.easing ) .queue(function() { if ( mode === "hide" ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); }); // inject all the animations we just queued to be first in line (after "inprogress") if ( queuelen > 1) { queue.splice.apply( queue, [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); } el.dequeue(); }; })(jQuery); (function( $, undefined ) { $.effects.effect.slide = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "width", "height" ], mode = $.effects.setMode( el, o.mode || "show" ), show = mode === "show", direction = o.direction || "left", ref = (direction === "up" || direction === "down") ? "top" : "left", positiveMotion = (direction === "up" || direction === "left"), distance, animation = {}; // Adjust $.effects.save( el, props ); el.show(); distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); $.effects.createWrapper( el ).css({ overflow: "hidden" }); if ( show ) { el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); } // Animation animation[ ref ] = ( show ? ( positiveMotion ? "+=" : "-=") : ( positiveMotion ? "-=" : "+=")) + distance; // Animate el.animate( animation, { queue: false, duration: o.duration, easing: o.easing, complete: function() { if ( mode === "hide" ) { el.hide(); } $.effects.restore( el, props ); $.effects.removeWrapper( el ); done(); } }); }; })(jQuery); (function( $, undefined ) { $.effects.effect.transfer = function( o, done ) { var elem = $( this ), target = $( o.to ), targetFixed = target.css( "position" ) === "fixed", body = $("body"), fixTop = targetFixed ? body.scrollTop() : 0, fixLeft = targetFixed ? body.scrollLeft() : 0, endPosition = target.offset(), animation = { top: endPosition.top - fixTop , left: endPosition.left - fixLeft , height: target.innerHeight(), width: target.innerWidth() }, startPosition = elem.offset(), transfer = $( '
' ) .appendTo( document.body ) .addClass( o.className ) .css({ top: startPosition.top - fixTop , left: startPosition.left - fixLeft , height: elem.innerHeight(), width: elem.innerWidth(), position: targetFixed ? "fixed" : "absolute" }) .animate( animation, o.duration, o.easing, function() { transfer.remove(); done(); }); }; })(jQuery); (function( $, undefined ) { var mouseHandled = false; $.widget( "ui.menu", { version: "1.9.2", defaultElement: "
    ", delay: 300, options: { icons: { submenu: "ui-icon-carat-1-e" }, menus: "ul", position: { my: "left top", at: "right top" }, role: "menu", // callbacks blur: null, focus: null, select: null }, _create: function() { this.activeMenu = this.element; this.element .uniqueId() .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) .attr({ role: this.options.role, tabIndex: 0 }) // need to catch all clicks on disabled menu // not possible through _on .bind( "click" + this.eventNamespace, $.proxy(function( event ) { if ( this.options.disabled ) { event.preventDefault(); } }, this )); if ( this.options.disabled ) { this.element .addClass( "ui-state-disabled" ) .attr( "aria-disabled", "true" ); } this._on({ // Prevent focus from sticking to links inside menu after clicking // them (focus should always stay on UL during navigation). "mousedown .ui-menu-item > a": function( event ) { event.preventDefault(); }, "click .ui-state-disabled > a": function( event ) { event.preventDefault(); }, "click .ui-menu-item:has(a)": function( event ) { var target = $( event.target ).closest( ".ui-menu-item" ); if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) { mouseHandled = true; this.select( event ); // Open submenu on click if ( target.has( ".ui-menu" ).length ) { this.expand( event ); } else if ( !this.element.is( ":focus" ) ) { // Redirect focus to the menu this.element.trigger( "focus", [ true ] ); // If the active item is on the top level, let it stay active. // Otherwise, blur the active item since it is no longer visible. if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { clearTimeout( this.timer ); } } } }, "mouseenter .ui-menu-item": function( event ) { var target = $( event.currentTarget ); // Remove ui-state-active class from siblings of the newly focused menu item // to avoid a jump caused by adjacent elements both having a class with a border target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); this.focus( event, target ); }, mouseleave: "collapseAll", "mouseleave .ui-menu": "collapseAll", focus: function( event, keepActiveItem ) { // If there's already an active item, keep it active // If not, activate the first item var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); if ( !keepActiveItem ) { this.focus( event, item ); } }, blur: function( event ) { this._delay(function() { if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { this.collapseAll( event ); } }); }, keydown: "_keydown" }); this.refresh(); // Clicks outside of a menu collapse any open menus this._on( this.document, { click: function( event ) { if ( !$( event.target ).closest( ".ui-menu" ).length ) { this.collapseAll( event ); } // Reset the mouseHandled flag mouseHandled = false; } }); }, _destroy: function() { // Destroy (sub)menus this.element .removeAttr( "aria-activedescendant" ) .find( ".ui-menu" ).andSelf() .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) .removeAttr( "role" ) .removeAttr( "tabIndex" ) .removeAttr( "aria-labelledby" ) .removeAttr( "aria-expanded" ) .removeAttr( "aria-hidden" ) .removeAttr( "aria-disabled" ) .removeUniqueId() .show(); // Destroy menu items this.element.find( ".ui-menu-item" ) .removeClass( "ui-menu-item" ) .removeAttr( "role" ) .removeAttr( "aria-disabled" ) .children( "a" ) .removeUniqueId() .removeClass( "ui-corner-all ui-state-hover" ) .removeAttr( "tabIndex" ) .removeAttr( "role" ) .removeAttr( "aria-haspopup" ) .children().each( function() { var elem = $( this ); if ( elem.data( "ui-menu-submenu-carat" ) ) { elem.remove(); } }); // Destroy menu dividers this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); }, _keydown: function( event ) { var match, prev, character, skip, regex, preventDefault = true; function escape( value ) { return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); } switch ( event.keyCode ) { case $.ui.keyCode.PAGE_UP: this.previousPage( event ); break; case $.ui.keyCode.PAGE_DOWN: this.nextPage( event ); break; case $.ui.keyCode.HOME: this._move( "first", "first", event ); break; case $.ui.keyCode.END: this._move( "last", "last", event ); break; case $.ui.keyCode.UP: this.previous( event ); break; case $.ui.keyCode.DOWN: this.next( event ); break; case $.ui.keyCode.LEFT: this.collapse( event ); break; case $.ui.keyCode.RIGHT: if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { this.expand( event ); } break; case $.ui.keyCode.ENTER: case $.ui.keyCode.SPACE: this._activate( event ); break; case $.ui.keyCode.ESCAPE: this.collapse( event ); break; default: preventDefault = false; prev = this.previousFilter || ""; character = String.fromCharCode( event.keyCode ); skip = false; clearTimeout( this.filterTimer ); if ( character === prev ) { skip = true; } else { character = prev + character; } regex = new RegExp( "^" + escape( character ), "i" ); match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { return regex.test( $( this ).children( "a" ).text() ); }); match = skip && match.index( this.active.next() ) !== -1 ? this.active.nextAll( ".ui-menu-item" ) : match; // If no matches on the current filter, reset to the last character pressed // to move down the menu to the first item that starts with that character if ( !match.length ) { character = String.fromCharCode( event.keyCode ); regex = new RegExp( "^" + escape( character ), "i" ); match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { return regex.test( $( this ).children( "a" ).text() ); }); } if ( match.length ) { this.focus( event, match ); if ( match.length > 1 ) { this.previousFilter = character; this.filterTimer = this._delay(function() { delete this.previousFilter; }, 1000 ); } else { delete this.previousFilter; } } else { delete this.previousFilter; } } if ( preventDefault ) { event.preventDefault(); } }, _activate: function( event ) { if ( !this.active.is( ".ui-state-disabled" ) ) { if ( this.active.children( "a[aria-haspopup='true']" ).length ) { this.expand( event ); } else { this.select( event ); } } }, refresh: function() { var menus, icon = this.options.icons.submenu, submenus = this.element.find( this.options.menus ); // Initialize nested menus submenus.filter( ":not(.ui-menu)" ) .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() .attr({ role: this.options.role, "aria-hidden": "true", "aria-expanded": "false" }) .each(function() { var menu = $( this ), item = menu.prev( "a" ), submenuCarat = $( "" ) .addClass( "ui-menu-icon ui-icon " + icon ) .data( "ui-menu-submenu-carat", true ); item .attr( "aria-haspopup", "true" ) .prepend( submenuCarat ); menu.attr( "aria-labelledby", item.attr( "id" ) ); }); menus = submenus.add( this.element ); // Don't refresh list items that are already adapted menus.children( ":not(.ui-menu-item):has(a)" ) .addClass( "ui-menu-item" ) .attr( "role", "presentation" ) .children( "a" ) .uniqueId() .addClass( "ui-corner-all" ) .attr({ tabIndex: -1, role: this._itemRole() }); // Initialize unlinked menu-items containing spaces and/or dashes only as dividers menus.children( ":not(.ui-menu-item)" ).each(function() { var item = $( this ); // hyphen, em dash, en dash if ( !/[^\-—–\s]/.test( item.text() ) ) { item.addClass( "ui-widget-content ui-menu-divider" ); } }); // Add aria-disabled attribute to any disabled menu item menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); // If the active item has been removed, blur the menu if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { this.blur(); } }, _itemRole: function() { return { menu: "menuitem", listbox: "option" }[ this.options.role ]; }, focus: function( event, item ) { var nested, focused; this.blur( event, event && event.type === "focus" ); this._scrollIntoView( item ); this.active = item.first(); focused = this.active.children( "a" ).addClass( "ui-state-focus" ); // Only update aria-activedescendant if there's a role // otherwise we assume focus is managed elsewhere if ( this.options.role ) { this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); } // Highlight active parent menu item, if any this.active .parent() .closest( ".ui-menu-item" ) .children( "a:first" ) .addClass( "ui-state-active" ); if ( event && event.type === "keydown" ) { this._close(); } else { this.timer = this._delay(function() { this._close(); }, this.delay ); } nested = item.children( ".ui-menu" ); if ( nested.length && ( /^mouse/.test( event.type ) ) ) { this._startOpening(nested); } this.activeMenu = item.parent(); this._trigger( "focus", event, { item: item } ); }, _scrollIntoView: function( item ) { var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; if ( this._hasScroll() ) { borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; scroll = this.activeMenu.scrollTop(); elementHeight = this.activeMenu.height(); itemHeight = item.height(); if ( offset < 0 ) { this.activeMenu.scrollTop( scroll + offset ); } else if ( offset + itemHeight > elementHeight ) { this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); } } }, blur: function( event, fromFocus ) { if ( !fromFocus ) { clearTimeout( this.timer ); } if ( !this.active ) { return; } this.active.children( "a" ).removeClass( "ui-state-focus" ); this.active = null; this._trigger( "blur", event, { item: this.active } ); }, _startOpening: function( submenu ) { clearTimeout( this.timer ); // Don't open if already open fixes a Firefox bug that caused a .5 pixel // shift in the submenu position when mousing over the carat icon if ( submenu.attr( "aria-hidden" ) !== "true" ) { return; } this.timer = this._delay(function() { this._close(); this._open( submenu ); }, this.delay ); }, _open: function( submenu ) { var position = $.extend({ of: this.active }, this.options.position ); clearTimeout( this.timer ); this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) .hide() .attr( "aria-hidden", "true" ); submenu .show() .removeAttr( "aria-hidden" ) .attr( "aria-expanded", "true" ) .position( position ); }, collapseAll: function( event, all ) { clearTimeout( this.timer ); this.timer = this._delay(function() { // If we were passed an event, look for the submenu that contains the event var currentMenu = all ? this.element : $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway if ( !currentMenu.length ) { currentMenu = this.element; } this._close( currentMenu ); this.blur( event ); this.activeMenu = currentMenu; }, this.delay ); }, // With no arguments, closes the currently active menu - if nothing is active // it closes all menus. If passed an argument, it will search for menus BELOW _close: function( startMenu ) { if ( !startMenu ) { startMenu = this.active ? this.active.parent() : this.element; } startMenu .find( ".ui-menu" ) .hide() .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ) .end() .find( "a.ui-state-active" ) .removeClass( "ui-state-active" ); }, collapse: function( event ) { var newItem = this.active && this.active.parent().closest( ".ui-menu-item", this.element ); if ( newItem && newItem.length ) { this._close(); this.focus( event, newItem ); } }, expand: function( event ) { var newItem = this.active && this.active .children( ".ui-menu " ) .children( ".ui-menu-item" ) .first(); if ( newItem && newItem.length ) { this._open( newItem.parent() ); // Delay so Firefox will not hide activedescendant change in expanding submenu from AT this._delay(function() { this.focus( event, newItem ); }); } }, next: function( event ) { this._move( "next", "first", event ); }, previous: function( event ) { this._move( "prev", "last", event ); }, isFirstItem: function() { return this.active && !this.active.prevAll( ".ui-menu-item" ).length; }, isLastItem: function() { return this.active && !this.active.nextAll( ".ui-menu-item" ).length; }, _move: function( direction, filter, event ) { var next; if ( this.active ) { if ( direction === "first" || direction === "last" ) { next = this.active [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) .eq( -1 ); } else { next = this.active [ direction + "All" ]( ".ui-menu-item" ) .eq( 0 ); } } if ( !next || !next.length || !this.active ) { next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); } this.focus( event, next ); }, nextPage: function( event ) { var item, base, height; if ( !this.active ) { this.next( event ); return; } if ( this.isLastItem() ) { return; } if ( this._hasScroll() ) { base = this.active.offset().top; height = this.element.height(); this.active.nextAll( ".ui-menu-item" ).each(function() { item = $( this ); return item.offset().top - base - height < 0; }); this.focus( event, item ); } else { this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active ? "first" : "last" ]() ); } }, previousPage: function( event ) { var item, base, height; if ( !this.active ) { this.next( event ); return; } if ( this.isFirstItem() ) { return; } if ( this._hasScroll() ) { base = this.active.offset().top; height = this.element.height(); this.active.prevAll( ".ui-menu-item" ).each(function() { item = $( this ); return item.offset().top - base + height > 0; }); this.focus( event, item ); } else { this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); } }, _hasScroll: function() { return this.element.outerHeight() < this.element.prop( "scrollHeight" ); }, select: function( event ) { // TODO: It should never be possible to not have an active item at this // point, but the tests don't trigger mouseenter before click. this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); var ui = { item: this.active }; if ( !this.active.has( ".ui-menu" ).length ) { this.collapseAll( event, true ); } this._trigger( "select", event, ui ); } }); }( jQuery )); (function( $, undefined ) { $.ui = $.ui || {}; var cachedScrollbarWidth, max = Math.max, abs = Math.abs, round = Math.round, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+%?/, rposition = /^\w+/, rpercent = /%$/, _position = $.fn.position; function getOffsets( offsets, width, height ) { return [ parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) ]; } function parseCss( element, property ) { return parseInt( $.css( element, property ), 10 ) || 0; } $.position = { scrollbarWidth: function() { if ( cachedScrollbarWidth !== undefined ) { return cachedScrollbarWidth; } var w1, w2, div = $( "
    " ), innerDiv = div.children()[0]; $( "body" ).append( div ); w1 = innerDiv.offsetWidth; div.css( "overflow", "scroll" ); w2 = innerDiv.offsetWidth; if ( w1 === w2 ) { w2 = div[0].clientWidth; } div.remove(); return (cachedScrollbarWidth = w1 - w2); }, getScrollInfo: function( within ) { var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), hasOverflowX = overflowX === "scroll" || ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), hasOverflowY = overflowY === "scroll" || ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); return { width: hasOverflowX ? $.position.scrollbarWidth() : 0, height: hasOverflowY ? $.position.scrollbarWidth() : 0 }; }, getWithinInfo: function( element ) { var withinElement = $( element || window ), isWindow = $.isWindow( withinElement[0] ); return { element: withinElement, isWindow: isWindow, offset: withinElement.offset() || { left: 0, top: 0 }, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), width: isWindow ? withinElement.width() : withinElement.outerWidth(), height: isWindow ? withinElement.height() : withinElement.outerHeight() }; } }; $.fn.position = function( options ) { if ( !options || !options.of ) { return _position.apply( this, arguments ); } // make a copy, we don't want to modify arguments options = $.extend( {}, options ); var atOffset, targetWidth, targetHeight, targetOffset, basePosition, target = $( options.of ), within = $.position.getWithinInfo( options.within ), scrollInfo = $.position.getScrollInfo( within ), targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), offsets = {}; if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); targetHeight = target.height(); targetOffset = { top: 0, left: 0 }; } else if ( $.isWindow( targetElem ) ) { targetWidth = target.width(); targetHeight = target.height(); targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; } else if ( targetElem.preventDefault ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; } else { targetWidth = target.outerWidth(); targetHeight = target.outerHeight(); targetOffset = target.offset(); } // clone to reuse original targetOffset later basePosition = $.extend( {}, targetOffset ); // force my and at to have valid horizontal and vertical positions // if a value is missing or invalid, it will be converted to center $.each( [ "my", "at" ], function() { var pos = ( options[ this ] || "" ).split( " " ), horizontalOffset, verticalOffset; if ( pos.length === 1) { pos = rhorizontal.test( pos[ 0 ] ) ? pos.concat( [ "center" ] ) : rvertical.test( pos[ 0 ] ) ? [ "center" ].concat( pos ) : [ "center", "center" ]; } pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; // calculate offsets horizontalOffset = roffset.exec( pos[ 0 ] ); verticalOffset = roffset.exec( pos[ 1 ] ); offsets[ this ] = [ horizontalOffset ? horizontalOffset[ 0 ] : 0, verticalOffset ? verticalOffset[ 0 ] : 0 ]; // reduce to just the positions without the offsets options[ this ] = [ rposition.exec( pos[ 0 ] )[ 0 ], rposition.exec( pos[ 1 ] )[ 0 ] ]; }); // normalize collision option if ( collision.length === 1 ) { collision[ 1 ] = collision[ 0 ]; } if ( options.at[ 0 ] === "right" ) { basePosition.left += targetWidth; } else if ( options.at[ 0 ] === "center" ) { basePosition.left += targetWidth / 2; } if ( options.at[ 1 ] === "bottom" ) { basePosition.top += targetHeight; } else if ( options.at[ 1 ] === "center" ) { basePosition.top += targetHeight / 2; } atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); basePosition.left += atOffset[ 0 ]; basePosition.top += atOffset[ 1 ]; return this.each(function() { var collisionPosition, using, elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseCss( this, "marginLeft" ), marginTop = parseCss( this, "marginTop" ), collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, position = $.extend( {}, basePosition ), myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; } else if ( options.my[ 0 ] === "center" ) { position.left -= elemWidth / 2; } if ( options.my[ 1 ] === "bottom" ) { position.top -= elemHeight; } else if ( options.my[ 1 ] === "center" ) { position.top -= elemHeight / 2; } position.left += myOffset[ 0 ]; position.top += myOffset[ 1 ]; // if the browser doesn't support fractions, then round for consistent results if ( !$.support.offsetFractions ) { position.left = round( position.left ); position.top = round( position.top ); } collisionPosition = { marginLeft: marginLeft, marginTop: marginTop }; $.each( [ "left", "top" ], function( i, dir ) { if ( $.ui.position[ collision[ i ] ] ) { $.ui.position[ collision[ i ] ][ dir ]( position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], my: options.my, at: options.at, within: within, elem : elem }); } }); if ( $.fn.bgiframe ) { elem.bgiframe(); } if ( options.using ) { // adds feedback as second argument to using callback, if present using = function( props ) { var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, top = targetOffset.top - position.top, bottom = top + targetHeight - elemHeight, feedback = { target: { element: target, left: targetOffset.left, top: targetOffset.top, width: targetWidth, height: targetHeight }, element: { element: elem, left: position.left, top: position.top, width: elemWidth, height: elemHeight }, horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" }; if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { feedback.horizontal = "center"; } if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { feedback.vertical = "middle"; } if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { feedback.important = "horizontal"; } else { feedback.important = "vertical"; } options.using.call( this, props, feedback ); }; } elem.offset( $.extend( position, { using: using } ) ); }); }; $.ui.position = { fit: { left: function( position, data ) { var within = data.within, withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, outerWidth = within.width, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = withinOffset - collisionPosLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, newOverRight; // element is wider than within if ( data.collisionWidth > outerWidth ) { // element is initially over the left side of within if ( overLeft > 0 && overRight <= 0 ) { newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; position.left += overLeft - newOverRight; // element is initially over right side of within } else if ( overRight > 0 && overLeft <= 0 ) { position.left = withinOffset; // element is initially over both left and right sides of within } else { if ( overLeft > overRight ) { position.left = withinOffset + outerWidth - data.collisionWidth; } else { position.left = withinOffset; } } // too far left -> align with left edge } else if ( overLeft > 0 ) { position.left += overLeft; // too far right -> align with right edge } else if ( overRight > 0 ) { position.left -= overRight; // adjust based on position and margin } else { position.left = max( position.left - collisionPosLeft, position.left ); } }, top: function( position, data ) { var within = data.within, withinOffset = within.isWindow ? within.scrollTop : within.offset.top, outerHeight = data.within.height, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = withinOffset - collisionPosTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, newOverBottom; // element is taller than within if ( data.collisionHeight > outerHeight ) { // element is initially over the top of within if ( overTop > 0 && overBottom <= 0 ) { newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; position.top += overTop - newOverBottom; // element is initially over bottom of within } else if ( overBottom > 0 && overTop <= 0 ) { position.top = withinOffset; // element is initially over both top and bottom of within } else { if ( overTop > overBottom ) { position.top = withinOffset + outerHeight - data.collisionHeight; } else { position.top = withinOffset; } } // too far up -> align with top } else if ( overTop > 0 ) { position.top += overTop; // too far down -> align with bottom edge } else if ( overBottom > 0 ) { position.top -= overBottom; // adjust based on position and margin } else { position.top = max( position.top - collisionPosTop, position.top ); } } }, flip: { left: function( position, data ) { var within = data.within, withinOffset = within.offset.left + within.scrollLeft, outerWidth = within.width, offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = collisionPosLeft - offsetLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, myOffset = data.my[ 0 ] === "left" ? -data.elemWidth : data.my[ 0 ] === "right" ? data.elemWidth : 0, atOffset = data.at[ 0 ] === "left" ? data.targetWidth : data.at[ 0 ] === "right" ? -data.targetWidth : 0, offset = -2 * data.offset[ 0 ], newOverRight, newOverLeft; if ( overLeft < 0 ) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { position.left += myOffset + atOffset + offset; } } else if ( overRight > 0 ) { newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { position.left += myOffset + atOffset + offset; } } }, top: function( position, data ) { var within = data.within, withinOffset = within.offset.top + within.scrollTop, outerHeight = within.height, offsetTop = within.isWindow ? within.scrollTop : within.offset.top, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = collisionPosTop - offsetTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, top = data.my[ 1 ] === "top", myOffset = top ? -data.elemHeight : data.my[ 1 ] === "bottom" ? data.elemHeight : 0, atOffset = data.at[ 1 ] === "top" ? data.targetHeight : data.at[ 1 ] === "bottom" ? -data.targetHeight : 0, offset = -2 * data.offset[ 1 ], newOverTop, newOverBottom; if ( overTop < 0 ) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { position.top += myOffset + atOffset + offset; } } else if ( overBottom > 0 ) { newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { position.top += myOffset + atOffset + offset; } } } }, flipfit: { left: function() { $.ui.position.flip.left.apply( this, arguments ); $.ui.position.fit.left.apply( this, arguments ); }, top: function() { $.ui.position.flip.top.apply( this, arguments ); $.ui.position.fit.top.apply( this, arguments ); } } }; // fraction support test (function () { var testElement, testElementParent, testElementStyle, offsetLeft, i, body = document.getElementsByTagName( "body" )[ 0 ], div = document.createElement( "div" ); //Create a "fake body" for testing based on method used in jQuery.support testElement = document.createElement( body ? "div" : "body" ); testElementStyle = { visibility: "hidden", width: 0, height: 0, border: 0, margin: 0, background: "none" }; if ( body ) { $.extend( testElementStyle, { position: "absolute", left: "-1000px", top: "-1000px" }); } for ( i in testElementStyle ) { testElement.style[ i ] = testElementStyle[ i ]; } testElement.appendChild( div ); testElementParent = body || document.documentElement; testElementParent.insertBefore( testElement, testElementParent.firstChild ); div.style.cssText = "position: absolute; left: 10.7432222px;"; offsetLeft = $( div ).offset().left; $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; testElement.innerHTML = ""; testElementParent.removeChild( testElement ); })(); // DEPRECATED if ( $.uiBackCompat !== false ) { // offset option (function( $ ) { var _position = $.fn.position; $.fn.position = function( options ) { if ( !options || !options.offset ) { return _position.call( this, options ); } var offset = options.offset.split( " " ), at = options.at.split( " " ); if ( offset.length === 1 ) { offset[ 1 ] = offset[ 0 ]; } if ( /^\d/.test( offset[ 0 ] ) ) { offset[ 0 ] = "+" + offset[ 0 ]; } if ( /^\d/.test( offset[ 1 ] ) ) { offset[ 1 ] = "+" + offset[ 1 ]; } if ( at.length === 1 ) { if ( /left|center|right/.test( at[ 0 ] ) ) { at[ 1 ] = "center"; } else { at[ 1 ] = at[ 0 ]; at[ 0 ] = "center"; } } return _position.call( this, $.extend( options, { at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], offset: undefined } ) ); }; }( jQuery ) ); } }( jQuery ) ); (function( $, undefined ) { $.widget( "ui.progressbar", { version: "1.9.2", options: { value: 0, max: 100 }, min: 0, _create: function() { this.element .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) .attr({ role: "progressbar", "aria-valuemin": this.min, "aria-valuemax": this.options.max, "aria-valuenow": this._value() }); this.valueDiv = $( "
    " ) .appendTo( this.element ); this.oldValue = this._value(); this._refreshValue(); }, _destroy: function() { this.element .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) .removeAttr( "role" ) .removeAttr( "aria-valuemin" ) .removeAttr( "aria-valuemax" ) .removeAttr( "aria-valuenow" ); this.valueDiv.remove(); }, value: function( newValue ) { if ( newValue === undefined ) { return this._value(); } this._setOption( "value", newValue ); return this; }, _setOption: function( key, value ) { if ( key === "value" ) { this.options.value = value; this._refreshValue(); if ( this._value() === this.options.max ) { this._trigger( "complete" ); } } this._super( key, value ); }, _value: function() { var val = this.options.value; // normalize invalid value if ( typeof val !== "number" ) { val = 0; } return Math.min( this.options.max, Math.max( this.min, val ) ); }, _percentage: function() { return 100 * this._value() / this.options.max; }, _refreshValue: function() { var value = this.value(), percentage = this._percentage(); if ( this.oldValue !== value ) { this.oldValue = value; this._trigger( "change" ); } this.valueDiv .toggle( value > this.min ) .toggleClass( "ui-corner-right", value === this.options.max ) .width( percentage.toFixed(0) + "%" ); this.element.attr( "aria-valuenow", value ); } }); })( jQuery ); (function( $, undefined ) { // number of pages in a slider // (how many times can you page up/down to go through the whole range) var numPages = 5; $.widget( "ui.slider", $.ui.mouse, { version: "1.9.2", widgetEventPrefix: "slide", options: { animate: false, distance: 0, max: 100, min: 0, orientation: "horizontal", range: false, step: 1, value: 0, values: null }, _create: function() { var i, handleCount, o = this.options, existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), handle = "", handles = []; this._keySliding = false; this._mouseSliding = false; this._animateOff = true; this._handleIndex = null; this._detectOrientation(); this._mouseInit(); this.element .addClass( "ui-slider" + " ui-slider-" + this.orientation + " ui-widget" + " ui-widget-content" + " ui-corner-all" + ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); this.range = $([]); if ( o.range ) { if ( o.range === true ) { if ( !o.values ) { o.values = [ this._valueMin(), this._valueMin() ]; } if ( o.values.length && o.values.length !== 2 ) { o.values = [ o.values[0], o.values[0] ]; } } this.range = $( "
    " ) .appendTo( this.element ) .addClass( "ui-slider-range" + // note: this isn't the most fittingly semantic framework class for this element, // but worked best visually with a variety of themes " ui-widget-header" + ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); } handleCount = ( o.values && o.values.length ) || 1; for ( i = existingHandles.length; i < handleCount; i++ ) { handles.push( handle ); } this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); this.handle = this.handles.eq( 0 ); this.handles.add( this.range ).filter( "a" ) .click(function( event ) { event.preventDefault(); }) .mouseenter(function() { if ( !o.disabled ) { $( this ).addClass( "ui-state-hover" ); } }) .mouseleave(function() { $( this ).removeClass( "ui-state-hover" ); }) .focus(function() { if ( !o.disabled ) { $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); $( this ).addClass( "ui-state-focus" ); } else { $( this ).blur(); } }) .blur(function() { $( this ).removeClass( "ui-state-focus" ); }); this.handles.each(function( i ) { $( this ).data( "ui-slider-handle-index", i ); }); this._on( this.handles, { keydown: function( event ) { var allowed, curVal, newVal, step, index = $( event.target ).data( "ui-slider-handle-index" ); switch ( event.keyCode ) { case $.ui.keyCode.HOME: case $.ui.keyCode.END: case $.ui.keyCode.PAGE_UP: case $.ui.keyCode.PAGE_DOWN: case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: event.preventDefault(); if ( !this._keySliding ) { this._keySliding = true; $( event.target ).addClass( "ui-state-active" ); allowed = this._start( event, index ); if ( allowed === false ) { return; } } break; } step = this.options.step; if ( this.options.values && this.options.values.length ) { curVal = newVal = this.values( index ); } else { curVal = newVal = this.value(); } switch ( event.keyCode ) { case $.ui.keyCode.HOME: newVal = this._valueMin(); break; case $.ui.keyCode.END: newVal = this._valueMax(); break; case $.ui.keyCode.PAGE_UP: newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); break; case $.ui.keyCode.PAGE_DOWN: newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: if ( curVal === this._valueMax() ) { return; } newVal = this._trimAlignValue( curVal + step ); break; case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: if ( curVal === this._valueMin() ) { return; } newVal = this._trimAlignValue( curVal - step ); break; } this._slide( event, index, newVal ); }, keyup: function( event ) { var index = $( event.target ).data( "ui-slider-handle-index" ); if ( this._keySliding ) { this._keySliding = false; this._stop( event, index ); this._change( event, index ); $( event.target ).removeClass( "ui-state-active" ); } } }); this._refreshValue(); this._animateOff = false; }, _destroy: function() { this.handles.remove(); this.range.remove(); this.element .removeClass( "ui-slider" + " ui-slider-horizontal" + " ui-slider-vertical" + " ui-slider-disabled" + " ui-widget" + " ui-widget-content" + " ui-corner-all" ); this._mouseDestroy(); }, _mouseCapture: function( event ) { var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, that = this, o = this.options; if ( o.disabled ) { return false; } this.elementSize = { width: this.element.outerWidth(), height: this.element.outerHeight() }; this.elementOffset = this.element.offset(); position = { x: event.pageX, y: event.pageY }; normValue = this._normValueFromMouse( position ); distance = this._valueMax() - this._valueMin() + 1; this.handles.each(function( i ) { var thisDistance = Math.abs( normValue - that.values(i) ); if ( distance > thisDistance ) { distance = thisDistance; closestHandle = $( this ); index = i; } }); // workaround for bug #3736 (if both handles of a range are at 0, // the first is always used as the one with least distance, // and moving it is obviously prevented by preventing negative ranges) if( o.range === true && this.values(1) === o.min ) { index += 1; closestHandle = $( this.handles[index] ); } allowed = this._start( event, index ); if ( allowed === false ) { return false; } this._mouseSliding = true; this._handleIndex = index; closestHandle .addClass( "ui-state-active" ) .focus(); offset = closestHandle.offset(); mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { left: event.pageX - offset.left - ( closestHandle.width() / 2 ), top: event.pageY - offset.top - ( closestHandle.height() / 2 ) - ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) }; if ( !this.handles.hasClass( "ui-state-hover" ) ) { this._slide( event, index, normValue ); } this._animateOff = true; return true; }, _mouseStart: function() { return true; }, _mouseDrag: function( event ) { var position = { x: event.pageX, y: event.pageY }, normValue = this._normValueFromMouse( position ); this._slide( event, this._handleIndex, normValue ); return false; }, _mouseStop: function( event ) { this.handles.removeClass( "ui-state-active" ); this._mouseSliding = false; this._stop( event, this._handleIndex ); this._change( event, this._handleIndex ); this._handleIndex = null; this._clickOffset = null; this._animateOff = false; return false; }, _detectOrientation: function() { this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; }, _normValueFromMouse: function( position ) { var pixelTotal, pixelMouse, percentMouse, valueTotal, valueMouse; if ( this.orientation === "horizontal" ) { pixelTotal = this.elementSize.width; pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); } else { pixelTotal = this.elementSize.height; pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); } percentMouse = ( pixelMouse / pixelTotal ); if ( percentMouse > 1 ) { percentMouse = 1; } if ( percentMouse < 0 ) { percentMouse = 0; } if ( this.orientation === "vertical" ) { percentMouse = 1 - percentMouse; } valueTotal = this._valueMax() - this._valueMin(); valueMouse = this._valueMin() + percentMouse * valueTotal; return this._trimAlignValue( valueMouse ); }, _start: function( event, index ) { var uiHash = { handle: this.handles[ index ], value: this.value() }; if ( this.options.values && this.options.values.length ) { uiHash.value = this.values( index ); uiHash.values = this.values(); } return this._trigger( "start", event, uiHash ); }, _slide: function( event, index, newVal ) { var otherVal, newValues, allowed; if ( this.options.values && this.options.values.length ) { otherVal = this.values( index ? 0 : 1 ); if ( ( this.options.values.length === 2 && this.options.range === true ) && ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) ) { newVal = otherVal; } if ( newVal !== this.values( index ) ) { newValues = this.values(); newValues[ index ] = newVal; // A slide can be canceled by returning false from the slide callback allowed = this._trigger( "slide", event, { handle: this.handles[ index ], value: newVal, values: newValues } ); otherVal = this.values( index ? 0 : 1 ); if ( allowed !== false ) { this.values( index, newVal, true ); } } } else { if ( newVal !== this.value() ) { // A slide can be canceled by returning false from the slide callback allowed = this._trigger( "slide", event, { handle: this.handles[ index ], value: newVal } ); if ( allowed !== false ) { this.value( newVal ); } } } }, _stop: function( event, index ) { var uiHash = { handle: this.handles[ index ], value: this.value() }; if ( this.options.values && this.options.values.length ) { uiHash.value = this.values( index ); uiHash.values = this.values(); } this._trigger( "stop", event, uiHash ); }, _change: function( event, index ) { if ( !this._keySliding && !this._mouseSliding ) { var uiHash = { handle: this.handles[ index ], value: this.value() }; if ( this.options.values && this.options.values.length ) { uiHash.value = this.values( index ); uiHash.values = this.values(); } this._trigger( "change", event, uiHash ); } }, value: function( newValue ) { if ( arguments.length ) { this.options.value = this._trimAlignValue( newValue ); this._refreshValue(); this._change( null, 0 ); return; } return this._value(); }, values: function( index, newValue ) { var vals, newValues, i; if ( arguments.length > 1 ) { this.options.values[ index ] = this._trimAlignValue( newValue ); this._refreshValue(); this._change( null, index ); return; } if ( arguments.length ) { if ( $.isArray( arguments[ 0 ] ) ) { vals = this.options.values; newValues = arguments[ 0 ]; for ( i = 0; i < vals.length; i += 1 ) { vals[ i ] = this._trimAlignValue( newValues[ i ] ); this._change( null, i ); } this._refreshValue(); } else { if ( this.options.values && this.options.values.length ) { return this._values( index ); } else { return this.value(); } } } else { return this._values(); } }, _setOption: function( key, value ) { var i, valsLength = 0; if ( $.isArray( this.options.values ) ) { valsLength = this.options.values.length; } $.Widget.prototype._setOption.apply( this, arguments ); switch ( key ) { case "disabled": if ( value ) { this.handles.filter( ".ui-state-focus" ).blur(); this.handles.removeClass( "ui-state-hover" ); this.handles.prop( "disabled", true ); this.element.addClass( "ui-disabled" ); } else { this.handles.prop( "disabled", false ); this.element.removeClass( "ui-disabled" ); } break; case "orientation": this._detectOrientation(); this.element .removeClass( "ui-slider-horizontal ui-slider-vertical" ) .addClass( "ui-slider-" + this.orientation ); this._refreshValue(); break; case "value": this._animateOff = true; this._refreshValue(); this._change( null, 0 ); this._animateOff = false; break; case "values": this._animateOff = true; this._refreshValue(); for ( i = 0; i < valsLength; i += 1 ) { this._change( null, i ); } this._animateOff = false; break; case "min": case "max": this._animateOff = true; this._refreshValue(); this._animateOff = false; break; } }, //internal value getter // _value() returns value trimmed by min and max, aligned by step _value: function() { var val = this.options.value; val = this._trimAlignValue( val ); return val; }, //internal values getter // _values() returns array of values trimmed by min and max, aligned by step // _values( index ) returns single value trimmed by min and max, aligned by step _values: function( index ) { var val, vals, i; if ( arguments.length ) { val = this.options.values[ index ]; val = this._trimAlignValue( val ); return val; } else { // .slice() creates a copy of the array // this copy gets trimmed by min and max and then returned vals = this.options.values.slice(); for ( i = 0; i < vals.length; i+= 1) { vals[ i ] = this._trimAlignValue( vals[ i ] ); } return vals; } }, // returns the step-aligned value that val is closest to, between (inclusive) min and max _trimAlignValue: function( val ) { if ( val <= this._valueMin() ) { return this._valueMin(); } if ( val >= this._valueMax() ) { return this._valueMax(); } var step = ( this.options.step > 0 ) ? this.options.step : 1, valModStep = (val - this._valueMin()) % step, alignValue = val - valModStep; if ( Math.abs(valModStep) * 2 >= step ) { alignValue += ( valModStep > 0 ) ? step : ( -step ); } // Since JavaScript has problems with large floats, round // the final value to 5 digits after the decimal point (see #4124) return parseFloat( alignValue.toFixed(5) ); }, _valueMin: function() { return this.options.min; }, _valueMax: function() { return this.options.max; }, _refreshValue: function() { var lastValPercent, valPercent, value, valueMin, valueMax, oRange = this.options.range, o = this.options, that = this, animate = ( !this._animateOff ) ? o.animate : false, _set = {}; if ( this.options.values && this.options.values.length ) { this.handles.each(function( i ) { valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( that.options.range === true ) { if ( that.orientation === "horizontal" ) { if ( i === 0 ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); } if ( i === 1 ) { that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); } } else { if ( i === 0 ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); } if ( i === 1 ) { that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); } } } lastValPercent = valPercent; }); } else { value = this.value(); valueMin = this._valueMin(); valueMax = this._valueMax(); valPercent = ( valueMax !== valueMin ) ? ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 0; _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( oRange === "min" && this.orientation === "horizontal" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); } if ( oRange === "max" && this.orientation === "horizontal" ) { this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); } if ( oRange === "min" && this.orientation === "vertical" ) { this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); } if ( oRange === "max" && this.orientation === "vertical" ) { this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); } } } }); }(jQuery)); (function( $ ) { function modifier( fn ) { return function() { var previous = this.element.val(); fn.apply( this, arguments ); this._refresh(); if ( previous !== this.element.val() ) { this._trigger( "change" ); } }; } $.widget( "ui.spinner", { version: "1.9.2", defaultElement: "", widgetEventPrefix: "spin", options: { culture: null, icons: { down: "ui-icon-triangle-1-s", up: "ui-icon-triangle-1-n" }, incremental: true, max: null, min: null, numberFormat: null, page: 10, step: 1, change: null, spin: null, start: null, stop: null }, _create: function() { // handle string values that need to be parsed this._setOption( "max", this.options.max ); this._setOption( "min", this.options.min ); this._setOption( "step", this.options.step ); // format the value, but don't constrain this._value( this.element.val(), true ); this._draw(); this._on( this._events ); this._refresh(); // turning off autocomplete prevents the browser from remembering the // value when navigating through history, so we re-enable autocomplete // if the page is unloaded before the widget is destroyed. #7790 this._on( this.window, { beforeunload: function() { this.element.removeAttr( "autocomplete" ); } }); }, _getCreateOptions: function() { var options = {}, element = this.element; $.each( [ "min", "max", "step" ], function( i, option ) { var value = element.attr( option ); if ( value !== undefined && value.length ) { options[ option ] = value; } }); return options; }, _events: { keydown: function( event ) { if ( this._start( event ) && this._keydown( event ) ) { event.preventDefault(); } }, keyup: "_stop", focus: function() { this.previous = this.element.val(); }, blur: function( event ) { if ( this.cancelBlur ) { delete this.cancelBlur; return; } this._refresh(); if ( this.previous !== this.element.val() ) { this._trigger( "change", event ); } }, mousewheel: function( event, delta ) { if ( !delta ) { return; } if ( !this.spinning && !this._start( event ) ) { return false; } this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); clearTimeout( this.mousewheelTimer ); this.mousewheelTimer = this._delay(function() { if ( this.spinning ) { this._stop( event ); } }, 100 ); event.preventDefault(); }, "mousedown .ui-spinner-button": function( event ) { var previous; // We never want the buttons to have focus; whenever the user is // interacting with the spinner, the focus should be on the input. // If the input is focused then this.previous is properly set from // when the input first received focus. If the input is not focused // then we need to set this.previous based on the value before spinning. previous = this.element[0] === this.document[0].activeElement ? this.previous : this.element.val(); function checkFocus() { var isActive = this.element[0] === this.document[0].activeElement; if ( !isActive ) { this.element.focus(); this.previous = previous; // support: IE // IE sets focus asynchronously, so we need to check if focus // moved off of the input because the user clicked on the button. this._delay(function() { this.previous = previous; }); } } // ensure focus is on (or stays on) the text field event.preventDefault(); checkFocus.call( this ); // support: IE // IE doesn't prevent moving focus even with event.preventDefault() // so we set a flag to know when we should ignore the blur event // and check (again) if focus moved off of the input. this.cancelBlur = true; this._delay(function() { delete this.cancelBlur; checkFocus.call( this ); }); if ( this._start( event ) === false ) { return; } this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }, "mouseup .ui-spinner-button": "_stop", "mouseenter .ui-spinner-button": function( event ) { // button will add ui-state-active if mouse was down while mouseleave and kept down if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { return; } if ( this._start( event ) === false ) { return false; } this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }, // TODO: do we really want to consider this a stop? // shouldn't we just stop the repeater and wait until mouseup before // we trigger the stop event? "mouseleave .ui-spinner-button": "_stop" }, _draw: function() { var uiSpinner = this.uiSpinner = this.element .addClass( "ui-spinner-input" ) .attr( "autocomplete", "off" ) .wrap( this._uiSpinnerHtml() ) .parent() // add buttons .append( this._buttonHtml() ); this.element.attr( "role", "spinbutton" ); // button bindings this.buttons = uiSpinner.find( ".ui-spinner-button" ) .attr( "tabIndex", -1 ) .button() .removeClass( "ui-corner-all" ); // IE 6 doesn't understand height: 50% for the buttons // unless the wrapper has an explicit height if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && uiSpinner.height() > 0 ) { uiSpinner.height( uiSpinner.height() ); } // disable spinner if element was already disabled if ( this.options.disabled ) { this.disable(); } }, _keydown: function( event ) { var options = this.options, keyCode = $.ui.keyCode; switch ( event.keyCode ) { case keyCode.UP: this._repeat( null, 1, event ); return true; case keyCode.DOWN: this._repeat( null, -1, event ); return true; case keyCode.PAGE_UP: this._repeat( null, options.page, event ); return true; case keyCode.PAGE_DOWN: this._repeat( null, -options.page, event ); return true; } return false; }, _uiSpinnerHtml: function() { return ""; }, _buttonHtml: function() { return "" + "" + "" + "" + "" + "" + ""; }, _start: function( event ) { if ( !this.spinning && this._trigger( "start", event ) === false ) { return false; } if ( !this.counter ) { this.counter = 1; } this.spinning = true; return true; }, _repeat: function( i, steps, event ) { i = i || 500; clearTimeout( this.timer ); this.timer = this._delay(function() { this._repeat( 40, steps, event ); }, i ); this._spin( steps * this.options.step, event ); }, _spin: function( step, event ) { var value = this.value() || 0; if ( !this.counter ) { this.counter = 1; } value = this._adjustValue( value + step * this._increment( this.counter ) ); if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { this._value( value ); this.counter++; } }, _increment: function( i ) { var incremental = this.options.incremental; if ( incremental ) { return $.isFunction( incremental ) ? incremental( i ) : Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); } return 1; }, _precision: function() { var precision = this._precisionOf( this.options.step ); if ( this.options.min !== null ) { precision = Math.max( precision, this._precisionOf( this.options.min ) ); } return precision; }, _precisionOf: function( num ) { var str = num.toString(), decimal = str.indexOf( "." ); return decimal === -1 ? 0 : str.length - decimal - 1; }, _adjustValue: function( value ) { var base, aboveMin, options = this.options; // make sure we're at a valid step // - find out where we are relative to the base (min or 0) base = options.min !== null ? options.min : 0; aboveMin = value - base; // - round to the nearest step aboveMin = Math.round(aboveMin / options.step) * options.step; // - rounding is based on 0, so adjust back to our base value = base + aboveMin; // fix precision from bad JS floating point math value = parseFloat( value.toFixed( this._precision() ) ); // clamp the value if ( options.max !== null && value > options.max) { return options.max; } if ( options.min !== null && value < options.min ) { return options.min; } return value; }, _stop: function( event ) { if ( !this.spinning ) { return; } clearTimeout( this.timer ); clearTimeout( this.mousewheelTimer ); this.counter = 0; this.spinning = false; this._trigger( "stop", event ); }, _setOption: function( key, value ) { if ( key === "culture" || key === "numberFormat" ) { var prevValue = this._parse( this.element.val() ); this.options[ key ] = value; this.element.val( this._format( prevValue ) ); return; } if ( key === "max" || key === "min" || key === "step" ) { if ( typeof value === "string" ) { value = this._parse( value ); } } this._super( key, value ); if ( key === "disabled" ) { if ( value ) { this.element.prop( "disabled", true ); this.buttons.button( "disable" ); } else { this.element.prop( "disabled", false ); this.buttons.button( "enable" ); } } }, _setOptions: modifier(function( options ) { this._super( options ); this._value( this.element.val() ); }), _parse: function( val ) { if ( typeof val === "string" && val !== "" ) { val = window.Globalize && this.options.numberFormat ? Globalize.parseFloat( val, 10, this.options.culture ) : +val; } return val === "" || isNaN( val ) ? null : val; }, _format: function( value ) { if ( value === "" ) { return ""; } return window.Globalize && this.options.numberFormat ? Globalize.format( value, this.options.numberFormat, this.options.culture ) : value; }, _refresh: function() { this.element.attr({ "aria-valuemin": this.options.min, "aria-valuemax": this.options.max, // TODO: what should we do with values that can't be parsed? "aria-valuenow": this._parse( this.element.val() ) }); }, // update the value without triggering change _value: function( value, allowAny ) { var parsed; if ( value !== "" ) { parsed = this._parse( value ); if ( parsed !== null ) { if ( !allowAny ) { parsed = this._adjustValue( parsed ); } value = this._format( parsed ); } } this.element.val( value ); this._refresh(); }, _destroy: function() { this.element .removeClass( "ui-spinner-input" ) .prop( "disabled", false ) .removeAttr( "autocomplete" ) .removeAttr( "role" ) .removeAttr( "aria-valuemin" ) .removeAttr( "aria-valuemax" ) .removeAttr( "aria-valuenow" ); this.uiSpinner.replaceWith( this.element ); }, stepUp: modifier(function( steps ) { this._stepUp( steps ); }), _stepUp: function( steps ) { this._spin( (steps || 1) * this.options.step ); }, stepDown: modifier(function( steps ) { this._stepDown( steps ); }), _stepDown: function( steps ) { this._spin( (steps || 1) * -this.options.step ); }, pageUp: modifier(function( pages ) { this._stepUp( (pages || 1) * this.options.page ); }), pageDown: modifier(function( pages ) { this._stepDown( (pages || 1) * this.options.page ); }), value: function( newVal ) { if ( !arguments.length ) { return this._parse( this.element.val() ); } modifier( this._value ).call( this, newVal ); }, widget: function() { return this.uiSpinner; } }); }( jQuery ) ); (function( $, undefined ) { var tabId = 0, rhash = /#.*$/; function getNextTabId() { return ++tabId; } function isLocal( anchor ) { return anchor.hash.length > 1 && anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" ) // support: Safari 5.1 // Safari 5.1 doesn't encode spaces in window.location // but it does encode spaces from anchors (#8777) .replace( /\s/g, "%20" ); } $.widget( "ui.tabs", { version: "1.9.2", delay: 300, options: { active: null, collapsible: false, event: "click", heightStyle: "content", hide: null, show: null, // callbacks activate: null, beforeActivate: null, beforeLoad: null, load: null }, _create: function() { var that = this, options = this.options, active = options.active, locationHash = location.hash.substring( 1 ); this.running = false; this.element .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) .toggleClass( "ui-tabs-collapsible", options.collapsible ) // Prevent users from focusing disabled tabs via click .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { if ( $( this ).is( ".ui-state-disabled" ) ) { event.preventDefault(); } }) // support: IE <9 // Preventing the default action in mousedown doesn't prevent IE // from focusing the element, so if the anchor gets focused, blur. // We don't have to worry about focusing the previously focused // element since clicking on a non-focusable element should focus // the body anyway. .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { this.blur(); } }); this._processTabs(); if ( active === null ) { // check the fragment identifier in the URL if ( locationHash ) { this.tabs.each(function( i, tab ) { if ( $( tab ).attr( "aria-controls" ) === locationHash ) { active = i; return false; } }); } // check for a tab marked active via a class if ( active === null ) { active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); } // no active tab, set to false if ( active === null || active === -1 ) { active = this.tabs.length ? 0 : false; } } // handle numbers: negative, out of range if ( active !== false ) { active = this.tabs.index( this.tabs.eq( active ) ); if ( active === -1 ) { active = options.collapsible ? false : 0; } } options.active = active; // don't allow collapsible: false and active: false if ( !options.collapsible && options.active === false && this.anchors.length ) { options.active = 0; } // Take disabling tabs via class attribute from HTML // into account and update option properly. if ( $.isArray( options.disabled ) ) { options.disabled = $.unique( options.disabled.concat( $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { return that.tabs.index( li ); }) ) ).sort(); } // check for length avoids error when initializing empty list if ( this.options.active !== false && this.anchors.length ) { this.active = this._findActive( this.options.active ); } else { this.active = $(); } this._refresh(); if ( this.active.length ) { this.load( options.active ); } }, _getCreateEventData: function() { return { tab: this.active, panel: !this.active.length ? $() : this._getPanelForTab( this.active ) }; }, _tabKeydown: function( event ) { var focusedTab = $( this.document[0].activeElement ).closest( "li" ), selectedIndex = this.tabs.index( focusedTab ), goingForward = true; if ( this._handlePageNav( event ) ) { return; } switch ( event.keyCode ) { case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: selectedIndex++; break; case $.ui.keyCode.UP: case $.ui.keyCode.LEFT: goingForward = false; selectedIndex--; break; case $.ui.keyCode.END: selectedIndex = this.anchors.length - 1; break; case $.ui.keyCode.HOME: selectedIndex = 0; break; case $.ui.keyCode.SPACE: // Activate only, no collapsing event.preventDefault(); clearTimeout( this.activating ); this._activate( selectedIndex ); return; case $.ui.keyCode.ENTER: // Toggle (cancel delayed activation, allow collapsing) event.preventDefault(); clearTimeout( this.activating ); // Determine if we should collapse or activate this._activate( selectedIndex === this.options.active ? false : selectedIndex ); return; default: return; } // Focus the appropriate tab, based on which key was pressed event.preventDefault(); clearTimeout( this.activating ); selectedIndex = this._focusNextTab( selectedIndex, goingForward ); // Navigating with control key will prevent automatic activation if ( !event.ctrlKey ) { // Update aria-selected immediately so that AT think the tab is already selected. // Otherwise AT may confuse the user by stating that they need to activate the tab, // but the tab will already be activated by the time the announcement finishes. focusedTab.attr( "aria-selected", "false" ); this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); this.activating = this._delay(function() { this.option( "active", selectedIndex ); }, this.delay ); } }, _panelKeydown: function( event ) { if ( this._handlePageNav( event ) ) { return; } // Ctrl+up moves focus to the current tab if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { event.preventDefault(); this.active.focus(); } }, // Alt+page up/down moves focus to the previous/next tab (and activates) _handlePageNav: function( event ) { if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { this._activate( this._focusNextTab( this.options.active - 1, false ) ); return true; } if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { this._activate( this._focusNextTab( this.options.active + 1, true ) ); return true; } }, _findNextTab: function( index, goingForward ) { var lastTabIndex = this.tabs.length - 1; function constrain() { if ( index > lastTabIndex ) { index = 0; } if ( index < 0 ) { index = lastTabIndex; } return index; } while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { index = goingForward ? index + 1 : index - 1; } return index; }, _focusNextTab: function( index, goingForward ) { index = this._findNextTab( index, goingForward ); this.tabs.eq( index ).focus(); return index; }, _setOption: function( key, value ) { if ( key === "active" ) { // _activate() will handle invalid values and update this.options this._activate( value ); return; } if ( key === "disabled" ) { // don't use the widget factory's disabled handling this._setupDisabled( value ); return; } this._super( key, value); if ( key === "collapsible" ) { this.element.toggleClass( "ui-tabs-collapsible", value ); // Setting collapsible: false while collapsed; open first panel if ( !value && this.options.active === false ) { this._activate( 0 ); } } if ( key === "event" ) { this._setupEvents( value ); } if ( key === "heightStyle" ) { this._setupHeightStyle( value ); } }, _tabId: function( tab ) { return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); }, _sanitizeSelector: function( hash ) { return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; }, refresh: function() { var options = this.options, lis = this.tablist.children( ":has(a[href])" ); // get disabled tabs from class attribute from HTML // this will get converted to a boolean if needed in _refresh() options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { return lis.index( tab ); }); this._processTabs(); // was collapsed or no tabs if ( options.active === false || !this.anchors.length ) { options.active = false; this.active = $(); // was active, but active tab is gone } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { // all remaining tabs are disabled if ( this.tabs.length === options.disabled.length ) { options.active = false; this.active = $(); // activate previous tab } else { this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); } // was active, active tab still exists } else { // make sure active index is correct options.active = this.tabs.index( this.active ); } this._refresh(); }, _refresh: function() { this._setupDisabled( this.options.disabled ); this._setupEvents( this.options.event ); this._setupHeightStyle( this.options.heightStyle ); this.tabs.not( this.active ).attr({ "aria-selected": "false", tabIndex: -1 }); this.panels.not( this._getPanelForTab( this.active ) ) .hide() .attr({ "aria-expanded": "false", "aria-hidden": "true" }); // Make sure one tab is in the tab order if ( !this.active.length ) { this.tabs.eq( 0 ).attr( "tabIndex", 0 ); } else { this.active .addClass( "ui-tabs-active ui-state-active" ) .attr({ "aria-selected": "true", tabIndex: 0 }); this._getPanelForTab( this.active ) .show() .attr({ "aria-expanded": "true", "aria-hidden": "false" }); } }, _processTabs: function() { var that = this; this.tablist = this._getList() .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) .attr( "role", "tablist" ); this.tabs = this.tablist.find( "> li:has(a[href])" ) .addClass( "ui-state-default ui-corner-top" ) .attr({ role: "tab", tabIndex: -1 }); this.anchors = this.tabs.map(function() { return $( "a", this )[ 0 ]; }) .addClass( "ui-tabs-anchor" ) .attr({ role: "presentation", tabIndex: -1 }); this.panels = $(); this.anchors.each(function( i, anchor ) { var selector, panel, panelId, anchorId = $( anchor ).uniqueId().attr( "id" ), tab = $( anchor ).closest( "li" ), originalAriaControls = tab.attr( "aria-controls" ); // inline tab if ( isLocal( anchor ) ) { selector = anchor.hash; panel = that.element.find( that._sanitizeSelector( selector ) ); // remote tab } else { panelId = that._tabId( tab ); selector = "#" + panelId; panel = that.element.find( selector ); if ( !panel.length ) { panel = that._createPanel( panelId ); panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); } panel.attr( "aria-live", "polite" ); } if ( panel.length) { that.panels = that.panels.add( panel ); } if ( originalAriaControls ) { tab.data( "ui-tabs-aria-controls", originalAriaControls ); } tab.attr({ "aria-controls": selector.substring( 1 ), "aria-labelledby": anchorId }); panel.attr( "aria-labelledby", anchorId ); }); this.panels .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .attr( "role", "tabpanel" ); }, // allow overriding how to find the list for rare usage scenarios (#7715) _getList: function() { return this.element.find( "ol,ul" ).eq( 0 ); }, _createPanel: function( id ) { return $( "
    " ) .attr( "id", id ) .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .data( "ui-tabs-destroy", true ); }, _setupDisabled: function( disabled ) { if ( $.isArray( disabled ) ) { if ( !disabled.length ) { disabled = false; } else if ( disabled.length === this.anchors.length ) { disabled = true; } } // disable tabs for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { $( li ) .addClass( "ui-state-disabled" ) .attr( "aria-disabled", "true" ); } else { $( li ) .removeClass( "ui-state-disabled" ) .removeAttr( "aria-disabled" ); } } this.options.disabled = disabled; }, _setupEvents: function( event ) { var events = { click: function( event ) { event.preventDefault(); } }; if ( event ) { $.each( event.split(" "), function( index, eventName ) { events[ eventName ] = "_eventHandler"; }); } this._off( this.anchors.add( this.tabs ).add( this.panels ) ); this._on( this.anchors, events ); this._on( this.tabs, { keydown: "_tabKeydown" } ); this._on( this.panels, { keydown: "_panelKeydown" } ); this._focusable( this.tabs ); this._hoverable( this.tabs ); }, _setupHeightStyle: function( heightStyle ) { var maxHeight, overflow, parent = this.element.parent(); if ( heightStyle === "fill" ) { // IE 6 treats height like minHeight, so we need to turn off overflow // in order to get a reliable height // we use the minHeight support test because we assume that only // browsers that don't support minHeight will treat height as minHeight if ( !$.support.minHeight ) { overflow = parent.css( "overflow" ); parent.css( "overflow", "hidden"); } maxHeight = parent.height(); this.element.siblings( ":visible" ).each(function() { var elem = $( this ), position = elem.css( "position" ); if ( position === "absolute" || position === "fixed" ) { return; } maxHeight -= elem.outerHeight( true ); }); if ( overflow ) { parent.css( "overflow", overflow ); } this.element.children().not( this.panels ).each(function() { maxHeight -= $( this ).outerHeight( true ); }); this.panels.each(function() { $( this ).height( Math.max( 0, maxHeight - $( this ).innerHeight() + $( this ).height() ) ); }) .css( "overflow", "auto" ); } else if ( heightStyle === "auto" ) { maxHeight = 0; this.panels.each(function() { maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); }).height( maxHeight ); } }, _eventHandler: function( event ) { var options = this.options, active = this.active, anchor = $( event.currentTarget ), tab = anchor.closest( "li" ), clickedIsActive = tab[ 0 ] === active[ 0 ], collapsing = clickedIsActive && options.collapsible, toShow = collapsing ? $() : this._getPanelForTab( tab ), toHide = !active.length ? $() : this._getPanelForTab( active ), eventData = { oldTab: active, oldPanel: toHide, newTab: collapsing ? $() : tab, newPanel: toShow }; event.preventDefault(); if ( tab.hasClass( "ui-state-disabled" ) || // tab is already loading tab.hasClass( "ui-tabs-loading" ) || // can't switch durning an animation this.running || // click on active header, but not collapsible ( clickedIsActive && !options.collapsible ) || // allow canceling activation ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { return; } options.active = collapsing ? false : this.tabs.index( tab ); this.active = clickedIsActive ? $() : tab; if ( this.xhr ) { this.xhr.abort(); } if ( !toHide.length && !toShow.length ) { $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); } if ( toShow.length ) { this.load( this.tabs.index( tab ), event ); } this._toggle( event, eventData ); }, // handles show/hide for selecting tabs _toggle: function( event, eventData ) { var that = this, toShow = eventData.newPanel, toHide = eventData.oldPanel; this.running = true; function complete() { that.running = false; that._trigger( "activate", event, eventData ); } function show() { eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); if ( toShow.length && that.options.show ) { that._show( toShow, that.options.show, complete ); } else { toShow.show(); complete(); } } // start out by hiding, then showing, then completing if ( toHide.length && this.options.hide ) { this._hide( toHide, this.options.hide, function() { eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); show(); }); } else { eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); toHide.hide(); show(); } toHide.attr({ "aria-expanded": "false", "aria-hidden": "true" }); eventData.oldTab.attr( "aria-selected", "false" ); // If we're switching tabs, remove the old tab from the tab order. // If we're opening from collapsed state, remove the previous tab from the tab order. // If we're collapsing, then keep the collapsing tab in the tab order. if ( toShow.length && toHide.length ) { eventData.oldTab.attr( "tabIndex", -1 ); } else if ( toShow.length ) { this.tabs.filter(function() { return $( this ).attr( "tabIndex" ) === 0; }) .attr( "tabIndex", -1 ); } toShow.attr({ "aria-expanded": "true", "aria-hidden": "false" }); eventData.newTab.attr({ "aria-selected": "true", tabIndex: 0 }); }, _activate: function( index ) { var anchor, active = this._findActive( index ); // trying to activate the already active panel if ( active[ 0 ] === this.active[ 0 ] ) { return; } // trying to collapse, simulate a click on the current active header if ( !active.length ) { active = this.active; } anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; this._eventHandler({ target: anchor, currentTarget: anchor, preventDefault: $.noop }); }, _findActive: function( index ) { return index === false ? $() : this.tabs.eq( index ); }, _getIndex: function( index ) { // meta-function to give users option to provide a href string instead of a numerical index. if ( typeof index === "string" ) { index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); } return index; }, _destroy: function() { if ( this.xhr ) { this.xhr.abort(); } this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); this.tablist .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) .removeAttr( "role" ); this.anchors .removeClass( "ui-tabs-anchor" ) .removeAttr( "role" ) .removeAttr( "tabIndex" ) .removeData( "href.tabs" ) .removeData( "load.tabs" ) .removeUniqueId(); this.tabs.add( this.panels ).each(function() { if ( $.data( this, "ui-tabs-destroy" ) ) { $( this ).remove(); } else { $( this ) .removeClass( "ui-state-default ui-state-active ui-state-disabled " + "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) .removeAttr( "tabIndex" ) .removeAttr( "aria-live" ) .removeAttr( "aria-busy" ) .removeAttr( "aria-selected" ) .removeAttr( "aria-labelledby" ) .removeAttr( "aria-hidden" ) .removeAttr( "aria-expanded" ) .removeAttr( "role" ); } }); this.tabs.each(function() { var li = $( this ), prev = li.data( "ui-tabs-aria-controls" ); if ( prev ) { li.attr( "aria-controls", prev ); } else { li.removeAttr( "aria-controls" ); } }); this.panels.show(); if ( this.options.heightStyle !== "content" ) { this.panels.css( "height", "" ); } }, enable: function( index ) { var disabled = this.options.disabled; if ( disabled === false ) { return; } if ( index === undefined ) { disabled = false; } else { index = this._getIndex( index ); if ( $.isArray( disabled ) ) { disabled = $.map( disabled, function( num ) { return num !== index ? num : null; }); } else { disabled = $.map( this.tabs, function( li, num ) { return num !== index ? num : null; }); } } this._setupDisabled( disabled ); }, disable: function( index ) { var disabled = this.options.disabled; if ( disabled === true ) { return; } if ( index === undefined ) { disabled = true; } else { index = this._getIndex( index ); if ( $.inArray( index, disabled ) !== -1 ) { return; } if ( $.isArray( disabled ) ) { disabled = $.merge( [ index ], disabled ).sort(); } else { disabled = [ index ]; } } this._setupDisabled( disabled ); }, load: function( index, event ) { index = this._getIndex( index ); var that = this, tab = this.tabs.eq( index ), anchor = tab.find( ".ui-tabs-anchor" ), panel = this._getPanelForTab( tab ), eventData = { tab: tab, panel: panel }; // not remote if ( isLocal( anchor[ 0 ] ) ) { return; } this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); // support: jQuery <1.8 // jQuery <1.8 returns false if the request is canceled in beforeSend, // but as of 1.8, $.ajax() always returns a jqXHR object. if ( this.xhr && this.xhr.statusText !== "canceled" ) { tab.addClass( "ui-tabs-loading" ); panel.attr( "aria-busy", "true" ); this.xhr .success(function( response ) { // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 setTimeout(function() { panel.html( response ); that._trigger( "load", event, eventData ); }, 1 ); }) .complete(function( jqXHR, status ) { // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 setTimeout(function() { if ( status === "abort" ) { that.panels.stop( false, true ); } tab.removeClass( "ui-tabs-loading" ); panel.removeAttr( "aria-busy" ); if ( jqXHR === that.xhr ) { delete that.xhr; } }, 1 ); }); } }, // TODO: Remove this function in 1.10 when ajaxOptions is removed _ajaxSettings: function( anchor, event, eventData ) { var that = this; return { url: anchor.attr( "href" ), beforeSend: function( jqXHR, settings ) { return that._trigger( "beforeLoad", event, $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); } }; }, _getPanelForTab: function( tab ) { var id = $( tab ).attr( "aria-controls" ); return this.element.find( this._sanitizeSelector( "#" + id ) ); } }); // DEPRECATED if ( $.uiBackCompat !== false ) { // helper method for a lot of the back compat extensions $.ui.tabs.prototype._ui = function( tab, panel ) { return { tab: tab, panel: panel, index: this.anchors.index( tab ) }; }; // url method $.widget( "ui.tabs", $.ui.tabs, { url: function( index, url ) { this.anchors.eq( index ).attr( "href", url ); } }); // TODO: Remove _ajaxSettings() method when removing this extension // ajaxOptions and cache options $.widget( "ui.tabs", $.ui.tabs, { options: { ajaxOptions: null, cache: false }, _create: function() { this._super(); var that = this; this._on({ tabsbeforeload: function( event, ui ) { // tab is already cached if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) { event.preventDefault(); return; } ui.jqXHR.success(function() { if ( that.options.cache ) { $.data( ui.tab[ 0 ], "cache.tabs", true ); } }); }}); }, _ajaxSettings: function( anchor, event, ui ) { var ajaxOptions = this.options.ajaxOptions; return $.extend( {}, ajaxOptions, { error: function( xhr, status ) { try { // Passing index avoid a race condition when this method is // called after the user has selected another tab. // Pass the anchor that initiated this request allows // loadError to manipulate the tab content panel via $(a.hash) ajaxOptions.error( xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] ); } catch ( error ) {} } }, this._superApply( arguments ) ); }, _setOption: function( key, value ) { // reset cache if switching from cached to not cached if ( key === "cache" && value === false ) { this.anchors.removeData( "cache.tabs" ); } this._super( key, value ); }, _destroy: function() { this.anchors.removeData( "cache.tabs" ); this._super(); }, url: function( index ){ this.anchors.eq( index ).removeData( "cache.tabs" ); this._superApply( arguments ); } }); // abort method $.widget( "ui.tabs", $.ui.tabs, { abort: function() { if ( this.xhr ) { this.xhr.abort(); } } }); // spinner $.widget( "ui.tabs", $.ui.tabs, { options: { spinner: "Loading…" }, _create: function() { this._super(); this._on({ tabsbeforeload: function( event, ui ) { // Don't react to nested tabs or tabs that don't use a spinner if ( event.target !== this.element[ 0 ] || !this.options.spinner ) { return; } var span = ui.tab.find( "span" ), html = span.html(); span.html( this.options.spinner ); ui.jqXHR.complete(function() { span.html( html ); }); } }); } }); // enable/disable events $.widget( "ui.tabs", $.ui.tabs, { options: { enable: null, disable: null }, enable: function( index ) { var options = this.options, trigger; if ( index && options.disabled === true || ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) { trigger = true; } this._superApply( arguments ); if ( trigger ) { this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); } }, disable: function( index ) { var options = this.options, trigger; if ( index && options.disabled === false || ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) { trigger = true; } this._superApply( arguments ); if ( trigger ) { this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); } } }); // add/remove methods and events $.widget( "ui.tabs", $.ui.tabs, { options: { add: null, remove: null, tabTemplate: "
  • #{label}
  • " }, add: function( url, label, index ) { if ( index === undefined ) { index = this.anchors.length; } var doInsertAfter, panel, options = this.options, li = $( options.tabTemplate .replace( /#\{href\}/g, url ) .replace( /#\{label\}/g, label ) ), id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( li ); li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); li.attr( "aria-controls", id ); doInsertAfter = index >= this.tabs.length; // try to find an existing element before creating a new one panel = this.element.find( "#" + id ); if ( !panel.length ) { panel = this._createPanel( id ); if ( doInsertAfter ) { if ( index > 0 ) { panel.insertAfter( this.panels.eq( -1 ) ); } else { panel.appendTo( this.element ); } } else { panel.insertBefore( this.panels[ index ] ); } } panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); if ( doInsertAfter ) { li.appendTo( this.tablist ); } else { li.insertBefore( this.tabs[ index ] ); } options.disabled = $.map( options.disabled, function( n ) { return n >= index ? ++n : n; }); this.refresh(); if ( this.tabs.length === 1 && options.active === false ) { this.option( "active", 0 ); } this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); return this; }, remove: function( index ) { index = this._getIndex( index ); var options = this.options, tab = this.tabs.eq( index ).remove(), panel = this._getPanelForTab( tab ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. // We check for more than 2 tabs, because if there are only 2, // then when we remove this tab, there will only be one tab left // so we don't need to detect which tab to activate. if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } options.disabled = $.map( $.grep( options.disabled, function( n ) { return n !== index; }), function( n ) { return n >= index ? --n : n; }); this.refresh(); this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); return this; } }); // length method $.widget( "ui.tabs", $.ui.tabs, { length: function() { return this.anchors.length; } }); // panel ids (idPrefix option + title attribute) $.widget( "ui.tabs", $.ui.tabs, { options: { idPrefix: "ui-tabs-" }, _tabId: function( tab ) { var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; a = a[0]; return $( a ).closest( "li" ).attr( "aria-controls" ) || a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || this.options.idPrefix + getNextTabId(); } }); // _createPanel method $.widget( "ui.tabs", $.ui.tabs, { options: { panelTemplate: "
    " }, _createPanel: function( id ) { return $( this.options.panelTemplate ) .attr( "id", id ) .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .data( "ui-tabs-destroy", true ); } }); // selected option $.widget( "ui.tabs", $.ui.tabs, { _create: function() { var options = this.options; if ( options.active === null && options.selected !== undefined ) { options.active = options.selected === -1 ? false : options.selected; } this._super(); options.selected = options.active; if ( options.selected === false ) { options.selected = -1; } }, _setOption: function( key, value ) { if ( key !== "selected" ) { return this._super( key, value ); } var options = this.options; this._super( "active", value === -1 ? false : value ); options.selected = options.active; if ( options.selected === false ) { options.selected = -1; } }, _eventHandler: function() { this._superApply( arguments ); this.options.selected = this.options.active; if ( this.options.selected === false ) { this.options.selected = -1; } } }); // show and select event $.widget( "ui.tabs", $.ui.tabs, { options: { show: null, select: null }, _create: function() { this._super(); if ( this.options.active !== false ) { this._trigger( "show", null, this._ui( this.active.find( ".ui-tabs-anchor" )[ 0 ], this._getPanelForTab( this.active )[ 0 ] ) ); } }, _trigger: function( type, event, data ) { var tab, panel, ret = this._superApply( arguments ); if ( !ret ) { return false; } if ( type === "beforeActivate" ) { tab = data.newTab.length ? data.newTab : data.oldTab; panel = data.newPanel.length ? data.newPanel : data.oldPanel; ret = this._super( "select", event, { tab: tab.find( ".ui-tabs-anchor" )[ 0], panel: panel[ 0 ], index: tab.closest( "li" ).index() }); } else if ( type === "activate" && data.newTab.length ) { ret = this._super( "show", event, { tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], panel: data.newPanel[ 0 ], index: data.newTab.closest( "li" ).index() }); } return ret; } }); // select method $.widget( "ui.tabs", $.ui.tabs, { select: function( index ) { index = this._getIndex( index ); if ( index === -1 ) { if ( this.options.collapsible && this.options.selected !== -1 ) { index = this.options.selected; } else { return; } } this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace ); } }); // cookie option (function() { var listId = 0; $.widget( "ui.tabs", $.ui.tabs, { options: { cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } }, _create: function() { var options = this.options, active; if ( options.active == null && options.cookie ) { active = parseInt( this._cookie(), 10 ); if ( active === -1 ) { active = false; } options.active = active; } this._super(); }, _cookie: function( active ) { var cookie = [ this.cookie || ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ]; if ( arguments.length ) { cookie.push( active === false ? -1 : active ); cookie.push( this.options.cookie ); } return $.cookie.apply( null, cookie ); }, _refresh: function() { this._super(); if ( this.options.cookie ) { this._cookie( this.options.active, this.options.cookie ); } }, _eventHandler: function() { this._superApply( arguments ); if ( this.options.cookie ) { this._cookie( this.options.active, this.options.cookie ); } }, _destroy: function() { this._super(); if ( this.options.cookie ) { this._cookie( null, this.options.cookie ); } } }); })(); // load event $.widget( "ui.tabs", $.ui.tabs, { _trigger: function( type, event, data ) { var _data = $.extend( {}, data ); if ( type === "load" ) { _data.panel = _data.panel[ 0 ]; _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; } return this._super( type, event, _data ); } }); // fx option // The new animation options (show, hide) conflict with the old show callback. // The old fx option wins over show/hide anyway (always favor back-compat). // If a user wants to use the new animation API, they must give up the old API. $.widget( "ui.tabs", $.ui.tabs, { options: { fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 } }, _getFx: function() { var hide, show, fx = this.options.fx; if ( fx ) { if ( $.isArray( fx ) ) { hide = fx[ 0 ]; show = fx[ 1 ]; } else { hide = show = fx; } } return fx ? { show: show, hide: hide } : null; }, _toggle: function( event, eventData ) { var that = this, toShow = eventData.newPanel, toHide = eventData.oldPanel, fx = this._getFx(); if ( !fx ) { return this._super( event, eventData ); } that.running = true; function complete() { that.running = false; that._trigger( "activate", event, eventData ); } function show() { eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); if ( toShow.length && fx.show ) { toShow .animate( fx.show, fx.show.duration, function() { complete(); }); } else { toShow.show(); complete(); } } // start out by hiding, then showing, then completing if ( toHide.length && fx.hide ) { toHide.animate( fx.hide, fx.hide.duration, function() { eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); show(); }); } else { eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); toHide.hide(); show(); } } }); } })( jQuery ); (function( $ ) { var increments = 0; function addDescribedBy( elem, id ) { var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); describedby.push( id ); elem .data( "ui-tooltip-id", id ) .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); } function removeDescribedBy( elem ) { var id = elem.data( "ui-tooltip-id" ), describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), index = $.inArray( id, describedby ); if ( index !== -1 ) { describedby.splice( index, 1 ); } elem.removeData( "ui-tooltip-id" ); describedby = $.trim( describedby.join( " " ) ); if ( describedby ) { elem.attr( "aria-describedby", describedby ); } else { elem.removeAttr( "aria-describedby" ); } } $.widget( "ui.tooltip", { version: "1.9.2", options: { content: function() { return $( this ).attr( "title" ); }, hide: true, // Disabled elements have inconsistent behavior across browsers (#8661) items: "[title]:not([disabled])", position: { my: "left top+15", at: "left bottom", collision: "flipfit flip" }, show: true, tooltipClass: null, track: false, // callbacks close: null, open: null }, _create: function() { this._on({ mouseover: "open", focusin: "open" }); // IDs of generated tooltips, needed for destroy this.tooltips = {}; // IDs of parent tooltips where we removed the title attribute this.parents = {}; if ( this.options.disabled ) { this._disable(); } }, _setOption: function( key, value ) { var that = this; if ( key === "disabled" ) { this[ value ? "_disable" : "_enable" ](); this.options[ key ] = value; // disable element style changes return; } this._super( key, value ); if ( key === "content" ) { $.each( this.tooltips, function( id, element ) { that._updateContent( element ); }); } }, _disable: function() { var that = this; // close open tooltips $.each( this.tooltips, function( id, element ) { var event = $.Event( "blur" ); event.target = event.currentTarget = element[0]; that.close( event, true ); }); // remove title attributes to prevent native tooltips this.element.find( this.options.items ).andSelf().each(function() { var element = $( this ); if ( element.is( "[title]" ) ) { element .data( "ui-tooltip-title", element.attr( "title" ) ) .attr( "title", "" ); } }); }, _enable: function() { // restore title attributes this.element.find( this.options.items ).andSelf().each(function() { var element = $( this ); if ( element.data( "ui-tooltip-title" ) ) { element.attr( "title", element.data( "ui-tooltip-title" ) ); } }); }, open: function( event ) { var that = this, target = $( event ? event.target : this.element ) // we need closest here due to mouseover bubbling, // but always pointing at the same event target .closest( this.options.items ); // No element to show a tooltip for or the tooltip is already open if ( !target.length || target.data( "ui-tooltip-id" ) ) { return; } if ( target.attr( "title" ) ) { target.data( "ui-tooltip-title", target.attr( "title" ) ); } target.data( "ui-tooltip-open", true ); // kill parent tooltips, custom or native, for hover if ( event && event.type === "mouseover" ) { target.parents().each(function() { var parent = $( this ), blurEvent; if ( parent.data( "ui-tooltip-open" ) ) { blurEvent = $.Event( "blur" ); blurEvent.target = blurEvent.currentTarget = this; that.close( blurEvent, true ); } if ( parent.attr( "title" ) ) { parent.uniqueId(); that.parents[ this.id ] = { element: this, title: parent.attr( "title" ) }; parent.attr( "title", "" ); } }); } this._updateContent( target, event ); }, _updateContent: function( target, event ) { var content, contentOption = this.options.content, that = this, eventType = event ? event.type : null; if ( typeof contentOption === "string" ) { return this._open( event, target, contentOption ); } content = contentOption.call( target[0], function( response ) { // ignore async response if tooltip was closed already if ( !target.data( "ui-tooltip-open" ) ) { return; } // IE may instantly serve a cached response for ajax requests // delay this call to _open so the other call to _open runs first that._delay(function() { // jQuery creates a special event for focusin when it doesn't // exist natively. To improve performance, the native event // object is reused and the type is changed. Therefore, we can't // rely on the type being correct after the event finished // bubbling, so we set it back to the previous value. (#8740) if ( event ) { event.type = eventType; } this._open( event, target, response ); }); }); if ( content ) { this._open( event, target, content ); } }, _open: function( event, target, content ) { var tooltip, events, delayedShow, positionOption = $.extend( {}, this.options.position ); if ( !content ) { return; } // Content can be updated multiple times. If the tooltip already // exists, then just update the content and bail. tooltip = this._find( target ); if ( tooltip.length ) { tooltip.find( ".ui-tooltip-content" ).html( content ); return; } // if we have a title, clear it to prevent the native tooltip // we have to check first to avoid defining a title if none exists // (we don't want to cause an element to start matching [title]) // // We use removeAttr only for key events, to allow IE to export the correct // accessible attributes. For mouse events, set to empty string to avoid // native tooltip showing up (happens only when removing inside mouseover). if ( target.is( "[title]" ) ) { if ( event && event.type === "mouseover" ) { target.attr( "title", "" ); } else { target.removeAttr( "title" ); } } tooltip = this._tooltip( target ); addDescribedBy( target, tooltip.attr( "id" ) ); tooltip.find( ".ui-tooltip-content" ).html( content ); function position( event ) { positionOption.of = event; if ( tooltip.is( ":hidden" ) ) { return; } tooltip.position( positionOption ); } if ( this.options.track && event && /^mouse/.test( event.type ) ) { this._on( this.document, { mousemove: position }); // trigger once to override element-relative positioning position( event ); } else { tooltip.position( $.extend({ of: target }, this.options.position ) ); } tooltip.hide(); this._show( tooltip, this.options.show ); // Handle tracking tooltips that are shown with a delay (#8644). As soon // as the tooltip is visible, position the tooltip using the most recent // event. if ( this.options.show && this.options.show.delay ) { delayedShow = setInterval(function() { if ( tooltip.is( ":visible" ) ) { position( positionOption.of ); clearInterval( delayedShow ); } }, $.fx.interval ); } this._trigger( "open", event, { tooltip: tooltip } ); events = { keyup: function( event ) { if ( event.keyCode === $.ui.keyCode.ESCAPE ) { var fakeEvent = $.Event(event); fakeEvent.currentTarget = target[0]; this.close( fakeEvent, true ); } }, remove: function() { this._removeTooltip( tooltip ); } }; if ( !event || event.type === "mouseover" ) { events.mouseleave = "close"; } if ( !event || event.type === "focusin" ) { events.focusout = "close"; } this._on( true, target, events ); }, close: function( event ) { var that = this, target = $( event ? event.currentTarget : this.element ), tooltip = this._find( target ); // disabling closes the tooltip, so we need to track when we're closing // to avoid an infinite loop in case the tooltip becomes disabled on close if ( this.closing ) { return; } // only set title if we had one before (see comment in _open()) if ( target.data( "ui-tooltip-title" ) ) { target.attr( "title", target.data( "ui-tooltip-title" ) ); } removeDescribedBy( target ); tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { that._removeTooltip( $( this ) ); }); target.removeData( "ui-tooltip-open" ); this._off( target, "mouseleave focusout keyup" ); // Remove 'remove' binding only on delegated targets if ( target[0] !== this.element[0] ) { this._off( target, "remove" ); } this._off( this.document, "mousemove" ); if ( event && event.type === "mouseleave" ) { $.each( this.parents, function( id, parent ) { $( parent.element ).attr( "title", parent.title ); delete that.parents[ id ]; }); } this.closing = true; this._trigger( "close", event, { tooltip: tooltip } ); this.closing = false; }, _tooltip: function( element ) { var id = "ui-tooltip-" + increments++, tooltip = $( "
    " ) .attr({ id: id, role: "tooltip" }) .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + ( this.options.tooltipClass || "" ) ); $( "
    " ) .addClass( "ui-tooltip-content" ) .appendTo( tooltip ); tooltip.appendTo( this.document[0].body ); if ( $.fn.bgiframe ) { tooltip.bgiframe(); } this.tooltips[ id ] = element; return tooltip; }, _find: function( target ) { var id = target.data( "ui-tooltip-id" ); return id ? $( "#" + id ) : $(); }, _removeTooltip: function( tooltip ) { tooltip.remove(); delete this.tooltips[ tooltip.attr( "id" ) ]; }, _destroy: function() { var that = this; // close open tooltips $.each( this.tooltips, function( id, element ) { // Delegate to close method to handle common cleanup var event = $.Event( "blur" ); event.target = event.currentTarget = element[0]; that.close( event, true ); // Remove immediately; destroying an open tooltip doesn't use the // hide animation $( "#" + id ).remove(); // Restore the title if ( element.data( "ui-tooltip-title" ) ) { element.attr( "title", element.data( "ui-tooltip-title" ) ); element.removeData( "ui-tooltip-title" ); } }); } }); }( jQuery ) ); (function($, undefined) { /** * Unobtrusive scripting adapter for jQuery * https://github.com/rails/jquery-ujs * * Requires jQuery 1.7.0 or later. * * Released under the MIT license * */ // Cut down on the number if issues from people inadvertently including jquery_ujs twice // by detecting and raising an error when it happens. var alreadyInitialized = function() { var events = $._data(document, 'events'); return events && events.click && $.grep(events.click, function(e) { return e.namespace === 'rails'; }).length; } if ( alreadyInitialized() ) { $.error('jquery-ujs has already been loaded!'); } // Shorthand to make it a little easier to call public rails functions from within rails.js var rails; $.rails = rails = { // Link elements bound by jquery-ujs linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]', // Select elements bound by jquery-ujs inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', // Form elements bound by jquery-ujs formSubmitSelector: 'form', // Form input elements bound by jquery-ujs formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])', // Form input elements disabled during form submission disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]', // Form input elements re-enabled after form submission enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', // Form required input elements requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', // Form file input elements fileInputSelector: 'input[type=file]', // Link onClick disable selector with possible reenable after remote submission linkDisableSelector: 'a[data-disable-with]', // Make sure that every Ajax request sends the CSRF token CSRFProtection: function(xhr) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); }, // Triggers an event on an element and returns false if the event result is false fire: function(obj, name, data) { var event = $.Event(name); obj.trigger(event, data); return event.result !== false; }, // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm confirm: function(message) { return confirm(message); }, // Default ajax function, may be overridden with custom function in $.rails.ajax ajax: function(options) { return $.ajax(options); }, // Default way to get an element's href. May be overridden at $.rails.href. href: function(element) { return element.attr('href'); }, // Submits "remote" forms and links with ajax handleRemote: function(element) { var method, url, data, elCrossDomain, crossDomain, withCredentials, dataType, options; if (rails.fire(element, 'ajax:before')) { elCrossDomain = element.data('cross-domain'); crossDomain = elCrossDomain === undefined ? null : elCrossDomain; withCredentials = element.data('with-credentials') || null; dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); if (element.is('form')) { method = element.attr('method'); url = element.attr('action'); data = element.serializeArray(); // memoized value from clicked submit button var button = element.data('ujs:submit-button'); if (button) { data.push(button); element.data('ujs:submit-button', null); } } else if (element.is(rails.inputChangeSelector)) { method = element.data('method'); url = element.data('url'); data = element.serialize(); if (element.data('params')) data = data + "&" + element.data('params'); } else { method = element.data('method'); url = rails.href(element); data = element.data('params') || null; } options = { type: method || 'GET', data: data, dataType: dataType, // stopping the "ajax:beforeSend" event will cancel the ajax request beforeSend: function(xhr, settings) { if (settings.dataType === undefined) { xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); } return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); }, success: function(data, status, xhr) { element.trigger('ajax:success', [data, status, xhr]); }, complete: function(xhr, status) { element.trigger('ajax:complete', [xhr, status]); }, error: function(xhr, status, error) { element.trigger('ajax:error', [xhr, status, error]); }, crossDomain: crossDomain }; // There is no withCredentials for IE6-8 when // "Enable native XMLHTTP support" is disabled if (withCredentials) { options.xhrFields = { withCredentials: withCredentials }; } // Only pass url to `ajax` options if not blank if (url) { options.url = url; } var jqxhr = rails.ajax(options); element.trigger('ajax:send', jqxhr); return jqxhr; } else { return false; } }, // Handles "data-method" on links such as: // Delete handleMethod: function(link) { var href = rails.href(link), method = link.data('method'), target = link.attr('target'), csrf_token = $('meta[name=csrf-token]').attr('content'), csrf_param = $('meta[name=csrf-param]').attr('content'), form = $('
    '), metadata_input = ''; if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += ''; } if (target) { form.attr('target', target); } form.hide().append(metadata_input).appendTo('body'); form.submit(); }, /* Disables form elements: - Caches element value in 'ujs:enable-with' data store - Replaces element text with value of 'data-disable-with' attribute - Sets disabled property to true */ disableFormElements: function(form) { form.find(rails.disableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; element.data('ujs:enable-with', element[method]()); element[method](element.data('disable-with')); element.prop('disabled', true); }); }, /* Re-enables disabled form elements: - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) - Sets disabled property to false */ enableFormElements: function(form) { form.find(rails.enableSelector).each(function() { var element = $(this), method = element.is('button') ? 'html' : 'val'; if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with')); element.prop('disabled', false); }); }, /* For 'data-confirm' attribute: - Fires `confirm` event - Shows the confirmation dialog - Fires the `confirm:complete` event Returns `true` if no function stops the chain and user chose yes; `false` otherwise. Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. */ allowAction: function(element) { var message = element.data('confirm'), answer = false, callback; if (!message) { return true; } if (rails.fire(element, 'confirm')) { answer = rails.confirm(message); callback = rails.fire(element, 'confirm:complete', [answer]); } return answer && callback; }, // Helper function which checks for blank inputs in a form that match the specified CSS selector blankInputs: function(form, specifiedSelector, nonBlank) { var inputs = $(), input, valueToCheck, selector = specifiedSelector || 'input,textarea', allInputs = form.find(selector); allInputs.each(function() { input = $(this); valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : input.val(); // If nonBlank and valueToCheck are both truthy, or nonBlank and valueToCheck are both falsey if (!valueToCheck === !nonBlank) { // Don't count unchecked required radio if other radio with same name is checked if (input.is('input[type=radio]') && allInputs.filter('input[type=radio]:checked[name="' + input.attr('name') + '"]').length) { return true; // Skip to next input } inputs = inputs.add(input); } }); return inputs.length ? inputs : false; }, // Helper function which checks for non-blank inputs in a form that match the specified CSS selector nonBlankInputs: function(form, specifiedSelector) { return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank }, // Helper function, needed to provide consistent behavior in IE stopEverything: function(e) { $(e.target).trigger('ujs:everythingStopped'); e.stopImmediatePropagation(); return false; }, // find all the submit events directly bound to the form and // manually invoke them. If anyone returns false then stop the loop callFormSubmitBindings: function(form, event) { var events = form.data('events'), continuePropagation = true; if (events !== undefined && events['submit'] !== undefined) { $.each(events['submit'], function(i, obj){ if (typeof obj.handler === 'function') return continuePropagation = obj.handler(event); }); } return continuePropagation; }, // replace element's html with the 'data-disable-with' after storing original html // and prevent clicking on it disableElement: function(element) { element.data('ujs:enable-with', element.html()); // store enabled state element.html(element.data('disable-with')); // set to disabled state element.bind('click.railsDisable', function(e) { // prevent further clicking return rails.stopEverything(e); }); }, // restore element to its original state which was disabled by 'disableElement' above enableElement: function(element) { if (element.data('ujs:enable-with') !== undefined) { element.html(element.data('ujs:enable-with')); // set to old enabled state // this should be element.removeData('ujs:enable-with') // but, there is currently a bug in jquery which makes hyphenated data attributes not get removed element.data('ujs:enable-with', false); // clean up cache } element.unbind('click.railsDisable'); // enable element } }; if (rails.fire($(document), 'rails:attachBindings')) { $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() { rails.enableElement($(this)); }); $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) { var link = $(this), method = link.data('method'), data = link.data('params'); if (!rails.allowAction(link)) return rails.stopEverything(e); if (link.is(rails.linkDisableSelector)) rails.disableElement(link); if (link.data('remote') !== undefined) { if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; } var handleRemote = rails.handleRemote(link); // response from rails.handleRemote() will either be false or a deferred object promise. if (handleRemote === false) { rails.enableElement(link); } else { handleRemote.error( function() { rails.enableElement(link); } ); } return false; } else if (link.data('method')) { rails.handleMethod(link); return false; } }); $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) { var link = $(this); if (!rails.allowAction(link)) return rails.stopEverything(e); rails.handleRemote(link); return false; }); $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) { var form = $(this), remote = form.data('remote') !== undefined, blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector), nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); if (!rails.allowAction(form)) return rails.stopEverything(e); // skip other logic when required values are missing or file upload is present if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { return rails.stopEverything(e); } if (remote) { if (nonBlankFileInputs) { // slight timeout so that the submit button gets properly serialized // (make it easy for event handler to serialize form without disabled values) setTimeout(function(){ rails.disableFormElements(form); }, 13); var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); // re-enable form elements if event bindings return false (canceling normal form submission) if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } return aborted; } // If browser does not support submit bubbling, then this live-binding will be called before direct // bindings. Therefore, we should directly call any direct bindings before remotely submitting form. if (!$.support.submitBubbles && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e); rails.handleRemote(form); return false; } else { // slight timeout so that the submit button gets properly serialized setTimeout(function(){ rails.disableFormElements(form); }, 13); } }); $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) { var button = $(this); if (!rails.allowAction(button)) return rails.stopEverything(event); // register the pressed submit button var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null; button.closest('form').data('ujs:submit-button', data); }); $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) { if (this == event.target) rails.disableFormElements($(this)); }); $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { if (this == event.target) rails.enableFormElements($(this)); }); $(function(){ // making sure that all forms have actual up-to-date token(cached forms contain old one) var csrf_token = $('meta[name=csrf-token]').attr('content'); var csrf_param = $('meta[name=csrf-param]').attr('content'); $('form input[name="' + csrf_param + '"]').val(csrf_token); }); } })( jQuery ); /* ============================================================ * bootstrap-dropdown.js v2.0.4 * http://twitter.github.com/bootstrap/javascript.html#dropdowns * ============================================================ * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================ */ !function ($) { "use strict"; // jshint ;_; /* DROPDOWN CLASS DEFINITION * ========================= */ var toggle = '[data-toggle="dropdown"]' , Dropdown = function (element) { var $el = $(element).on('click.dropdown.data-api', this.toggle) $('html').on('click.dropdown.data-api', function () { $el.parent().removeClass('open') }) } Dropdown.prototype = { constructor: Dropdown , toggle: function (e) { var $this = $(this) , $parent , selector , isActive if ($this.is('.disabled, :disabled')) return selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 } $parent = $(selector) $parent.length || ($parent = $this.parent()) isActive = $parent.hasClass('open') clearMenus() if (!isActive) $parent.toggleClass('open') return false } } function clearMenus() { $(toggle).parent().removeClass('open') } /* DROPDOWN PLUGIN DEFINITION * ========================== */ $.fn.dropdown = function (option) { return this.each(function () { var $this = $(this) , data = $this.data('dropdown') if (!data) $this.data('dropdown', (data = new Dropdown(this))) if (typeof option == 'string') data[option].call($this) }) } $.fn.dropdown.Constructor = Dropdown /* APPLY TO STANDARD DROPDOWN ELEMENTS * =================================== */ $(function () { $('html').on('click.dropdown.data-api', clearMenus) $('body') .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) }) }(window.jQuery); /* ======================================================== * bootstrap-tab.js v2.0.4 * http://twitter.github.com/bootstrap/javascript.html#tabs * ======================================================== * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ======================================================== */ !function ($) { "use strict"; // jshint ;_; /* TAB CLASS DEFINITION * ==================== */ var Tab = function ( element ) { this.element = $(element) } Tab.prototype = { constructor: Tab , show: function () { var $this = this.element , $ul = $this.closest('ul:not(.dropdown-menu)') , selector = $this.attr('data-target') , previous , $target , e if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 } if ( $this.parent('li').hasClass('active') ) return previous = $ul.find('.active a').last()[0] e = $.Event('show', { relatedTarget: previous }) $this.trigger(e) if (e.isDefaultPrevented()) return $target = $(selector) this.activate($this.parent('li'), $ul) this.activate($target, $target.parent(), function () { $this.trigger({ type: 'shown' , relatedTarget: previous }) }) } , activate: function ( element, container, callback) { var $active = container.find('> .active') , transition = callback && $.support.transition && $active.hasClass('fade') function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') element.addClass('active') if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if ( element.parent('.dropdown-menu') ) { element.closest('li.dropdown').addClass('active') } callback && callback() } transition ? $active.one($.support.transition.end, next) : next() $active.removeClass('in') } } /* TAB PLUGIN DEFINITION * ===================== */ $.fn.tab = function ( option ) { return this.each(function () { var $this = $(this) , data = $this.data('tab') if (!data) $this.data('tab', (data = new Tab(this))) if (typeof option == 'string') data[option]() }) } $.fn.tab.Constructor = Tab /* TAB DATA-API * ============ */ $(function () { $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { e.preventDefault() $(this).tab('show') }) }) }(window.jQuery); /* * jQuery UI Nested Sortable * v 2.0 / 29 oct 2012 * http://mjsarfatti.com/sandbox/nestedSortable * * Depends on: * jquery.ui.sortable.js 1.10+ * * Copyright (c) 2010-2013 Manuele J Sarfatti * Licensed under the MIT License * http://www.opensource.org/licenses/mit-license.php */ (function($) { function isOverAxis( x, reference, size ) { return ( x > reference ) && ( x < ( reference + size ) ); } $.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, { options: { doNotClear: false, expandOnHover: 700, isAllowed: function(placeholder, placeholderParent, originalItem) { return true; }, isTree: false, listType: 'ol', maxLevels: 0, protectRoot: false, rootID: null, rtl: false, startCollapsed: false, tabSize: 20, branchClass: 'mjs-nestedSortable-branch', collapsedClass: 'mjs-nestedSortable-collapsed', disableNestingClass: 'mjs-nestedSortable-no-nesting', errorClass: 'mjs-nestedSortable-error', expandedClass: 'mjs-nestedSortable-expanded', hoveringClass: 'mjs-nestedSortable-hovering', leafClass: 'mjs-nestedSortable-leaf' }, _create: function() { this.element.data('ui-sortable', this.element.data('mjs-nestedSortable')); // mjs - prevent browser from freezing if the HTML is not correct if (!this.element.is(this.options.listType)) throw new Error('nestedSortable: Please check that the listType option is set to your actual list type'); // mjs - force 'intersect' tolerance method if we have a tree with expanding/collapsing functionality if (this.options.isTree) this.options.tolerance = 'intersect'; $.ui.sortable.prototype._create.apply(this, arguments); // mjs - prepare the tree by applying the right classes (the CSS is responsible for actual hide/show functionality) if (this.options.isTree) { var self = this; $(this.items).each(function() { var $li = this.item; if ($li.children(self.options.listType).length) { $li.addClass(self.options.branchClass); // expand/collapse class only if they have children if (self.options.startCollapsed) $li.addClass(self.options.collapsedClass); else $li.addClass(self.options.expandedClass); } else { $li.addClass(self.options.leafClass); } }) } }, _destroy: function() { this.element .removeData("mjs-nestedSortable") .removeData("ui-sortable"); return $.ui.sortable.prototype._destroy.apply(this, arguments); }, _mouseDrag: function(event) { var i, item, itemElement, intersection, o = this.options, scrolled = false; //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); if (!this.lastPositionAbs) { this.lastPositionAbs = this.positionAbs; } //Do scrolling if(this.options.scroll) { if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; } if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; } } else { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); } if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); } //Regenerate the absolute position used for position checks this.positionAbs = this._convertPositionTo("absolute"); // mjs - find the top offset before rearrangement, var previousTopOffset = this.placeholder.offset().top; //Set the helper position if(!this.options.axis || this.options.axis !== "y") { this.helper[0].style.left = this.position.left+"px"; } if(!this.options.axis || this.options.axis !== "x") { this.helper[0].style.top = this.position.top+"px"; } // mjs - check and reset hovering state at each cycle this.hovering = this.hovering ? this.hovering : null; this.mouseentered = this.mouseentered ? this.mouseentered : false; // mjs - let's start caching some variables var parentItem = (this.placeholder[0].parentNode.parentNode && $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length) ? $(this.placeholder[0].parentNode.parentNode) : null, level = this._getLevel(this.placeholder), childLevels = this._getChildLevels(this.helper); var newList = document.createElement(o.listType); //Rearrange for (i = this.items.length - 1; i >= 0; i--) { //Cache variables and intersection, continue if no intersection item = this.items[i]; itemElement = item.item[0]; intersection = this._intersectsWithPointer(item); if (!intersection) { continue; } // Only put the placeholder inside the current Container, skip all // items form other containers. This works because when moving // an item from one container to another the // currentContainer is switched before the placeholder is moved. // // Without this moving items in "sub-sortables" can cause the placeholder to jitter // beetween the outer and inner container. if (item.instance !== this.currentContainer) { continue; } // cannot intersect with itself // no useless actions that have been done before // no action if the item moved is the parent of the item checked if (itemElement !== this.currentItem[0] && this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && !$.contains(this.placeholder[0], itemElement) && (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) ) { // mjs - we are intersecting an element: trigger the mouseenter event and store this state if (!this.mouseentered) { $(itemElement).mouseenter(); this.mouseentered = true; } // mjs - if the element has children and they are hidden, show them after a delay (CSS responsible) if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) { if (!this.hovering) { $(itemElement).addClass(o.hoveringClass); var self = this; this.hovering = window.setTimeout(function() { $(itemElement).removeClass(o.collapsedClass).addClass(o.expandedClass); self.refreshPositions(); self._trigger("expand", event, self._uiHash()); }, o.expandOnHover); } } this.direction = intersection == 1 ? "down" : "up"; // mjs - rearrange the elements and reset timeouts and hovering state if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { $(itemElement).mouseleave(); this.mouseentered = false; $(itemElement).removeClass(o.hoveringClass); this.hovering && window.clearTimeout(this.hovering); this.hovering = null; // mjs - do not switch container if it's a root item and 'protectRoot' is true // or if it's not a root item but we are trying to make it root if (o.protectRoot && ! (this.currentItem[0].parentNode == this.element[0] // it's a root item && itemElement.parentNode != this.element[0]) // it's intersecting a non-root item ) { if (this.currentItem[0].parentNode != this.element[0] && itemElement.parentNode == this.element[0] ) { if ( ! $(itemElement).children(o.listType).length) { itemElement.appendChild(newList); o.isTree && $(itemElement).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass); } var a = this.direction === "down" ? $(itemElement).prev().children(o.listType) : $(itemElement).children(o.listType); if (a[0] !== undefined) { this._rearrange(event, null, a); } } else { this._rearrange(event, item); } } else if ( ! o.protectRoot) { this._rearrange(event, item); } } else { break; } // Clear emtpy ul's/ol's this._clearEmpty(itemElement); this._trigger("change", event, this._uiHash()); break; } } // mjs - to find the previous sibling in the list, keep backtracking until we hit a valid list item. var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null; if (previousItem != null) { while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) { if (previousItem[0].previousSibling) { previousItem = $(previousItem[0].previousSibling); } else { previousItem = null; break; } } } // mjs - to find the next sibling in the list, keep stepping forward until we hit a valid list item. var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null; if (nextItem != null) { while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) { if (nextItem[0].nextSibling) { nextItem = $(nextItem[0].nextSibling); } else { nextItem = null; break; } } } this.beyondMaxLevels = 0; // mjs - if the item is moved to the left, send it one level up but only if it's at the bottom of the list if (parentItem != null && nextItem == null && ! (o.protectRoot && parentItem[0].parentNode == this.element[0]) && (o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth()) || ! o.rtl && (this.positionAbs.left < parentItem.offset().left)) ) { parentItem.after(this.placeholder[0]); if (o.isTree && parentItem.children(o.listItem).children('li:visible:not(.ui-sortable-helper)').length < 1) { parentItem.removeClass(this.options.branchClass + ' ' + this.options.expandedClass) .addClass(this.options.leafClass); } this._clearEmpty(parentItem[0]); this._trigger("change", event, this._uiHash()); } // mjs - if the item is below a sibling and is moved to the right, make it a child of that sibling else if (previousItem != null && ! previousItem.hasClass(o.disableNestingClass) && (previousItem.children(o.listType).length && previousItem.children(o.listType).is(':visible') || ! previousItem.children(o.listType).length) && ! (o.protectRoot && this.currentItem[0].parentNode == this.element[0]) && (o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize) || ! o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize)) ) { this._isAllowed(previousItem, level, level+childLevels+1); if (!previousItem.children(o.listType).length) { previousItem[0].appendChild(newList); o.isTree && previousItem.removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass); } // mjs - if this item is being moved from the top, add it to the top of the list. if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) { previousItem.children(o.listType).prepend(this.placeholder); } // mjs - otherwise, add it to the bottom of the list. else { previousItem.children(o.listType)[0].appendChild(this.placeholder[0]); } this._trigger("change", event, this._uiHash()); } else { this._isAllowed(parentItem, level, level+childLevels); } //Post events to containers this._contactContainers(event); //Interconnect with droppables if($.ui.ddmanager) { $.ui.ddmanager.drag(this, event); } //Call callbacks this._trigger('sort', event, this._uiHash()); this.lastPositionAbs = this.positionAbs; return false; }, _mouseStop: function(event, noPropagation) { // mjs - if the item is in a position not allowed, send it back if (this.beyondMaxLevels) { this.placeholder.removeClass(this.options.errorClass); if (this.domPosition.prev) { $(this.domPosition.prev).after(this.placeholder); } else { $(this.domPosition.parent).prepend(this.placeholder); } this._trigger("revert", event, this._uiHash()); } // mjs - clear the hovering timeout, just to be sure $('.'+this.options.hoveringClass).mouseleave().removeClass(this.options.hoveringClass); this.mouseentered = false; this.hovering && window.clearTimeout(this.hovering); this.hovering = null; $.ui.sortable.prototype._mouseStop.apply(this, arguments); }, // mjs - this function is slightly modified to make it easier to hover over a collapsed element and have it expand _intersectsWithSides: function(item) { var half = this.options.isTree ? .8 : .5; var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height*half), item.height), isOverTopHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top - (item.height*half), item.height), isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if (this.floating && horizontalDirection) { return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); } else { return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && isOverTopHalf)); } }, _contactContainers: function(event) { if (this.options.protectRoot && this.currentItem[0].parentNode == this.element[0] ) { return; } $.ui.sortable.prototype._contactContainers.apply(this, arguments); }, _clear: function(event, noPropagation) { $.ui.sortable.prototype._clear.apply(this, arguments); // mjs - clean last empty ul/ol for (var i = this.items.length - 1; i >= 0; i--) { var item = this.items[i].item[0]; this._clearEmpty(item); } }, serialize: function(options) { var o = $.extend({}, this.options, options), items = this._getItemsAsjQuery(o && o.connected), str = []; $(items).each(function() { var res = ($(o.item || this).attr(o.attribute || 'id') || '') .match(o.expression || (/(.+)[-=_](.+)/)), pid = ($(o.item || this).parent(o.listType) .parent(o.items) .attr(o.attribute || 'id') || '') .match(o.expression || (/(.+)[-=_](.+)/)); if (res) { str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']') + '=' + (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID)); } }); if(!str.length && o.key) { str.push(o.key + '='); } return str.join('&'); }, toHierarchy: function(options) { var o = $.extend({}, this.options, options), sDepth = o.startDepthCount || 0, ret = []; $(this.element).children(o.items).each(function () { var level = _recursiveItems(this); ret.push(level); }); return ret; function _recursiveItems(item) { var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); if (id) { var currentItem = {"id" : id[2]}; if ($(item).children(o.listType).children(o.items).length > 0) { currentItem.children = []; $(item).children(o.listType).children(o.items).each(function() { var level = _recursiveItems(this); currentItem.children.push(level); }); } return currentItem; } } }, toArray: function(options) { var o = $.extend({}, this.options, options), sDepth = o.startDepthCount || 0, ret = [], left = 2; ret.push({ "item_id": o.rootID, "parent_id": 'none', "depth": sDepth, "left": '1', "right": ($(o.items, this.element).length + 1) * 2 }); $(this.element).children(o.items).each(function () { left = _recursiveArray(this, sDepth + 1, left); }); ret = ret.sort(function(a,b){ return (a.left - b.left); }); return ret; function _recursiveArray(item, depth, left) { var right = left + 1, id, pid; if ($(item).children(o.listType).children(o.items).length > 0) { depth ++; $(item).children(o.listType).children(o.items).each(function () { right = _recursiveArray($(this), depth, right); }); depth --; } id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/)); if (depth === sDepth + 1) { pid = o.rootID; } else { var parentItem = ($(item).parent(o.listType) .parent(o.items) .attr(o.attribute || 'id')) .match(o.expression || (/(.+)[-=_](.+)/)); pid = parentItem[2]; } if (id) { ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right}); } left = right + 1; return left; } }, _clearEmpty: function(item) { var o = this.options; var emptyList = $(item).children(o.listType); if (emptyList.length && !emptyList.children().length && !o.doNotClear) { o.isTree && $(item).removeClass(o.branchClass + ' ' + o.expandedClass).addClass(o.leafClass); emptyList.remove(); } else if (o.isTree && emptyList.length && emptyList.children().length && emptyList.is(':visible')) { $(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.expandedClass); } else if (o.isTree && emptyList.length && emptyList.children().length && !emptyList.is(':visible')) { $(item).removeClass(o.leafClass).addClass(o.branchClass + ' ' + o.collapsedClass); } }, _getLevel: function(item) { var level = 1; if (this.options.listType) { var list = item.closest(this.options.listType); while (list && list.length > 0 && !list.is('.ui-sortable')) { level++; list = list.parent().closest(this.options.listType); } } return level; }, _getChildLevels: function(parent, depth) { var self = this, o = this.options, result = 0; depth = depth || 0; $(parent).children(o.listType).children(o.items).each(function (index, child) { result = Math.max(self._getChildLevels(child, depth + 1), result); }); return depth ? result + 1 : result; }, _isAllowed: function(parentItem, level, levels) { var o = this.options, maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list // mjs - is the root protected? // mjs - are we nesting too deep? if ( ! o.isAllowed(this.placeholder, parentItem, this.currentItem)) { this.placeholder.addClass(o.errorClass); if (maxLevels < levels && maxLevels != 0) { this.beyondMaxLevels = levels - maxLevels; } else { this.beyondMaxLevels = 1; } } else { if (maxLevels < levels && maxLevels != 0) { this.placeholder.addClass(o.errorClass); this.beyondMaxLevels = levels - maxLevels; } else { this.placeholder.removeClass(o.errorClass); this.beyondMaxLevels = 0; } } } })); $.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options); })(jQuery); /* * jQuery UI Widget 1.9.1+amd * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/jQuery.widget/ */ (function (factory) { if (typeof define === "function" && define.amd) { // Register as an anonymous AMD module: define(["jquery"], factory); } else { // Browser globals: factory(jQuery); } }(function( $, undefined ) { var uuid = 0, slice = Array.prototype.slice, _cleanData = $.cleanData; $.cleanData = function( elems ) { for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { try { $( elem ).triggerHandler( "remove" ); // http://bugs.jquery.com/ticket/8235 } catch( e ) {} } _cleanData( elems ); }; $.widget = function( name, base, prototype ) { var fullName, existingConstructor, constructor, basePrototype, namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; fullName = namespace + "-" + name; if ( !prototype ) { prototype = base; base = $.Widget; } // create selector for plugin $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { return !!$.data( elem, fullName ); }; $[ namespace ] = $[ namespace ] || {}; existingConstructor = $[ namespace ][ name ]; constructor = $[ namespace ][ name ] = function( options, element ) { // allow instantiation without "new" keyword if ( !this._createWidget ) { return new constructor( options, element ); } // allow instantiation without initializing for simple inheritance // must use "new" keyword (the code above always passes args) if ( arguments.length ) { this._createWidget( options, element ); } }; // extend with the existing constructor to carry over any static properties $.extend( constructor, existingConstructor, { version: prototype.version, // copy the object used to create the prototype in case we need to // redefine the widget later _proto: $.extend( {}, prototype ), // track widgets that inherit from this widget in case this widget is // redefined after a widget inherits from it _childConstructors: [] }); basePrototype = new base(); // we need to make the options hash a property directly on the new instance // otherwise we'll modify the options hash on the prototype that we're // inheriting from basePrototype.options = $.widget.extend( {}, basePrototype.options ); $.each( prototype, function( prop, value ) { if ( $.isFunction( value ) ) { prototype[ prop ] = (function() { var _super = function() { return base.prototype[ prop ].apply( this, arguments ); }, _superApply = function( args ) { return base.prototype[ prop ].apply( this, args ); }; return function() { var __super = this._super, __superApply = this._superApply, returnValue; this._super = _super; this._superApply = _superApply; returnValue = value.apply( this, arguments ); this._super = __super; this._superApply = __superApply; return returnValue; }; })(); } }); constructor.prototype = $.widget.extend( basePrototype, { // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based widgetEventPrefix: basePrototype.widgetEventPrefix || name }, prototype, { constructor: constructor, namespace: namespace, widgetName: name, // TODO remove widgetBaseClass, see #8155 widgetBaseClass: fullName, widgetFullName: fullName }); // If this widget is being redefined then we need to find all widgets that // are inheriting from it and redefine all of them so that they inherit from // the new version of this widget. We're essentially trying to replace one // level in the prototype chain. if ( existingConstructor ) { $.each( existingConstructor._childConstructors, function( i, child ) { var childPrototype = child.prototype; // redefine the child widget using the same prototype that was // originally used, but inherit from the new version of the base $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); }); // remove the list of existing child constructors from the old constructor // so the old child constructors can be garbage collected delete existingConstructor._childConstructors; } else { base._childConstructors.push( constructor ); } $.widget.bridge( name, constructor ); }; $.widget.extend = function( target ) { var input = slice.call( arguments, 1 ), inputIndex = 0, inputLength = input.length, key, value; for ( ; inputIndex < inputLength; inputIndex++ ) { for ( key in input[ inputIndex ] ) { value = input[ inputIndex ][ key ]; if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { // Clone objects if ( $.isPlainObject( value ) ) { target[ key ] = $.isPlainObject( target[ key ] ) ? $.widget.extend( {}, target[ key ], value ) : // Don't extend strings, arrays, etc. with objects $.widget.extend( {}, value ); // Copy everything else by reference } else { target[ key ] = value; } } } } return target; }; $.widget.bridge = function( name, object ) { var fullName = object.prototype.widgetFullName; $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string", args = slice.call( arguments, 1 ), returnValue = this; // allow multiple hashes to be passed on init options = !isMethodCall && args.length ? $.widget.extend.apply( null, [ options ].concat(args) ) : options; if ( isMethodCall ) { this.each(function() { var methodValue, instance = $.data( this, fullName ); if ( !instance ) { return $.error( "cannot call methods on " + name + " prior to initialization; " + "attempted to call method '" + options + "'" ); } if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { return $.error( "no such method '" + options + "' for " + name + " widget instance" ); } methodValue = instance[ options ].apply( instance, args ); if ( methodValue !== instance && methodValue !== undefined ) { returnValue = methodValue && methodValue.jquery ? returnValue.pushStack( methodValue.get() ) : methodValue; return false; } }); } else { this.each(function() { var instance = $.data( this, fullName ); if ( instance ) { instance.option( options || {} )._init(); } else { new object( options, this ); } }); } return returnValue; }; }; $.Widget = function( /* options, element */ ) {}; $.Widget._childConstructors = []; $.Widget.prototype = { widgetName: "widget", widgetEventPrefix: "", defaultElement: "
    ", options: { disabled: false, // callbacks create: null }, _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); this.uuid = uuid++; this.eventNamespace = "." + this.widgetName + this.uuid; this.options = $.widget.extend( {}, this.options, this._getCreateOptions(), options ); this.bindings = $(); this.hoverable = $(); this.focusable = $(); if ( element !== this ) { // 1.9 BC for #7810 // TODO remove dual storage $.data( element, this.widgetName, this ); $.data( element, this.widgetFullName, this ); this._on( this.element, { remove: function( event ) { if ( event.target === element ) { this.destroy(); } } }); this.document = $( element.style ? // element within the document element.ownerDocument : // element is window or document element.document || element ); this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); } this._create(); this._trigger( "create", null, this._getCreateEventData() ); this._init(); }, _getCreateOptions: $.noop, _getCreateEventData: $.noop, _create: $.noop, _init: $.noop, destroy: function() { this._destroy(); // we can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element .unbind( this.eventNamespace ) // 1.9 BC for #7810 // TODO remove dual storage .removeData( this.widgetName ) .removeData( this.widgetFullName ) // support: jquery <1.6.3 // http://bugs.jquery.com/ticket/9413 .removeData( $.camelCase( this.widgetFullName ) ); this.widget() .unbind( this.eventNamespace ) .removeAttr( "aria-disabled" ) .removeClass( this.widgetFullName + "-disabled " + "ui-state-disabled" ); // clean up events and states this.bindings.unbind( this.eventNamespace ); this.hoverable.removeClass( "ui-state-hover" ); this.focusable.removeClass( "ui-state-focus" ); }, _destroy: $.noop, widget: function() { return this.element; }, option: function( key, value ) { var options = key, parts, curOption, i; if ( arguments.length === 0 ) { // don't return a reference to the internal hash return $.widget.extend( {}, this.options ); } if ( typeof key === "string" ) { // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } options = {}; parts = key.split( "." ); key = parts.shift(); if ( parts.length ) { curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); for ( i = 0; i < parts.length - 1; i++ ) { curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; curOption = curOption[ parts[ i ] ]; } key = parts.pop(); if ( value === undefined ) { return curOption[ key ] === undefined ? null : curOption[ key ]; } curOption[ key ] = value; } else { if ( value === undefined ) { return this.options[ key ] === undefined ? null : this.options[ key ]; } options[ key ] = value; } } this._setOptions( options ); return this; }, _setOptions: function( options ) { var key; for ( key in options ) { this._setOption( key, options[ key ] ); } return this; }, _setOption: function( key, value ) { this.options[ key ] = value; if ( key === "disabled" ) { this.widget() .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) .attr( "aria-disabled", value ); this.hoverable.removeClass( "ui-state-hover" ); this.focusable.removeClass( "ui-state-focus" ); } return this; }, enable: function() { return this._setOption( "disabled", false ); }, disable: function() { return this._setOption( "disabled", true ); }, _on: function( element, handlers ) { var delegateElement, instance = this; // no element argument, shuffle and use this.element if ( !handlers ) { handlers = element; element = this.element; delegateElement = this.widget(); } else { // accept selectors, DOM elements element = delegateElement = $( element ); this.bindings = this.bindings.add( element ); } $.each( handlers, function( event, handler ) { function handlerProxy() { // allow widgets to customize the disabled handling // - disabled as an array instead of boolean // - disabled class as method for disabling individual parts if ( instance.options.disabled === true || $( this ).hasClass( "ui-state-disabled" ) ) { return; } return ( typeof handler === "string" ? instance[ handler ] : handler ) .apply( instance, arguments ); } // copy the guid so direct unbinding works if ( typeof handler !== "string" ) { handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++; } var match = event.match( /^(\w+)\s*(.*)$/ ), eventName = match[1] + instance.eventNamespace, selector = match[2]; if ( selector ) { delegateElement.delegate( selector, eventName, handlerProxy ); } else { element.bind( eventName, handlerProxy ); } }); }, _off: function( element, eventName ) { eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; element.unbind( eventName ).undelegate( eventName ); }, _delay: function( handler, delay ) { function handlerProxy() { return ( typeof handler === "string" ? instance[ handler ] : handler ) .apply( instance, arguments ); } var instance = this; return setTimeout( handlerProxy, delay || 0 ); }, _hoverable: function( element ) { this.hoverable = this.hoverable.add( element ); this._on( element, { mouseenter: function( event ) { $( event.currentTarget ).addClass( "ui-state-hover" ); }, mouseleave: function( event ) { $( event.currentTarget ).removeClass( "ui-state-hover" ); } }); }, _focusable: function( element ) { this.focusable = this.focusable.add( element ); this._on( element, { focusin: function( event ) { $( event.currentTarget ).addClass( "ui-state-focus" ); }, focusout: function( event ) { $( event.currentTarget ).removeClass( "ui-state-focus" ); } }); }, _trigger: function( type, event, data ) { var prop, orig, callback = this.options[ type ]; data = data || {}; event = $.Event( event ); event.type = ( type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type ).toLowerCase(); // the original event may come from any element // so we need to reset the target on the new event event.target = this.element[ 0 ]; // copy original event properties over to the new event orig = event.originalEvent; if ( orig ) { for ( prop in orig ) { if ( !( prop in event ) ) { event[ prop ] = orig[ prop ]; } } } this.element.trigger( event, data ); return !( $.isFunction( callback ) && callback.apply( this.element[0], [ event ].concat( data ) ) === false || event.isDefaultPrevented() ); } }; $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { if ( typeof options === "string" ) { options = { effect: options }; } var hasOptions, effectName = !options ? method : options === true || typeof options === "number" ? defaultEffect : options.effect || defaultEffect; options = options || {}; if ( typeof options === "number" ) { options = { duration: options }; } hasOptions = !$.isEmptyObject( options ); options.complete = callback; if ( options.delay ) { element.delay( options.delay ); } if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { element[ method ]( options ); } else if ( effectName !== method && element[ effectName ] ) { element[ effectName ]( options.duration, options.easing, callback ); } else { element.queue(function( next ) { $( this )[ method ](); if ( callback ) { callback.call( element[ 0 ] ); } next(); }); } }; }); // DEPRECATED if ( $.uiBackCompat !== false ) { $.Widget.prototype._getCreateOptions = function() { return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; }; } })); /* * jQuery Iframe Transport Plugin 1.5 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT */ /*jslint unparam: true, nomen: true */ /*global define, window, document */ (function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // Register as an anonymous AMD module: define(['jquery'], factory); } else { // Browser globals: factory(window.jQuery); } }(function ($) { 'use strict'; // Helper variable to create unique names for the transport iframes: var counter = 0; // The iframe transport accepts three additional options: // options.fileInput: a jQuery collection of file input fields // options.paramName: the parameter name for the file form data, // overrides the name property of the file input field(s), // can be a string or an array of strings. // options.formData: an array of objects with name and value properties, // equivalent to the return data of .serializeArray(), e.g.: // [{name: 'a', value: 1}, {name: 'b', value: 2}] $.ajaxTransport('iframe', function (options) { if (options.async && (options.type === 'POST' || options.type === 'GET')) { var form, iframe; return { send: function (_, completeCallback) { form = $('
    '); form.attr('accept-charset', options.formAcceptCharset); // javascript:false as initial iframe src // prevents warning popups on HTTPS in IE6. // IE versions below IE8 cannot set the name property of // elements that have already been added to the DOM, // so we set the name along with the iframe HTML markup: iframe = $( '' ).bind('load', function () { var fileInputClones, paramNames = $.isArray(options.paramName) ? options.paramName : [options.paramName]; iframe .unbind('load') .bind('load', function () { var response; // Wrap in a try/catch block to catch exceptions thrown // when trying to access cross-domain iframe contents: try { response = iframe.contents(); // Google Chrome and Firefox do not throw an // exception when calling iframe.contents() on // cross-domain requests, so we unify the response: if (!response.length || !response[0].firstChild) { throw new Error(); } } catch (e) { response = undefined; } // The complete callback returns the // iframe content document as response object: completeCallback( 200, 'success', {'iframe': response} ); // Fix for IE endless progress bar activity bug // (happens on form submits to iframe targets): $('') .appendTo(form); form.remove(); }); form .prop('target', iframe.prop('name')) .prop('action', options.url) .prop('method', options.type); if (options.formData) { $.each(options.formData, function (index, field) { $('') .prop('name', field.name) .val(field.value) .appendTo(form); }); } if (options.fileInput && options.fileInput.length && options.type === 'POST') { fileInputClones = options.fileInput.clone(); // Insert a clone for each file input field: options.fileInput.after(function (index) { return fileInputClones[index]; }); if (options.paramName) { options.fileInput.each(function (index) { $(this).prop( 'name', paramNames[index] || options.paramName ); }); } // Appending the file input fields to the hidden form // removes them from their original location: form .append(options.fileInput) .prop('enctype', 'multipart/form-data') // enctype must be set as encoding for IE: .prop('encoding', 'multipart/form-data'); } form.submit(); // Insert the file input fields at their original location // by replacing the clones with the originals: if (fileInputClones && fileInputClones.length) { options.fileInput.each(function (index, input) { var clone = $(fileInputClones[index]); $(input).prop('name', clone.prop('name')); clone.replaceWith(input); }); } }); form.append(iframe).appendTo(document.body); }, abort: function () { if (iframe) { // javascript:false as iframe src aborts the request // and prevents warning popups on HTTPS in IE6. // concat is used to avoid the "Script URL" JSLint error: iframe .unbind('load') .prop('src', 'javascript'.concat(':false;')); } if (form) { form.remove(); } } }; } }); // The iframe transport returns the iframe content document as response. // The following adds converters from iframe to text, json, html, and script: $.ajaxSetup({ converters: { 'iframe text': function (iframe) { return $(iframe[0].body).text(); }, 'iframe json': function (iframe) { return $.parseJSON($(iframe[0].body).text()); }, 'iframe html': function (iframe) { return $(iframe[0].body).html(); }, 'iframe script': function (iframe) { return $.globalEval($(iframe[0].body).text()); } } }); })); /* * jQuery File Upload Plugin 5.19.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT */ /*jslint nomen: true, unparam: true, regexp: true */ /*global define, window, document, Blob, FormData, location */ (function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // Register as an anonymous AMD module: define([ 'jquery', 'jquery.ui.widget' ], factory); } else { // Browser globals: factory(window.jQuery); } }(function ($) { 'use strict'; // The FileReader API is not actually used, but works as feature detection, // as e.g. Safari supports XHR file uploads via the FormData API, // but not non-multipart XHR file uploads: $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); $.support.xhrFormDataFileUpload = !!window.FormData; // The fileupload widget listens for change events on file input fields defined // via fileInput setting and paste or drop events of the given dropZone. // In addition to the default jQuery Widget methods, the fileupload widget // exposes the "add" and "send" methods, to add or directly send files using // the fileupload API. // By default, files added via file input selection, paste, drag & drop or // "add" method are uploaded immediately, but it is possible to override // the "add" callback option to queue file uploads. $.widget('blueimp.fileupload', { options: { // The drop target element(s), by the default the complete document. // Set to null to disable drag & drop support: dropZone: $(document), // The paste target element(s), by the default the complete document. // Set to null to disable paste support: pasteZone: $(document), // The file input field(s), that are listened to for change events. // If undefined, it is set to the file input fields inside // of the widget element on plugin initialization. // Set to null to disable the change listener. fileInput: undefined, // By default, the file input field is replaced with a clone after // each input field change event. This is required for iframe transport // queues and allows change events to be fired for the same file // selection, but can be disabled by setting the following option to false: replaceFileInput: true, // The parameter name for the file form data (the request argument name). // If undefined or empty, the name property of the file input field is // used, or "files[]" if the file input name property is also empty, // can be a string or an array of strings: paramName: undefined, // By default, each file of a selection is uploaded using an individual // request for XHR type uploads. Set to false to upload file // selections in one request each: singleFileUploads: true, // To limit the number of files uploaded with one XHR request, // set the following option to an integer greater than 0: limitMultiFileUploads: undefined, // Set the following option to true to issue all file upload requests // in a sequential order: sequentialUploads: false, // To limit the number of concurrent uploads, // set the following option to an integer greater than 0: limitConcurrentUploads: undefined, // Set the following option to true to force iframe transport uploads: forceIframeTransport: false, // Set the following option to the location of a redirect url on the // origin server, for cross-domain iframe transport uploads: redirect: undefined, // The parameter name for the redirect url, sent as part of the form // data and set to 'redirect' if this option is empty: redirectParamName: undefined, // Set the following option to the location of a postMessage window, // to enable postMessage transport uploads: postMessage: undefined, // By default, XHR file uploads are sent as multipart/form-data. // The iframe transport is always using multipart/form-data. // Set to false to enable non-multipart XHR uploads: multipart: true, // To upload large files in smaller chunks, set the following option // to a preferred maximum chunk size. If set to 0, null or undefined, // or the browser does not support the required Blob API, files will // be uploaded as a whole. maxChunkSize: undefined, // When a non-multipart upload or a chunked multipart upload has been // aborted, this option can be used to resume the upload by setting // it to the size of the already uploaded bytes. This option is most // useful when modifying the options object inside of the "add" or // "send" callbacks, as the options are cloned for each file upload. uploadedBytes: undefined, // By default, failed (abort or error) file uploads are removed from the // global progress calculation. Set the following option to false to // prevent recalculating the global progress data: recalculateProgress: true, // Interval in milliseconds to calculate and trigger progress events: progressInterval: 100, // Interval in milliseconds to calculate progress bitrate: bitrateInterval: 500, // Additional form data to be sent along with the file uploads can be set // using this option, which accepts an array of objects with name and // value properties, a function returning such an array, a FormData // object (for XHR file uploads), or a simple object. // The form of the first fileInput is given as parameter to the function: formData: function (form) { return form.serializeArray(); }, // The add callback is invoked as soon as files are added to the fileupload // widget (via file input selection, drag & drop, paste or add API call). // If the singleFileUploads option is enabled, this callback will be // called once for each file in the selection for XHR file uplaods, else // once for each file selection. // The upload starts when the submit method is invoked on the data parameter. // The data object contains a files property holding the added files // and allows to override plugin options as well as define ajax settings. // Listeners for this callback can also be bound the following way: // .bind('fileuploadadd', func); // data.submit() returns a Promise object and allows to attach additional // handlers using jQuery's Deferred callbacks: // data.submit().done(func).fail(func).always(func); add: function (e, data) { data.submit(); }, // Other callbacks: // Callback for the submit event of each file upload: // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); // Callback for the start of each file upload request: // send: function (e, data) {}, // .bind('fileuploadsend', func); // Callback for successful uploads: // done: function (e, data) {}, // .bind('fileuploaddone', func); // Callback for failed (abort or error) uploads: // fail: function (e, data) {}, // .bind('fileuploadfail', func); // Callback for completed (success, abort or error) requests: // always: function (e, data) {}, // .bind('fileuploadalways', func); // Callback for upload progress events: // progress: function (e, data) {}, // .bind('fileuploadprogress', func); // Callback for global upload progress events: // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); // Callback for uploads start, equivalent to the global ajaxStart event: // start: function (e) {}, // .bind('fileuploadstart', func); // Callback for uploads stop, equivalent to the global ajaxStop event: // stop: function (e) {}, // .bind('fileuploadstop', func); // Callback for change events of the fileInput(s): // change: function (e, data) {}, // .bind('fileuploadchange', func); // Callback for paste events to the pasteZone(s): // paste: function (e, data) {}, // .bind('fileuploadpaste', func); // Callback for drop events of the dropZone(s): // drop: function (e, data) {}, // .bind('fileuploaddrop', func); // Callback for dragover events of the dropZone(s): // dragover: function (e) {}, // .bind('fileuploaddragover', func); // The plugin options are used as settings object for the ajax calls. // The following are jQuery ajax settings required for the file uploads: processData: false, contentType: false, cache: false }, // A list of options that require a refresh after assigning a new value: _refreshOptionsList: [ 'fileInput', 'dropZone', 'pasteZone', 'multipart', 'forceIframeTransport' ], _BitrateTimer: function () { this.timestamp = +(new Date()); this.loaded = 0; this.bitrate = 0; this.getBitrate = function (now, loaded, interval) { var timeDiff = now - this.timestamp; if (!this.bitrate || !interval || timeDiff > interval) { this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; this.loaded = loaded; this.timestamp = now; } return this.bitrate; }; }, _isXHRUpload: function (options) { return !options.forceIframeTransport && ((!options.multipart && $.support.xhrFileUpload) || $.support.xhrFormDataFileUpload); }, _getFormData: function (options) { var formData; if (typeof options.formData === 'function') { return options.formData(options.form); } if ($.isArray(options.formData)) { return options.formData; } if (options.formData) { formData = []; $.each(options.formData, function (name, value) { formData.push({name: name, value: value}); }); return formData; } return []; }, _getTotal: function (files) { var total = 0; $.each(files, function (index, file) { total += file.size || 1; }); return total; }, _onProgress: function (e, data) { if (e.lengthComputable) { var now = +(new Date()), total, loaded; if (data._time && data.progressInterval && (now - data._time < data.progressInterval) && e.loaded !== e.total) { return; } data._time = now; total = data.total || this._getTotal(data.files); loaded = parseInt( e.loaded / e.total * (data.chunkSize || total), 10 ) + (data.uploadedBytes || 0); this._loaded += loaded - (data.loaded || data.uploadedBytes || 0); data.lengthComputable = true; data.loaded = loaded; data.total = total; data.bitrate = data._bitrateTimer.getBitrate( now, loaded, data.bitrateInterval ); // Trigger a custom progress event with a total data property set // to the file size(s) of the current upload and a loaded data // property calculated accordingly: this._trigger('progress', e, data); // Trigger a global progress event for all current file uploads, // including ajax calls queued for sequential file uploads: this._trigger('progressall', e, { lengthComputable: true, loaded: this._loaded, total: this._total, bitrate: this._bitrateTimer.getBitrate( now, this._loaded, data.bitrateInterval ) }); } }, _initProgressListener: function (options) { var that = this, xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); // Accesss to the native XHR object is required to add event listeners // for the upload progress event: if (xhr.upload) { $(xhr.upload).bind('progress', function (e) { var oe = e.originalEvent; // Make sure the progress event properties get copied over: e.lengthComputable = oe.lengthComputable; e.loaded = oe.loaded; e.total = oe.total; that._onProgress(e, options); }); options.xhr = function () { return xhr; }; } }, _initXHRData: function (options) { var formData, file = options.files[0], // Ignore non-multipart setting if not supported: multipart = options.multipart || !$.support.xhrFileUpload, paramName = options.paramName[0]; options.headers = options.headers || {}; if (options.contentRange) { options.headers['Content-Range'] = options.contentRange; } if (!multipart) { options.headers['Content-Disposition'] = 'attachment; filename="' + encodeURI(file.name) + '"'; options.contentType = file.type; options.data = options.blob || file; } else if ($.support.xhrFormDataFileUpload) { if (options.postMessage) { // window.postMessage does not allow sending FormData // objects, so we just add the File/Blob objects to // the formData array and let the postMessage window // create the FormData object out of this array: formData = this._getFormData(options); if (options.blob) { formData.push({ name: paramName, value: options.blob }); } else { $.each(options.files, function (index, file) { formData.push({ name: options.paramName[index] || paramName, value: file }); }); } } else { if (options.formData instanceof FormData) { formData = options.formData; } else { formData = new FormData(); $.each(this._getFormData(options), function (index, field) { formData.append(field.name, field.value); }); } if (options.blob) { options.headers['Content-Disposition'] = 'attachment; filename="' + encodeURI(file.name) + '"'; options.headers['Content-Description'] = encodeURI(file.type); formData.append(paramName, options.blob, file.name); } else { $.each(options.files, function (index, file) { // File objects are also Blob instances. // This check allows the tests to run with // dummy objects: if (file instanceof Blob) { formData.append( options.paramName[index] || paramName, file, file.name ); } }); } } options.data = formData; } // Blob reference is not needed anymore, free memory: options.blob = null; }, _initIframeSettings: function (options) { // Setting the dataType to iframe enables the iframe transport: options.dataType = 'iframe ' + (options.dataType || ''); // The iframe transport accepts a serialized array as form data: options.formData = this._getFormData(options); // Add redirect url to form data on cross-domain uploads: if (options.redirect && $('').prop('href', options.url) .prop('host') !== location.host) { options.formData.push({ name: options.redirectParamName || 'redirect', value: options.redirect }); } }, _initDataSettings: function (options) { if (this._isXHRUpload(options)) { if (!this._chunkedUpload(options, true)) { if (!options.data) { this._initXHRData(options); } this._initProgressListener(options); } if (options.postMessage) { // Setting the dataType to postmessage enables the // postMessage transport: options.dataType = 'postmessage ' + (options.dataType || ''); } } else { this._initIframeSettings(options, 'iframe'); } }, _getParamName: function (options) { var fileInput = $(options.fileInput), paramName = options.paramName; if (!paramName) { paramName = []; fileInput.each(function () { var input = $(this), name = input.prop('name') || 'files[]', i = (input.prop('files') || [1]).length; while (i) { paramName.push(name); i -= 1; } }); if (!paramName.length) { paramName = [fileInput.prop('name') || 'files[]']; } } else if (!$.isArray(paramName)) { paramName = [paramName]; } return paramName; }, _initFormSettings: function (options) { // Retrieve missing options from the input field and the // associated form, if available: if (!options.form || !options.form.length) { options.form = $(options.fileInput.prop('form')); // If the given file input doesn't have an associated form, // use the default widget file input's form: if (!options.form.length) { options.form = $(this.options.fileInput.prop('form')); } } options.paramName = this._getParamName(options); if (!options.url) { options.url = options.form.prop('action') || location.href; } // The HTTP request method must be "POST" or "PUT": options.type = (options.type || options.form.prop('method') || '') .toUpperCase(); if (options.type !== 'POST' && options.type !== 'PUT') { options.type = 'POST'; } if (!options.formAcceptCharset) { options.formAcceptCharset = options.form.attr('accept-charset'); } }, _getAJAXSettings: function (data) { var options = $.extend({}, this.options, data); this._initFormSettings(options); this._initDataSettings(options); return options; }, // Maps jqXHR callbacks to the equivalent // methods of the given Promise object: _enhancePromise: function (promise) { promise.success = promise.done; promise.error = promise.fail; promise.complete = promise.always; return promise; }, // Creates and returns a Promise object enhanced with // the jqXHR methods abort, success, error and complete: _getXHRPromise: function (resolveOrReject, context, args) { var dfd = $.Deferred(), promise = dfd.promise(); context = context || this.options.context || promise; if (resolveOrReject === true) { dfd.resolveWith(context, args); } else if (resolveOrReject === false) { dfd.rejectWith(context, args); } promise.abort = dfd.promise; return this._enhancePromise(promise); }, // Parses the Range header from the server response // and returns the uploaded bytes: _getUploadedBytes: function (jqXHR) { var range = jqXHR.getResponseHeader('Range'), parts = range && range.split('-'), upperBytesPos = parts && parts.length > 1 && parseInt(parts[1], 10); return upperBytesPos && upperBytesPos + 1; }, // Uploads a file in multiple, sequential requests // by splitting the file up in multiple blob chunks. // If the second parameter is true, only tests if the file // should be uploaded in chunks, but does not invoke any // upload requests: _chunkedUpload: function (options, testOnly) { var that = this, file = options.files[0], fs = file.size, ub = options.uploadedBytes = options.uploadedBytes || 0, mcs = options.maxChunkSize || fs, slice = file.slice || file.webkitSlice || file.mozSlice, dfd = $.Deferred(), promise = dfd.promise(), jqXHR, upload; if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || options.data) { return false; } if (testOnly) { return true; } if (ub >= fs) { file.error = 'Uploaded bytes exceed file size'; return this._getXHRPromise( false, options.context, [null, 'error', file.error] ); } // The chunk upload method: upload = function (i) { // Clone the options object for each chunk upload: var o = $.extend({}, options); o.blob = slice.call( file, ub, ub + mcs ); // Store the current chunk size, as the blob itself // will be dereferenced after data processing: o.chunkSize = o.blob.size; // Expose the chunk bytes position range: o.contentRange = 'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs; // Process the upload data (the blob and potential form data): that._initXHRData(o); // Add progress listeners for this chunk upload: that._initProgressListener(o); jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context)) .done(function (result, textStatus, jqXHR) { ub = that._getUploadedBytes(jqXHR) || (ub + o.chunkSize); // Create a progress event if upload is done and // no progress event has been invoked for this chunk: if (!o.loaded) { that._onProgress($.Event('progress', { lengthComputable: true, loaded: ub - o.uploadedBytes, total: ub - o.uploadedBytes }), o); } options.uploadedBytes = o.uploadedBytes = ub; if (ub < fs) { // File upload not yet complete, // continue with the next chunk: upload(); } else { dfd.resolveWith( o.context, [result, textStatus, jqXHR] ); } }) .fail(function (jqXHR, textStatus, errorThrown) { dfd.rejectWith( o.context, [jqXHR, textStatus, errorThrown] ); }); }; this._enhancePromise(promise); promise.abort = function () { return jqXHR.abort(); }; upload(); return promise; }, _beforeSend: function (e, data) { if (this._active === 0) { // the start callback is triggered when an upload starts // and no other uploads are currently running, // equivalent to the global ajaxStart event: this._trigger('start'); // Set timer for global bitrate progress calculation: this._bitrateTimer = new this._BitrateTimer(); } this._active += 1; // Initialize the global progress values: this._loaded += data.uploadedBytes || 0; this._total += this._getTotal(data.files); }, _onDone: function (result, textStatus, jqXHR, options) { if (!this._isXHRUpload(options)) { // Create a progress event for each iframe load: this._onProgress($.Event('progress', { lengthComputable: true, loaded: 1, total: 1 }), options); } options.result = result; options.textStatus = textStatus; options.jqXHR = jqXHR; this._trigger('done', null, options); }, _onFail: function (jqXHR, textStatus, errorThrown, options) { options.jqXHR = jqXHR; options.textStatus = textStatus; options.errorThrown = errorThrown; this._trigger('fail', null, options); if (options.recalculateProgress) { // Remove the failed (error or abort) file upload from // the global progress calculation: this._loaded -= options.loaded || options.uploadedBytes || 0; this._total -= options.total || this._getTotal(options.files); } }, _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { this._active -= 1; options.textStatus = textStatus; if (jqXHRorError && jqXHRorError.always) { options.jqXHR = jqXHRorError; options.result = jqXHRorResult; } else { options.jqXHR = jqXHRorResult; options.errorThrown = jqXHRorError; } this._trigger('always', null, options); if (this._active === 0) { // The stop callback is triggered when all uploads have // been completed, equivalent to the global ajaxStop event: this._trigger('stop'); // Reset the global progress values: this._loaded = this._total = 0; this._bitrateTimer = null; } }, _onSend: function (e, data) { var that = this, jqXHR, slot, pipe, options = that._getAJAXSettings(data), send = function (resolve, args) { that._sending += 1; // Set timer for bitrate progress calculation: options._bitrateTimer = new that._BitrateTimer(); jqXHR = jqXHR || ( (resolve !== false && that._trigger('send', e, options) !== false && (that._chunkedUpload(options) || $.ajax(options))) || that._getXHRPromise(false, options.context, args) ).done(function (result, textStatus, jqXHR) { that._onDone(result, textStatus, jqXHR, options); }).fail(function (jqXHR, textStatus, errorThrown) { that._onFail(jqXHR, textStatus, errorThrown, options); }).always(function (jqXHRorResult, textStatus, jqXHRorError) { that._sending -= 1; that._onAlways( jqXHRorResult, textStatus, jqXHRorError, options ); if (options.limitConcurrentUploads && options.limitConcurrentUploads > that._sending) { // Start the next queued upload, // that has not been aborted: var nextSlot = that._slots.shift(), isPending; while (nextSlot) { // jQuery 1.6 doesn't provide .state(), // while jQuery 1.8+ removed .isRejected(): isPending = nextSlot.state ? nextSlot.state() === 'pending' : !nextSlot.isRejected(); if (isPending) { nextSlot.resolve(); break; } nextSlot = that._slots.shift(); } } }); return jqXHR; }; this._beforeSend(e, options); if (this.options.sequentialUploads || (this.options.limitConcurrentUploads && this.options.limitConcurrentUploads <= this._sending)) { if (this.options.limitConcurrentUploads > 1) { slot = $.Deferred(); this._slots.push(slot); pipe = slot.pipe(send); } else { pipe = (this._sequence = this._sequence.pipe(send, send)); } // Return the piped Promise object, enhanced with an abort method, // which is delegated to the jqXHR object of the current upload, // and jqXHR callbacks mapped to the equivalent Promise methods: pipe.abort = function () { var args = [undefined, 'abort', 'abort']; if (!jqXHR) { if (slot) { slot.rejectWith(pipe, args); } return send(false, args); } return jqXHR.abort(); }; return this._enhancePromise(pipe); } return send(); }, _onAdd: function (e, data) { var that = this, result = true, options = $.extend({}, this.options, data), limit = options.limitMultiFileUploads, paramName = this._getParamName(options), paramNameSet, paramNameSlice, fileSet, i; if (!(options.singleFileUploads || limit) || !this._isXHRUpload(options)) { fileSet = [data.files]; paramNameSet = [paramName]; } else if (!options.singleFileUploads && limit) { fileSet = []; paramNameSet = []; for (i = 0; i < data.files.length; i += limit) { fileSet.push(data.files.slice(i, i + limit)); paramNameSlice = paramName.slice(i, i + limit); if (!paramNameSlice.length) { paramNameSlice = paramName; } paramNameSet.push(paramNameSlice); } } else { paramNameSet = paramName; } data.originalFiles = data.files; $.each(fileSet || data.files, function (index, element) { var newData = $.extend({}, data); newData.files = fileSet ? element : [element]; newData.paramName = paramNameSet[index]; newData.submit = function () { newData.jqXHR = this.jqXHR = (that._trigger('submit', e, this) !== false) && that._onSend(e, this); return this.jqXHR; }; return (result = that._trigger('add', e, newData)); }); return result; }, _replaceFileInput: function (input) { var inputClone = input.clone(true); $('
    ').append(inputClone)[0].reset(); // Detaching allows to insert the fileInput on another form // without loosing the file input value: input.after(inputClone).detach(); // Avoid memory leaks with the detached file input: $.cleanData(input.unbind('remove')); // Replace the original file input element in the fileInput // elements set with the clone, which has been copied including // event handlers: this.options.fileInput = this.options.fileInput.map(function (i, el) { if (el === input[0]) { return inputClone[0]; } return el; }); // If the widget has been initialized on the file input itself, // override this.element with the file input clone: if (input[0] === this.element[0]) { this.element = inputClone; } }, _handleFileTreeEntry: function (entry, path) { var that = this, dfd = $.Deferred(), errorHandler = function (e) { if (e && !e.entry) { e.entry = entry; } // Since $.when returns immediately if one // Deferred is rejected, we use resolve instead. // This allows valid files and invalid items // to be returned together in one set: dfd.resolve([e]); }, dirReader; path = path || ''; if (entry.isFile) { if (entry._file) { // Workaround for Chrome bug #149735 entry._file.relativePath = path; dfd.resolve(entry._file); } else { entry.file(function (file) { file.relativePath = path; dfd.resolve(file); }, errorHandler); } } else if (entry.isDirectory) { dirReader = entry.createReader(); dirReader.readEntries(function (entries) { that._handleFileTreeEntries( entries, path + entry.name + '/' ).done(function (files) { dfd.resolve(files); }).fail(errorHandler); }, errorHandler); } else { // Return an empy list for file system items // other than files or directories: dfd.resolve([]); } return dfd.promise(); }, _handleFileTreeEntries: function (entries, path) { var that = this; return $.when.apply( $, $.map(entries, function (entry) { return that._handleFileTreeEntry(entry, path); }) ).pipe(function () { return Array.prototype.concat.apply( [], arguments ); }); }, _getDroppedFiles: function (dataTransfer) { dataTransfer = dataTransfer || {}; var items = dataTransfer.items; if (items && items.length && (items[0].webkitGetAsEntry || items[0].getAsEntry)) { return this._handleFileTreeEntries( $.map(items, function (item) { var entry; if (item.webkitGetAsEntry) { entry = item.webkitGetAsEntry(); if (entry) { // Workaround for Chrome bug #149735: entry._file = item.getAsFile(); } return entry; } return item.getAsEntry(); }) ); } return $.Deferred().resolve( $.makeArray(dataTransfer.files) ).promise(); }, _getSingleFileInputFiles: function (fileInput) { fileInput = $(fileInput); var entries = fileInput.prop('webkitEntries') || fileInput.prop('entries'), files, value; if (entries && entries.length) { return this._handleFileTreeEntries(entries); } files = $.makeArray(fileInput.prop('files')); if (!files.length) { value = fileInput.prop('value'); if (!value) { return $.Deferred().resolve([]).promise(); } // If the files property is not available, the browser does not // support the File API and we add a pseudo File object with // the input value as name with path information removed: files = [{name: value.replace(/^.*\\/, '')}]; } else if (files[0].name === undefined && files[0].fileName) { // File normalization for Safari 4 and Firefox 3: $.each(files, function (index, file) { file.name = file.fileName; file.size = file.fileSize; }); } return $.Deferred().resolve(files).promise(); }, _getFileInputFiles: function (fileInput) { if (!(fileInput instanceof $) || fileInput.length === 1) { return this._getSingleFileInputFiles(fileInput); } return $.when.apply( $, $.map(fileInput, this._getSingleFileInputFiles) ).pipe(function () { return Array.prototype.concat.apply( [], arguments ); }); }, _onChange: function (e) { var that = this, data = { fileInput: $(e.target), form: $(e.target.form) }; this._getFileInputFiles(data.fileInput).always(function (files) { data.files = files; if (that.options.replaceFileInput) { that._replaceFileInput(data.fileInput); } if (that._trigger('change', e, data) !== false) { that._onAdd(e, data); } }); }, _onPaste: function (e) { var cbd = e.originalEvent.clipboardData, items = (cbd && cbd.items) || [], data = {files: []}; $.each(items, function (index, item) { var file = item.getAsFile && item.getAsFile(); if (file) { data.files.push(file); } }); if (this._trigger('paste', e, data) === false || this._onAdd(e, data) === false) { return false; } }, _onDrop: function (e) { e.preventDefault(); var that = this, dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer, data = {}; this._getDroppedFiles(dataTransfer).always(function (files) { data.files = files; if (that._trigger('drop', e, data) !== false) { that._onAdd(e, data); } }); }, _onDragOver: function (e) { var dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer; if (this._trigger('dragover', e) === false) { return false; } if (dataTransfer) { dataTransfer.dropEffect = 'copy'; } e.preventDefault(); }, _initEventHandlers: function () { if (this._isXHRUpload(this.options)) { this._on(this.options.dropZone, { dragover: this._onDragOver, drop: this._onDrop }); this._on(this.options.pasteZone, { paste: this._onPaste }); } this._on(this.options.fileInput, { change: this._onChange }); }, _destroyEventHandlers: function () { this._off(this.options.dropZone, 'dragover drop'); this._off(this.options.pasteZone, 'paste'); this._off(this.options.fileInput, 'change'); }, _setOption: function (key, value) { var refresh = $.inArray(key, this._refreshOptionsList) !== -1; if (refresh) { this._destroyEventHandlers(); } this._super(key, value); if (refresh) { this._initSpecialOptions(); this._initEventHandlers(); } }, _initSpecialOptions: function () { var options = this.options; if (options.fileInput === undefined) { options.fileInput = this.element.is('input[type="file"]') ? this.element : this.element.find('input[type="file"]'); } else if (!(options.fileInput instanceof $)) { options.fileInput = $(options.fileInput); } if (!(options.dropZone instanceof $)) { options.dropZone = $(options.dropZone); } if (!(options.pasteZone instanceof $)) { options.pasteZone = $(options.pasteZone); } }, _create: function () { var options = this.options; // Initialize options set via HTML5 data-attributes: $.extend(options, $(this.element[0].cloneNode(false)).data()); this._initSpecialOptions(); this._slots = []; this._sequence = this._getXHRPromise(true); this._sending = this._active = this._loaded = this._total = 0; this._initEventHandlers(); }, _destroy: function () { this._destroyEventHandlers(); }, // This method is exposed to the widget API and allows adding files // using the fileupload API. The data parameter accepts an object which // must have a files property and can contain additional options: // .fileupload('add', {files: filesList}); add: function (data) { var that = this; if (!data || this.options.disabled) { return; } if (data.fileInput && !data.files) { this._getFileInputFiles(data.fileInput).always(function (files) { data.files = files; that._onAdd(null, data); }); } else { data.files = $.makeArray(data.files); this._onAdd(null, data); } }, // This method is exposed to the widget API and allows sending files // using the fileupload API. The data parameter accepts an object which // must have a files or fileInput property and can contain additional options: // .fileupload('send', {files: filesList}); // The method returns a Promise object for the file upload call. send: function (data) { if (data && !this.options.disabled) { if (data.fileInput && !data.files) { var that = this, dfd = $.Deferred(), promise = dfd.promise(), jqXHR, aborted; promise.abort = function () { aborted = true; if (jqXHR) { return jqXHR.abort(); } dfd.reject(null, 'abort', 'abort'); return promise; }; this._getFileInputFiles(data.fileInput).always( function (files) { if (aborted) { return; } data.files = files; jqXHR = that._onSend(null, data).then( function (result, textStatus, jqXHR) { dfd.resolve(result, textStatus, jqXHR); }, function (jqXHR, textStatus, errorThrown) { dfd.reject(jqXHR, textStatus, errorThrown); } ); } ); return this._enhancePromise(promise); } data.files = $.makeArray(data.files); if (data.files.length) { return this._onSend(null, data); } } return this._getXHRPromise(false, data && data.context); } }); })); /* * JavaScript Templates 2.1.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT * * Inspired by John Resig's JavaScript Micro-Templating: * http://ejohn.org/blog/javascript-micro-templating/ */ /*jslint evil: true, regexp: true */ /*global document, define */ (function ($) { "use strict"; var tmpl = function (str, data) { var f = !/[^\w\-\.:]/.test(str) ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str)) : new Function( tmpl.arg + ',tmpl', "var _e=tmpl.encode" + tmpl.helper + ",_s='" + str.replace(tmpl.regexp, tmpl.func) + "';return _s;" ); return data ? f(data, tmpl) : function (data) { return f(data, tmpl); }; }; tmpl.cache = {}; tmpl.load = function (id) { return document.getElementById(id).innerHTML; }; tmpl.regexp = /([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g; tmpl.func = function (s, p1, p2, p3, p4, p5) { if (p1) { // whitespace, quote and backspace in interpolation context return { "\n": "\\n", "\r": "\\r", "\t": "\\t", " " : " " }[s] || "\\" + s; } if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%} if (p2 === "=") { return "'+_e(" + p3 + ")+'"; } return "'+(" + p3 + "||'')+'"; } if (p4) { // evaluation start tag: {% return "';"; } if (p5) { // evaluation end tag: %} return "_s+='"; } }; tmpl.encReg = /[<>&"'\x00]/g; tmpl.encMap = { "<" : "<", ">" : ">", "&" : "&", "\"" : """, "'" : "'" }; tmpl.encode = function (s) { return String(s || "").replace( tmpl.encReg, function (c) { return tmpl.encMap[c] || ""; } ); }; tmpl.arg = "o"; tmpl.helper = ",print=function(s,e){_s+=e&&(s||'')||_e(s);}" + ",include=function(s,d){_s+=tmpl(s,d);}"; if (typeof define === "function" && define.amd) { define(function () { return tmpl; }); } else { $.tmpl = tmpl; } }(this)); /* ========================================================= * bootstrap-datepicker.js * http://www.eyecon.ro/bootstrap-datepicker * ========================================================= * Copyright 2012 Stefan Petre * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ========================================================= */ !function( $ ) { // Picker object var Datepicker = function(element, options){ this.element = $(element); this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy'); this.picker = $(DPGlobal.template) .appendTo('body') .on({ click: $.proxy(this.click, this), mousedown: $.proxy(this.mousedown, this) }); this.isInput = this.element.is('input'); this.component = this.element.is('.date') ? this.element.find('.add-on') : false; if (this.isInput) { this.element.on({ focus: $.proxy(this.show, this), blur: $.proxy(this.hide, this), keyup: $.proxy(this.update, this) }); } else { if (this.component){ this.component.on('click', $.proxy(this.show, this)); } else { this.element.on('click', $.proxy(this.show, this)); } } this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0; if (typeof this.minViewMode === 'string') { switch (this.minViewMode) { case 'months': this.minViewMode = 1; break; case 'years': this.minViewMode = 2; break; default: this.minViewMode = 0; break; } } this.viewMode = options.viewMode||this.element.data('date-viewmode')||0; if (typeof this.viewMode === 'string') { switch (this.viewMode) { case 'months': this.viewMode = 1; break; case 'years': this.viewMode = 2; break; default: this.viewMode = 0; break; } } this.startViewMode = this.viewMode; this.weekStart = options.weekStart||this.element.data('date-weekstart')||0; this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1; this.fillDow(); this.fillMonths(); this.update(); this.showMode(); }; Datepicker.prototype = { constructor: Datepicker, show: function(e) { this.picker.show(); this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); this.place(); $(window).on('resize', $.proxy(this.place, this)); if (e ) { e.stopPropagation(); e.preventDefault(); } if (!this.isInput) { $(document).on('mousedown', $.proxy(this.hide, this)); } this.element.trigger({ type: 'show', date: this.date }); }, hide: function(){ this.picker.hide(); $(window).off('resize', this.place); this.viewMode = this.startViewMode; this.showMode(); if (!this.isInput) { $(document).off('mousedown', this.hide); } this.set(); this.element.trigger({ type: 'hide', date: this.date }); }, set: function() { var formated = DPGlobal.formatDate(this.date, this.format); if (!this.isInput) { if (this.component){ this.element.find('input').prop('value', formated); } this.element.data('date', formated); } else { this.element.prop('value', formated); } }, setValue: function(newDate) { if (typeof newDate === 'string') { this.date = DPGlobal.parseDate(newDate, this.format); } else { this.date = new Date(newDate); } this.set(); this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0); this.fill(); }, place: function(){ var offset = this.component ? this.component.offset() : this.element.offset(); this.picker.css({ top: offset.top + this.height, left: offset.left }); }, update: function(newDate){ this.date = DPGlobal.parseDate( typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')), this.format ); this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0); this.fill(); }, fillDow: function(){ var dowCnt = this.weekStart; var html = '
'; while (dowCnt < this.weekStart + 7) { html += ''; } html += ''; this.picker.find('.datepicker-days thead').append(html); }, fillMonths: function(){ var html = ''; var i = 0 while (i < 12) { html += ''+DPGlobal.dates.monthsShort[i++]+''; } this.picker.find('.datepicker-months td').append(html); }, fill: function() { var d = new Date(this.viewDate), year = d.getFullYear(), month = d.getMonth(), currentDate = this.date.valueOf(); this.picker.find('.datepicker-days th:eq(1)') .text(DPGlobal.dates.months[month]+' '+year); var prevMonth = new Date(year, month-1, 28,0,0,0,0), day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth()); prevMonth.setDate(day); prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7); var nextMonth = new Date(prevMonth); nextMonth.setDate(nextMonth.getDate() + 42); nextMonth = nextMonth.valueOf(); html = []; var clsName; while(prevMonth.valueOf() < nextMonth) { if (prevMonth.getDay() === this.weekStart) { html.push(''); } clsName = ''; if (prevMonth.getMonth() < month) { clsName += ' old'; } else if (prevMonth.getMonth() > month) { clsName += ' new'; } if (prevMonth.valueOf() === currentDate) { clsName += ' active'; } html.push(''); if (prevMonth.getDay() === this.weekEnd) { html.push(''); } prevMonth.setDate(prevMonth.getDate()+1); } this.picker.find('.datepicker-days tbody').empty().append(html.join('')); var currentYear = this.date.getFullYear(); var months = this.picker.find('.datepicker-months') .find('th:eq(1)') .text(year) .end() .find('span').removeClass('active'); if (currentYear === year) { months.eq(this.date.getMonth()).addClass('active'); } html = ''; year = parseInt(year/10, 10) * 10; var yearCont = this.picker.find('.datepicker-years') .find('th:eq(1)') .text(year + '-' + (year + 9)) .end() .find('td'); year -= 1; for (var i = -1; i < 11; i++) { html += ''+year+''; year += 1; } yearCont.html(html); }, click: function(e) { e.stopPropagation(); e.preventDefault(); var target = $(e.target).closest('span, td, th'); if (target.length === 1) { switch(target[0].nodeName.toLowerCase()) { case 'th': switch(target[0].className) { case 'switch': this.showMode(1); break; case 'prev': case 'next': this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call( this.viewDate, this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) + DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1) ); this.fill(); this.set(); break; } break; case 'span': if (target.is('.month')) { var month = target.parent().find('span').index(target); this.viewDate.setMonth(month); } else { var year = parseInt(target.text(), 10)||0; this.viewDate.setFullYear(year); } if (this.viewMode !== 0) { this.date = new Date(this.viewDate); this.element.trigger({ type: 'changeDate', date: this.date, viewMode: DPGlobal.modes[this.viewMode].clsName }); } this.showMode(-1); this.fill(); this.set(); break; case 'td': if (target.is('.day')){ var day = parseInt(target.text(), 10)||1; var month = this.viewDate.getMonth(); if (target.is('.old')) { month -= 1; } else if (target.is('.new')) { month += 1; } var year = this.viewDate.getFullYear(); this.date = new Date(year, month, day,0,0,0,0); this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0); this.fill(); this.set(); this.element.trigger({ type: 'changeDate', date: this.date, viewMode: DPGlobal.modes[this.viewMode].clsName }); } break; } } }, mousedown: function(e){ e.stopPropagation(); e.preventDefault(); }, showMode: function(dir) { if (dir) { this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir)); } this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show(); } }; $.fn.datepicker = function ( option, val ) { return this.each(function () { var $this = $(this), data = $this.data('datepicker'), options = typeof option === 'object' && option; if (!data) { $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options)))); } if (typeof option === 'string') data[option](val); }); }; $.fn.datepicker.defaults = { }; $.fn.datepicker.Constructor = Datepicker; var DPGlobal = { modes: [ { clsName: 'days', navFnc: 'Month', navStep: 1 }, { clsName: 'months', navFnc: 'FullYear', navStep: 1 }, { clsName: 'years', navFnc: 'FullYear', navStep: 10 }], dates:{ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }, isLeapYear: function (year) { return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) }, getDaysInMonth: function (year, month) { return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] }, parseFormat: function(format){ var separator = format.match(/[.\/\-\s].*?/), parts = format.split(/\W+/); if (!separator || !parts || parts.length === 0){ throw new Error("Invalid date format."); } return {separator: separator, parts: parts}; }, parseDate: function(date, format) { var parts = date.split(format.separator), date = new Date(), val; date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); if (parts.length === format.parts.length) { for (var i=0, cnt = format.parts.length; i < cnt; i++) { val = parseInt(parts[i], 10)||1; switch(format.parts[i]) { case 'dd': case 'd': date.setDate(val); break; case 'mm': case 'm': date.setMonth(val - 1); break; case 'yy': date.setFullYear(2000 + val); break; case 'yyyy': date.setFullYear(val); break; } } } return date; }, formatDate: function(date, format){ var val = { d: date.getDate(), m: date.getMonth() + 1, yy: date.getFullYear().toString().substring(2), yyyy: date.getFullYear() }; val.dd = (val.d < 10 ? '0' : '') + val.d; val.mm = (val.m < 10 ? '0' : '') + val.m; var date = []; for (var i=0, cnt = format.parts.length; i < cnt; i++) { date.push(val[format.parts[i]]); } return date.join(format.separator); }, headTemplate: ''+ ''+ ''+ ''+ ''+ ''+ '', contTemplate: '' }; DPGlobal.template = '
'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'
'+prevMonth.getDate() + '
'+ DPGlobal.headTemplate+ ''+ '
'+ ''+ '
'+ ''+ DPGlobal.headTemplate+ DPGlobal.contTemplate+ '
'+ '
'+ '
'+ ''+ DPGlobal.headTemplate+ DPGlobal.contTemplate+ '
'+ '
'+ ''; }( window.jQuery ) ; (function() { $(document).ready(function() { $(".sortable").nestedSortable({ listType: "ul", handle: ".sort_handle", items: "li", toleranceElement: "> div", forcePlaceholderSize: true, placeholder: 'placeholder', update: function(event, ui) { var finalstring, mylist; mylist = $(".sortable").sortable('serialize'); mylist = mylist.replace(/root/g, ""); finalstring = ""; $(mylist.split("&")).each(function(index) { var fragments, id, parent_id, string2, string3, type; string2 = this.split("["); type = string2[0]; string3 = string2[1].split("]"); id = string3[0]; fragments = this.split("="); parent_id = fragments[1]; return finalstring = finalstring + type + "[" + index + "]" + "[id]=" + id + "&" + type + "[" + index + "][parent_id]=" + parent_id + "&" + type + "[" + index + "][position]=" + index + "&"; }); return $.post($(this).data('update-url'), finalstring); } }); $(".one_level_sortable").nestedSortable({ listType: "ul", handle: ".sort_handle", items: "li", toleranceElement: "> div", disableNesting: true, update: function(event, ui) { var finalstring, mylist; mylist = $(".one_level_sortable").sortable('serialize'); mylist = mylist.replace(/root/g, ""); finalstring = ""; $(mylist.split("&")).each(function(index) { var fragments, id, parent_id, string2, string3, type; string2 = this.split("["); type = string2[0]; string3 = string2[1].split("]"); id = string3[0]; fragments = this.split("="); parent_id = fragments[1]; return finalstring = finalstring + type + "[" + index + "]" + "[id]=" + id + "&" + type + "[" + index + "][parent_id]=" + parent_id + "&" + type + "[" + index + "][position]=" + index + "&"; }); return $.post($(this).data('update-url'), finalstring); } }); $(document).on("click", ".add_content_link", function(event) { if ($('.add_content_link').hasClass('disabled')) { return false; } else { $('.add_content_link').addClass('disabled'); $('#add_new').append('

Add Section
'); $('.add_content_link').tab('show'); return false; } }); $(document).on("click", "#submit_content_part", function(event) { $.ajax({ url: '/admin/content_sections.js', type: 'POST', data: { resource: $('.add_content_tab').data('resource'), resource_id: $('.add_content_tab').data('id'), name: $('.add_content_part_input input').val() } }); $('.add_content_part_input').remove(); return $('.add_content_link').removeClass('disabled'); }); $("#draggable li").draggable({ revert: true, cursor: "move" }); return $("#droppable").droppable({ drop: function(event, ui) { return $.ajax({ url: '/admin/assets/add_image.js', type: 'POST', data: { resource: $(ui.draggable).data('resource'), resource_id: $(ui.draggable).data('resource-id'), asset_id: $(ui.draggable).data('asset-id') } }); } }); }); }).call(this); // This is a manifest file that'll be compiled into including all the files listed below. // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically // be included in the compiled file accessible from http://example.com/assets/application.js // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // the compiled file. // ; ;TI"required_assets_digest;F"%9022036bbf0cb950276a9790ae50c241I" _version;F"%6776f581a4329e299531e1d52aa59832