1875032c79d82e34fbbe79475cf44f72d78af889
[profile/ivi/cowhide.git] / dist / cowhide.js
1 /*!
2  * jQuery JavaScript Library v2.0.4-pre
3  * http://jquery.com/
4  *
5  * Includes Sizzle.js
6  * http://sizzlejs.com/
7  *
8  * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
9  * Released under the MIT license
10  * http://jquery.org/license
11  *
12  * Date: 2014-02-14T09:19Z
13  */
14
15 (function ( window, factory ) {
16
17         if ( typeof module === "object" && typeof module.exports === "object" ) {
18                 // Expose a jQuery-making factory as module.exports in loaders that implement the Node
19                 // module pattern (including browserify).
20                 // This accentuates the need for a real window in the environment
21                 // e.g. var jQuery = require("jquery")(window);
22                 module.exports = function( w ) {
23                         w = w || window;
24                         if ( !w.document ) {
25                                 throw new Error("jQuery requires a window with a document");
26                         }
27                         return factory( w );
28                 };
29         } else {
30                 // Execute the factory to produce jQuery
31                 var jQuery = factory( window );
32
33                 // Register as a named AMD module, since jQuery can be concatenated with other
34                 // files that may use define, but not via a proper concatenation script that
35                 // understands anonymous AMD modules. A named AMD is safest and most robust
36                 // way to register. Lowercase jquery is used because AMD module names are
37                 // derived from file names, and jQuery is normally delivered in a lowercase
38                 // file name. Do this after creating the global so that if an AMD module wants
39                 // to call noConflict to hide this version of jQuery, it will work.
40                 if ( typeof define === "function" && define.amd ) {
41                         define( "jquery", [], function() {
42                                 return jQuery;
43                         });
44                 }
45         }
46
47 // Pass this, window may not be defined yet
48 }(this, function ( window ) {
49
50 // Can't do this because several apps including ASP.NET trace
51 // the stack via arguments.caller.callee and Firefox dies if
52 // you try to trace through "use strict" call chains. (#13335)
53 // Support: Firefox 18+
54 //"use strict";
55 var
56         // A central reference to the root jQuery(document)
57         rootjQuery,
58
59         // The deferred used on DOM ready
60         readyList,
61
62         // Support: IE9
63         // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
64         core_strundefined = typeof undefined,
65
66         // Use the correct document accordingly with window argument (sandbox)
67         location = window.location,
68         document = window.document,
69         docElem = document.documentElement,
70
71         // Map over jQuery in case of overwrite
72         _jQuery = window.jQuery,
73
74         // Map over the $ in case of overwrite
75         _$ = window.$,
76
77         // [[Class]] -> type pairs
78         class2type = {},
79
80         // List of deleted data cache ids, so we can reuse them
81         core_deletedIds = [],
82
83         core_version = "2.0.4-pre",
84
85         // Save a reference to some core methods
86         core_concat = core_deletedIds.concat,
87         core_push = core_deletedIds.push,
88         core_slice = core_deletedIds.slice,
89         core_indexOf = core_deletedIds.indexOf,
90         core_toString = class2type.toString,
91         core_hasOwn = class2type.hasOwnProperty,
92         core_trim = core_version.trim,
93
94         // Define a local copy of jQuery
95         jQuery = function( selector, context ) {
96                 // The jQuery object is actually just the init constructor 'enhanced'
97                 return new jQuery.fn.init( selector, context, rootjQuery );
98         },
99
100         // Used for matching numbers
101         core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
102
103         // Used for splitting on whitespace
104         core_rnotwhite = /\S+/g,
105
106         // A simple way to check for HTML strings
107         // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
108         // Strict HTML recognition (#11290: must start with <)
109         rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
110
111         // Match a standalone tag
112         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
113
114         // Matches dashed string for camelizing
115         rmsPrefix = /^-ms-/,
116         rdashAlpha = /-([\da-z])/gi,
117
118         // Used by jQuery.camelCase as callback to replace()
119         fcamelCase = function( all, letter ) {
120                 return letter.toUpperCase();
121         },
122
123         // The ready event handler and self cleanup method
124         completed = function() {
125                 document.removeEventListener( "DOMContentLoaded", completed, false );
126                 window.removeEventListener( "load", completed, false );
127                 jQuery.ready();
128         };
129
130 jQuery.fn = jQuery.prototype = {
131         // The current version of jQuery being used
132         jquery: core_version,
133
134         constructor: jQuery,
135         init: function( selector, context, rootjQuery ) {
136                 var match, elem;
137
138                 // HANDLE: $(""), $(null), $(undefined), $(false)
139                 if ( !selector ) {
140                         return this;
141                 }
142
143                 // Handle HTML strings
144                 if ( typeof selector === "string" ) {
145                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
146                                 // Assume that strings that start and end with <> are HTML and skip the regex check
147                                 match = [ null, selector, null ];
148
149                         } else {
150                                 match = rquickExpr.exec( selector );
151                         }
152
153                         // Match html or make sure no context is specified for #id
154                         if ( match && (match[1] || !context) ) {
155
156                                 // HANDLE: $(html) -> $(array)
157                                 if ( match[1] ) {
158                                         context = context instanceof jQuery ? context[0] : context;
159
160                                         // scripts is true for back-compat
161                                         jQuery.merge( this, jQuery.parseHTML(
162                                                 match[1],
163                                                 context && context.nodeType ? context.ownerDocument || context : document,
164                                                 true
165                                         ) );
166
167                                         // HANDLE: $(html, props)
168                                         if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
169                                                 for ( match in context ) {
170                                                         // Properties of context are called as methods if possible
171                                                         if ( jQuery.isFunction( this[ match ] ) ) {
172                                                                 this[ match ]( context[ match ] );
173
174                                                         // ...and otherwise set as attributes
175                                                         } else {
176                                                                 this.attr( match, context[ match ] );
177                                                         }
178                                                 }
179                                         }
180
181                                         return this;
182
183                                 // HANDLE: $(#id)
184                                 } else {
185                                         elem = document.getElementById( match[2] );
186
187                                         // Check parentNode to catch when Blackberry 4.6 returns
188                                         // nodes that are no longer in the document #6963
189                                         if ( elem && elem.parentNode ) {
190                                                 // Inject the element directly into the jQuery object
191                                                 this.length = 1;
192                                                 this[0] = elem;
193                                         }
194
195                                         this.context = document;
196                                         this.selector = selector;
197                                         return this;
198                                 }
199
200                         // HANDLE: $(expr, $(...))
201                         } else if ( !context || context.jquery ) {
202                                 return ( context || rootjQuery ).find( selector );
203
204                         // HANDLE: $(expr, context)
205                         // (which is just equivalent to: $(context).find(expr)
206                         } else {
207                                 return this.constructor( context ).find( selector );
208                         }
209
210                 // HANDLE: $(DOMElement)
211                 } else if ( selector.nodeType ) {
212                         this.context = this[0] = selector;
213                         this.length = 1;
214                         return this;
215
216                 // HANDLE: $(function)
217                 // Shortcut for document ready
218                 } else if ( jQuery.isFunction( selector ) ) {
219                         return rootjQuery.ready( selector );
220                 }
221
222                 if ( selector.selector !== undefined ) {
223                         this.selector = selector.selector;
224                         this.context = selector.context;
225                 }
226
227                 return jQuery.makeArray( selector, this );
228         },
229
230         // Start with an empty selector
231         selector: "",
232
233         // The default length of a jQuery object is 0
234         length: 0,
235
236         toArray: function() {
237                 return core_slice.call( this );
238         },
239
240         // Get the Nth element in the matched element set OR
241         // Get the whole matched element set as a clean array
242         get: function( num ) {
243                 return num == null ?
244
245                         // Return a 'clean' array
246                         this.toArray() :
247
248                         // Return just the object
249                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
250         },
251
252         // Take an array of elements and push it onto the stack
253         // (returning the new matched element set)
254         pushStack: function( elems ) {
255
256                 // Build a new jQuery matched element set
257                 var ret = jQuery.merge( this.constructor(), elems );
258
259                 // Add the old object onto the stack (as a reference)
260                 ret.prevObject = this;
261                 ret.context = this.context;
262
263                 // Return the newly-formed element set
264                 return ret;
265         },
266
267         // Execute a callback for every element in the matched set.
268         // (You can seed the arguments with an array of args, but this is
269         // only used internally.)
270         each: function( callback, args ) {
271                 return jQuery.each( this, callback, args );
272         },
273
274         ready: function( fn ) {
275                 // Add the callback
276                 jQuery.ready.promise().done( fn );
277
278                 return this;
279         },
280
281         slice: function() {
282                 return this.pushStack( core_slice.apply( this, arguments ) );
283         },
284
285         first: function() {
286                 return this.eq( 0 );
287         },
288
289         last: function() {
290                 return this.eq( -1 );
291         },
292
293         eq: function( i ) {
294                 var len = this.length,
295                         j = +i + ( i < 0 ? len : 0 );
296                 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
297         },
298
299         map: function( callback ) {
300                 return this.pushStack( jQuery.map(this, function( elem, i ) {
301                         return callback.call( elem, i, elem );
302                 }));
303         },
304
305         end: function() {
306                 return this.prevObject || this.constructor(null);
307         },
308
309         // For internal use only.
310         // Behaves like an Array's method, not like a jQuery method.
311         push: core_push,
312         sort: [].sort,
313         splice: [].splice
314 };
315
316 // Give the init function the jQuery prototype for later instantiation
317 jQuery.fn.init.prototype = jQuery.fn;
318
319 jQuery.extend = jQuery.fn.extend = function() {
320         var options, name, src, copy, copyIsArray, clone,
321                 target = arguments[0] || {},
322                 i = 1,
323                 length = arguments.length,
324                 deep = false;
325
326         // Handle a deep copy situation
327         if ( typeof target === "boolean" ) {
328                 deep = target;
329                 target = arguments[1] || {};
330                 // skip the boolean and the target
331                 i = 2;
332         }
333
334         // Handle case when target is a string or something (possible in deep copy)
335         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
336                 target = {};
337         }
338
339         // extend jQuery itself if only one argument is passed
340         if ( length === i ) {
341                 target = this;
342                 --i;
343         }
344
345         for ( ; i < length; i++ ) {
346                 // Only deal with non-null/undefined values
347                 if ( (options = arguments[ i ]) != null ) {
348                         // Extend the base object
349                         for ( name in options ) {
350                                 src = target[ name ];
351                                 copy = options[ name ];
352
353                                 // Prevent never-ending loop
354                                 if ( target === copy ) {
355                                         continue;
356                                 }
357
358                                 // Recurse if we're merging plain objects or arrays
359                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
360                                         if ( copyIsArray ) {
361                                                 copyIsArray = false;
362                                                 clone = src && jQuery.isArray(src) ? src : [];
363
364                                         } else {
365                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
366                                         }
367
368                                         // Never move original objects, clone them
369                                         target[ name ] = jQuery.extend( deep, clone, copy );
370
371                                 // Don't bring in undefined values
372                                 } else if ( copy !== undefined ) {
373                                         target[ name ] = copy;
374                                 }
375                         }
376                 }
377         }
378
379         // Return the modified object
380         return target;
381 };
382
383 jQuery.extend({
384         // Unique for each copy of jQuery on the page
385         expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
386
387         noConflict: function( deep ) {
388                 if ( window.$ === jQuery ) {
389                         window.$ = _$;
390                 }
391
392                 if ( deep && window.jQuery === jQuery ) {
393                         window.jQuery = _jQuery;
394                 }
395
396                 return jQuery;
397         },
398
399         // Is the DOM ready to be used? Set to true once it occurs.
400         isReady: false,
401
402         // A counter to track how many items to wait for before
403         // the ready event fires. See #6781
404         readyWait: 1,
405
406         // Hold (or release) the ready event
407         holdReady: function( hold ) {
408                 if ( hold ) {
409                         jQuery.readyWait++;
410                 } else {
411                         jQuery.ready( true );
412                 }
413         },
414
415         // Handle when the DOM is ready
416         ready: function( wait ) {
417
418                 // Abort if there are pending holds or we're already ready
419                 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
420                         return;
421                 }
422
423                 // Remember that the DOM is ready
424                 jQuery.isReady = true;
425
426                 // If a normal DOM Ready event fired, decrement, and wait if need be
427                 if ( wait !== true && --jQuery.readyWait > 0 ) {
428                         return;
429                 }
430
431                 // If there are functions bound, to execute
432                 readyList.resolveWith( document, [ jQuery ] );
433
434                 // Trigger any bound ready events
435                 if ( jQuery.fn.trigger ) {
436                         jQuery( document ).trigger("ready").off("ready");
437                 }
438         },
439
440         // See test/unit/core.js for details concerning isFunction.
441         // Since version 1.3, DOM methods and functions like alert
442         // aren't supported. They return false on IE (#2968).
443         isFunction: function( obj ) {
444                 return jQuery.type(obj) === "function";
445         },
446
447         isArray: Array.isArray,
448
449         isWindow: function( obj ) {
450                 return obj != null && obj === obj.window;
451         },
452
453         isNumeric: function( obj ) {
454                 return !isNaN( parseFloat(obj) ) && isFinite( obj );
455         },
456
457         type: function( obj ) {
458                 if ( obj == null ) {
459                         return String( obj );
460                 }
461                 // Support: Safari <= 5.1 (functionish RegExp)
462                 return typeof obj === "object" || typeof obj === "function" ?
463                         class2type[ core_toString.call(obj) ] || "object" :
464                         typeof obj;
465         },
466
467         isPlainObject: function( obj ) {
468                 // Not plain objects:
469                 // - Any object or value whose internal [[Class]] property is not "[object Object]"
470                 // - DOM nodes
471                 // - window
472                 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
473                         return false;
474                 }
475
476                 // Support: Firefox <20
477                 // The try/catch suppresses exceptions thrown when attempting to access
478                 // the "constructor" property of certain host objects, ie. |window.location|
479                 // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
480                 try {
481                         if ( obj.constructor &&
482                                         !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
483                                 return false;
484                         }
485                 } catch ( e ) {
486                         return false;
487                 }
488
489                 // If the function hasn't returned already, we're confident that
490                 // |obj| is a plain object, created by {} or constructed with new Object
491                 return true;
492         },
493
494         isEmptyObject: function( obj ) {
495                 var name;
496                 for ( name in obj ) {
497                         return false;
498                 }
499                 return true;
500         },
501
502         error: function( msg ) {
503                 throw new Error( msg );
504         },
505
506         // data: string of html
507         // context (optional): If specified, the fragment will be created in this context, defaults to document
508         // keepScripts (optional): If true, will include scripts passed in the html string
509         parseHTML: function( data, context, keepScripts ) {
510                 if ( !data || typeof data !== "string" ) {
511                         return null;
512                 }
513                 if ( typeof context === "boolean" ) {
514                         keepScripts = context;
515                         context = false;
516                 }
517                 context = context || document;
518
519                 var parsed = rsingleTag.exec( data ),
520                         scripts = !keepScripts && [];
521
522                 // Single tag
523                 if ( parsed ) {
524                         return [ context.createElement( parsed[1] ) ];
525                 }
526
527                 parsed = jQuery.buildFragment( [ data ], context, scripts );
528
529                 if ( scripts ) {
530                         jQuery( scripts ).remove();
531                 }
532
533                 return jQuery.merge( [], parsed.childNodes );
534         },
535
536         parseJSON: JSON.parse,
537
538         // Cross-browser xml parsing
539         parseXML: function( data ) {
540                 var xml, tmp;
541                 if ( !data || typeof data !== "string" ) {
542                         return null;
543                 }
544
545                 // Support: IE9
546                 try {
547                         tmp = new DOMParser();
548                         xml = tmp.parseFromString( data , "text/xml" );
549                 } catch ( e ) {
550                         xml = undefined;
551                 }
552
553                 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
554                         jQuery.error( "Invalid XML: " + data );
555                 }
556                 return xml;
557         },
558
559         noop: function() {},
560
561         // Evaluates a script in a global context
562         globalEval: function( code ) {
563                 var script,
564                                 indirect = eval;
565
566                 code = jQuery.trim( code );
567
568                 if ( code ) {
569                         // If the code includes a valid, prologue position
570                         // strict mode pragma, execute code by injecting a
571                         // script tag into the document.
572                         if ( code.indexOf("use strict") === 1 ) {
573                                 script = document.createElement("script");
574                                 script.text = code;
575                                 document.head.appendChild( script ).parentNode.removeChild( script );
576                         } else {
577                         // Otherwise, avoid the DOM node creation, insertion
578                         // and removal by using an indirect global eval
579                                 indirect( code );
580                         }
581                 }
582         },
583
584         // Convert dashed to camelCase; used by the css and data modules
585         // Microsoft forgot to hump their vendor prefix (#9572)
586         camelCase: function( string ) {
587                 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
588         },
589
590         nodeName: function( elem, name ) {
591                 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
592         },
593
594         // args is for internal usage only
595         each: function( obj, callback, args ) {
596                 var value,
597                         i = 0,
598                         length = obj.length,
599                         isArray = isArraylike( obj );
600
601                 if ( args ) {
602                         if ( isArray ) {
603                                 for ( ; i < length; i++ ) {
604                                         value = callback.apply( obj[ i ], args );
605
606                                         if ( value === false ) {
607                                                 break;
608                                         }
609                                 }
610                         } else {
611                                 for ( i in obj ) {
612                                         value = callback.apply( obj[ i ], args );
613
614                                         if ( value === false ) {
615                                                 break;
616                                         }
617                                 }
618                         }
619
620                 // A special, fast, case for the most common use of each
621                 } else {
622                         if ( isArray ) {
623                                 for ( ; i < length; i++ ) {
624                                         value = callback.call( obj[ i ], i, obj[ i ] );
625
626                                         if ( value === false ) {
627                                                 break;
628                                         }
629                                 }
630                         } else {
631                                 for ( i in obj ) {
632                                         value = callback.call( obj[ i ], i, obj[ i ] );
633
634                                         if ( value === false ) {
635                                                 break;
636                                         }
637                                 }
638                         }
639                 }
640
641                 return obj;
642         },
643
644         trim: function( text ) {
645                 return text == null ? "" : core_trim.call( text );
646         },
647
648         // results is for internal usage only
649         makeArray: function( arr, results ) {
650                 var ret = results || [];
651
652                 if ( arr != null ) {
653                         if ( isArraylike( Object(arr) ) ) {
654                                 jQuery.merge( ret,
655                                         typeof arr === "string" ?
656                                         [ arr ] : arr
657                                 );
658                         } else {
659                                 core_push.call( ret, arr );
660                         }
661                 }
662
663                 return ret;
664         },
665
666         inArray: function( elem, arr, i ) {
667                 return arr == null ? -1 : core_indexOf.call( arr, elem, i );
668         },
669
670         merge: function( first, second ) {
671                 var l = second.length,
672                         i = first.length,
673                         j = 0;
674
675                 if ( typeof l === "number" ) {
676                         for ( ; j < l; j++ ) {
677                                 first[ i++ ] = second[ j ];
678                         }
679                 } else {
680                         while ( second[j] !== undefined ) {
681                                 first[ i++ ] = second[ j++ ];
682                         }
683                 }
684
685                 first.length = i;
686
687                 return first;
688         },
689
690         grep: function( elems, callback, inv ) {
691                 var retVal,
692                         ret = [],
693                         i = 0,
694                         length = elems.length;
695                 inv = !!inv;
696
697                 // Go through the array, only saving the items
698                 // that pass the validator function
699                 for ( ; i < length; i++ ) {
700                         retVal = !!callback( elems[ i ], i );
701                         if ( inv !== retVal ) {
702                                 ret.push( elems[ i ] );
703                         }
704                 }
705
706                 return ret;
707         },
708
709         // arg is for internal usage only
710         map: function( elems, callback, arg ) {
711                 var value,
712                         i = 0,
713                         length = elems.length,
714                         isArray = isArraylike( elems ),
715                         ret = [];
716
717                 // Go through the array, translating each of the items to their
718                 if ( isArray ) {
719                         for ( ; i < length; i++ ) {
720                                 value = callback( elems[ i ], i, arg );
721
722                                 if ( value != null ) {
723                                         ret[ ret.length ] = value;
724                                 }
725                         }
726
727                 // Go through every key on the object,
728                 } else {
729                         for ( i in elems ) {
730                                 value = callback( elems[ i ], i, arg );
731
732                                 if ( value != null ) {
733                                         ret[ ret.length ] = value;
734                                 }
735                         }
736                 }
737
738                 // Flatten any nested arrays
739                 return core_concat.apply( [], ret );
740         },
741
742         // A global GUID counter for objects
743         guid: 1,
744
745         // Bind a function to a context, optionally partially applying any
746         // arguments.
747         proxy: function( fn, context ) {
748                 var tmp, args, proxy;
749
750                 if ( typeof context === "string" ) {
751                         tmp = fn[ context ];
752                         context = fn;
753                         fn = tmp;
754                 }
755
756                 // Quick check to determine if target is callable, in the spec
757                 // this throws a TypeError, but we will just return undefined.
758                 if ( !jQuery.isFunction( fn ) ) {
759                         return undefined;
760                 }
761
762                 // Simulated bind
763                 args = core_slice.call( arguments, 2 );
764                 proxy = function() {
765                         return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
766                 };
767
768                 // Set the guid of unique handler to the same of original handler, so it can be removed
769                 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
770
771                 return proxy;
772         },
773
774         // Multifunctional method to get and set values of a collection
775         // The value/s can optionally be executed if it's a function
776         access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
777                 var i = 0,
778                         length = elems.length,
779                         bulk = key == null;
780
781                 // Sets many values
782                 if ( jQuery.type( key ) === "object" ) {
783                         chainable = true;
784                         for ( i in key ) {
785                                 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
786                         }
787
788                 // Sets one value
789                 } else if ( value !== undefined ) {
790                         chainable = true;
791
792                         if ( !jQuery.isFunction( value ) ) {
793                                 raw = true;
794                         }
795
796                         if ( bulk ) {
797                                 // Bulk operations run against the entire set
798                                 if ( raw ) {
799                                         fn.call( elems, value );
800                                         fn = null;
801
802                                 // ...except when executing function values
803                                 } else {
804                                         bulk = fn;
805                                         fn = function( elem, key, value ) {
806                                                 return bulk.call( jQuery( elem ), value );
807                                         };
808                                 }
809                         }
810
811                         if ( fn ) {
812                                 for ( ; i < length; i++ ) {
813                                         fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
814                                 }
815                         }
816                 }
817
818                 return chainable ?
819                         elems :
820
821                         // Gets
822                         bulk ?
823                                 fn.call( elems ) :
824                                 length ? fn( elems[0], key ) : emptyGet;
825         },
826
827         now: Date.now,
828
829         // A method for quickly swapping in/out CSS properties to get correct calculations.
830         // Note: this method belongs to the css module but it's needed here for the support module.
831         // If support gets modularized, this method should be moved back to the css module.
832         swap: function( elem, options, callback, args ) {
833                 var ret, name,
834                         old = {};
835
836                 // Remember the old values, and insert the new ones
837                 for ( name in options ) {
838                         old[ name ] = elem.style[ name ];
839                         elem.style[ name ] = options[ name ];
840                 }
841
842                 ret = callback.apply( elem, args || [] );
843
844                 // Revert the old values
845                 for ( name in options ) {
846                         elem.style[ name ] = old[ name ];
847                 }
848
849                 return ret;
850         }
851 });
852
853 jQuery.ready.promise = function( obj ) {
854         if ( !readyList ) {
855
856                 readyList = jQuery.Deferred();
857
858                 // Catch cases where $(document).ready() is called after the browser event has already occurred.
859                 // we once tried to use readyState "interactive" here, but it caused issues like the one
860                 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
861                 if ( document.readyState === "complete" ) {
862                         // Handle it asynchronously to allow scripts the opportunity to delay ready
863                         setTimeout( jQuery.ready );
864
865                 } else {
866
867                         // Use the handy event callback
868                         document.addEventListener( "DOMContentLoaded", completed, false );
869
870                         // A fallback to window.onload, that will always work
871                         window.addEventListener( "load", completed, false );
872                 }
873         }
874         return readyList.promise( obj );
875 };
876
877 // Populate the class2type map
878 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
879         class2type[ "[object " + name + "]" ] = name.toLowerCase();
880 });
881
882 function isArraylike( obj ) {
883         var length = obj.length,
884                 type = jQuery.type( obj );
885
886         if ( jQuery.isWindow( obj ) ) {
887                 return false;
888         }
889
890         if ( obj.nodeType === 1 && length ) {
891                 return true;
892         }
893
894         return type === "array" || type !== "function" &&
895                 ( length === 0 ||
896                 typeof length === "number" && length > 0 && ( length - 1 ) in obj );
897 }
898
899 // All jQuery objects should point back to these
900 rootjQuery = jQuery(document);
901 /*!
902  * Sizzle CSS Selector Engine v1.10.18
903  * http://sizzlejs.com/
904  *
905  * Copyright 2013 jQuery Foundation, Inc. and other contributors
906  * Released under the MIT license
907  * http://jquery.org/license
908  *
909  * Date: 2014-02-05
910  */
911 (function( window ) {
912
913 var i,
914         support,
915         Expr,
916         getText,
917         isXML,
918         compile,
919         select,
920         outermostContext,
921         sortInput,
922         hasDuplicate,
923
924         // Local document vars
925         setDocument,
926         document,
927         docElem,
928         documentIsHTML,
929         rbuggyQSA,
930         rbuggyMatches,
931         matches,
932         contains,
933
934         // Instance-specific data
935         expando = "sizzle" + -(new Date()),
936         preferredDoc = window.document,
937         dirruns = 0,
938         done = 0,
939         classCache = createCache(),
940         tokenCache = createCache(),
941         compilerCache = createCache(),
942         sortOrder = function( a, b ) {
943                 if ( a === b ) {
944                         hasDuplicate = true;
945                 }
946                 return 0;
947         },
948
949         // General-purpose constants
950         strundefined = typeof undefined,
951         MAX_NEGATIVE = 1 << 31,
952
953         // Instance methods
954         hasOwn = ({}).hasOwnProperty,
955         arr = [],
956         pop = arr.pop,
957         push_native = arr.push,
958         push = arr.push,
959         slice = arr.slice,
960         // Use a stripped-down indexOf if we can't use a native one
961         indexOf = arr.indexOf || function( elem ) {
962                 var i = 0,
963                         len = this.length;
964                 for ( ; i < len; i++ ) {
965                         if ( this[i] === elem ) {
966                                 return i;
967                         }
968                 }
969                 return -1;
970         },
971
972         booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
973
974         // Regular expressions
975
976         // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
977         whitespace = "[\\x20\\t\\r\\n\\f]",
978         // http://www.w3.org/TR/css3-syntax/#characters
979         characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
980
981         // Loosely modeled on CSS identifier characters
982         // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
983         // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
984         identifier = characterEncoding.replace( "w", "w#" ),
985
986         // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
987         attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
988                 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
989
990         // Prefer arguments quoted,
991         //   then not containing pseudos/brackets,
992         //   then attribute selectors/non-parenthetical expressions,
993         //   then anything else
994         // These preferences are here to reduce the number of selectors
995         //   needing tokenize in the PSEUDO preFilter
996         pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
997
998         // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
999         rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
1000
1001         rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
1002         rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
1003
1004         rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
1005
1006         rpseudo = new RegExp( pseudos ),
1007         ridentifier = new RegExp( "^" + identifier + "$" ),
1008
1009         matchExpr = {
1010                 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
1011                 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
1012                 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
1013                 "ATTR": new RegExp( "^" + attributes ),
1014                 "PSEUDO": new RegExp( "^" + pseudos ),
1015                 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
1016                         "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
1017                         "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
1018                 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
1019                 // For use in libraries implementing .is()
1020                 // We use this for POS matching in `select`
1021                 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
1022                         whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
1023         },
1024
1025         rinputs = /^(?:input|select|textarea|button)$/i,
1026         rheader = /^h\d$/i,
1027
1028         rnative = /^[^{]+\{\s*\[native \w/,
1029
1030         // Easily-parseable/retrievable ID or TAG or CLASS selectors
1031         rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
1032
1033         rsibling = /[+~]/,
1034         rescape = /'|\\/g,
1035
1036         // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1037         runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
1038         funescape = function( _, escaped, escapedWhitespace ) {
1039                 var high = "0x" + escaped - 0x10000;
1040                 // NaN means non-codepoint
1041                 // Support: Firefox<24
1042                 // Workaround erroneous numeric interpretation of +"0x"
1043                 return high !== high || escapedWhitespace ?
1044                         escaped :
1045                         high < 0 ?
1046                                 // BMP codepoint
1047                                 String.fromCharCode( high + 0x10000 ) :
1048                                 // Supplemental Plane codepoint (surrogate pair)
1049                                 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1050         };
1051
1052 // Optimize for push.apply( _, NodeList )
1053 try {
1054         push.apply(
1055                 (arr = slice.call( preferredDoc.childNodes )),
1056                 preferredDoc.childNodes
1057         );
1058         // Support: Android<4.0
1059         // Detect silently failing push.apply
1060         arr[ preferredDoc.childNodes.length ].nodeType;
1061 } catch ( e ) {
1062         push = { apply: arr.length ?
1063
1064                 // Leverage slice if possible
1065                 function( target, els ) {
1066                         push_native.apply( target, slice.call(els) );
1067                 } :
1068
1069                 // Support: IE<9
1070                 // Otherwise append directly
1071                 function( target, els ) {
1072                         var j = target.length,
1073                                 i = 0;
1074                         // Can't trust NodeList.length
1075                         while ( (target[j++] = els[i++]) ) {}
1076                         target.length = j - 1;
1077                 }
1078         };
1079 }
1080
1081 function Sizzle( selector, context, results, seed ) {
1082         var match, elem, m, nodeType,
1083                 // QSA vars
1084                 i, groups, old, nid, newContext, newSelector;
1085
1086         if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
1087                 setDocument( context );
1088         }
1089
1090         context = context || document;
1091         results = results || [];
1092
1093         if ( !selector || typeof selector !== "string" ) {
1094                 return results;
1095         }
1096
1097         if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
1098                 return [];
1099         }
1100
1101         if ( documentIsHTML && !seed ) {
1102
1103                 // Shortcuts
1104                 if ( (match = rquickExpr.exec( selector )) ) {
1105                         // Speed-up: Sizzle("#ID")
1106                         if ( (m = match[1]) ) {
1107                                 if ( nodeType === 9 ) {
1108                                         elem = context.getElementById( m );
1109                                         // Check parentNode to catch when Blackberry 4.6 returns
1110                                         // nodes that are no longer in the document (jQuery #6963)
1111                                         if ( elem && elem.parentNode ) {
1112                                                 // Handle the case where IE, Opera, and Webkit return items
1113                                                 // by name instead of ID
1114                                                 if ( elem.id === m ) {
1115                                                         results.push( elem );
1116                                                         return results;
1117                                                 }
1118                                         } else {
1119                                                 return results;
1120                                         }
1121                                 } else {
1122                                         // Context is not a document
1123                                         if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
1124                                                 contains( context, elem ) && elem.id === m ) {
1125                                                 results.push( elem );
1126                                                 return results;
1127                                         }
1128                                 }
1129
1130                         // Speed-up: Sizzle("TAG")
1131                         } else if ( match[2] ) {
1132                                 push.apply( results, context.getElementsByTagName( selector ) );
1133                                 return results;
1134
1135                         // Speed-up: Sizzle(".CLASS")
1136                         } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
1137                                 push.apply( results, context.getElementsByClassName( m ) );
1138                                 return results;
1139                         }
1140                 }
1141
1142                 // QSA path
1143                 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
1144                         nid = old = expando;
1145                         newContext = context;
1146                         newSelector = nodeType === 9 && selector;
1147
1148                         // qSA works strangely on Element-rooted queries
1149                         // We can work around this by specifying an extra ID on the root
1150                         // and working up from there (Thanks to Andrew Dupont for the technique)
1151                         // IE 8 doesn't work on object elements
1152                         if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
1153                                 groups = tokenize( selector );
1154
1155                                 if ( (old = context.getAttribute("id")) ) {
1156                                         nid = old.replace( rescape, "\\$&" );
1157                                 } else {
1158                                         context.setAttribute( "id", nid );
1159                                 }
1160                                 nid = "[id='" + nid + "'] ";
1161
1162                                 i = groups.length;
1163                                 while ( i-- ) {
1164                                         groups[i] = nid + toSelector( groups[i] );
1165                                 }
1166                                 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
1167                                 newSelector = groups.join(",");
1168                         }
1169
1170                         if ( newSelector ) {
1171                                 try {
1172                                         push.apply( results,
1173                                                 newContext.querySelectorAll( newSelector )
1174                                         );
1175                                         return results;
1176                                 } catch(qsaError) {
1177                                 } finally {
1178                                         if ( !old ) {
1179                                                 context.removeAttribute("id");
1180                                         }
1181                                 }
1182                         }
1183                 }
1184         }
1185
1186         // All others
1187         return select( selector.replace( rtrim, "$1" ), context, results, seed );
1188 }
1189
1190 /**
1191  * Create key-value caches of limited size
1192  * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
1193  *      property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1194  *      deleting the oldest entry
1195  */
1196 function createCache() {
1197         var keys = [];
1198
1199         function cache( key, value ) {
1200                 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1201                 if ( keys.push( key + " " ) > Expr.cacheLength ) {
1202                         // Only keep the most recent entries
1203                         delete cache[ keys.shift() ];
1204                 }
1205                 return (cache[ key + " " ] = value);
1206         }
1207         return cache;
1208 }
1209
1210 /**
1211  * Mark a function for special use by Sizzle
1212  * @param {Function} fn The function to mark
1213  */
1214 function markFunction( fn ) {
1215         fn[ expando ] = true;
1216         return fn;
1217 }
1218
1219 /**
1220  * Support testing using an element
1221  * @param {Function} fn Passed the created div and expects a boolean result
1222  */
1223 function assert( fn ) {
1224         var div = document.createElement("div");
1225
1226         try {
1227                 return !!fn( div );
1228         } catch (e) {
1229                 return false;
1230         } finally {
1231                 // Remove from its parent by default
1232                 if ( div.parentNode ) {
1233                         div.parentNode.removeChild( div );
1234                 }
1235                 // release memory in IE
1236                 div = null;
1237         }
1238 }
1239
1240 /**
1241  * Adds the same handler for all of the specified attrs
1242  * @param {String} attrs Pipe-separated list of attributes
1243  * @param {Function} handler The method that will be applied
1244  */
1245 function addHandle( attrs, handler ) {
1246         var arr = attrs.split("|"),
1247                 i = attrs.length;
1248
1249         while ( i-- ) {
1250                 Expr.attrHandle[ arr[i] ] = handler;
1251         }
1252 }
1253
1254 /**
1255  * Checks document order of two siblings
1256  * @param {Element} a
1257  * @param {Element} b
1258  * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1259  */
1260 function siblingCheck( a, b ) {
1261         var cur = b && a,
1262                 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1263                         ( ~b.sourceIndex || MAX_NEGATIVE ) -
1264                         ( ~a.sourceIndex || MAX_NEGATIVE );
1265
1266         // Use IE sourceIndex if available on both nodes
1267         if ( diff ) {
1268                 return diff;
1269         }
1270
1271         // Check if b follows a
1272         if ( cur ) {
1273                 while ( (cur = cur.nextSibling) ) {
1274                         if ( cur === b ) {
1275                                 return -1;
1276                         }
1277                 }
1278         }
1279
1280         return a ? 1 : -1;
1281 }
1282
1283 /**
1284  * Returns a function to use in pseudos for input types
1285  * @param {String} type
1286  */
1287 function createInputPseudo( type ) {
1288         return function( elem ) {
1289                 var name = elem.nodeName.toLowerCase();
1290                 return name === "input" && elem.type === type;
1291         };
1292 }
1293
1294 /**
1295  * Returns a function to use in pseudos for buttons
1296  * @param {String} type
1297  */
1298 function createButtonPseudo( type ) {
1299         return function( elem ) {
1300                 var name = elem.nodeName.toLowerCase();
1301                 return (name === "input" || name === "button") && elem.type === type;
1302         };
1303 }
1304
1305 /**
1306  * Returns a function to use in pseudos for positionals
1307  * @param {Function} fn
1308  */
1309 function createPositionalPseudo( fn ) {
1310         return markFunction(function( argument ) {
1311                 argument = +argument;
1312                 return markFunction(function( seed, matches ) {
1313                         var j,
1314                                 matchIndexes = fn( [], seed.length, argument ),
1315                                 i = matchIndexes.length;
1316
1317                         // Match elements found at the specified indexes
1318                         while ( i-- ) {
1319                                 if ( seed[ (j = matchIndexes[i]) ] ) {
1320                                         seed[j] = !(matches[j] = seed[j]);
1321                                 }
1322                         }
1323                 });
1324         });
1325 }
1326
1327 /**
1328  * Checks a node for validity as a Sizzle context
1329  * @param {Element|Object=} context
1330  * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1331  */
1332 function testContext( context ) {
1333         return context && typeof context.getElementsByTagName !== strundefined && context;
1334 }
1335
1336 // Expose support vars for convenience
1337 support = Sizzle.support = {};
1338
1339 /**
1340  * Detects XML nodes
1341  * @param {Element|Object} elem An element or a document
1342  * @returns {Boolean} True iff elem is a non-HTML XML node
1343  */
1344 isXML = Sizzle.isXML = function( elem ) {
1345         // documentElement is verified for cases where it doesn't yet exist
1346         // (such as loading iframes in IE - #4833)
1347         var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1348         return documentElement ? documentElement.nodeName !== "HTML" : false;
1349 };
1350
1351 /**
1352  * Sets document-related variables once based on the current document
1353  * @param {Element|Object} [doc] An element or document object to use to set the document
1354  * @returns {Object} Returns the current document
1355  */
1356 setDocument = Sizzle.setDocument = function( node ) {
1357         var hasCompare,
1358                 doc = node ? node.ownerDocument || node : preferredDoc,
1359                 parent = doc.defaultView;
1360
1361         // If no document and documentElement is available, return
1362         if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1363                 return document;
1364         }
1365
1366         // Set our document
1367         document = doc;
1368         docElem = doc.documentElement;
1369
1370         // Support tests
1371         documentIsHTML = !isXML( doc );
1372
1373         // Support: IE>8
1374         // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1375         // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1376         // IE6-8 do not support the defaultView property so parent will be undefined
1377         if ( parent && parent !== parent.top ) {
1378                 // IE11 does not have attachEvent, so all must suffer
1379                 if ( parent.addEventListener ) {
1380                         parent.addEventListener( "unload", function() {
1381                                 setDocument();
1382                         }, false );
1383                 } else if ( parent.attachEvent ) {
1384                         parent.attachEvent( "onunload", function() {
1385                                 setDocument();
1386                         });
1387                 }
1388         }
1389
1390         /* Attributes
1391         ---------------------------------------------------------------------- */
1392
1393         // Support: IE<8
1394         // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1395         support.attributes = assert(function( div ) {
1396                 div.className = "i";
1397                 return !div.getAttribute("className");
1398         });
1399
1400         /* getElement(s)By*
1401         ---------------------------------------------------------------------- */
1402
1403         // Check if getElementsByTagName("*") returns only elements
1404         support.getElementsByTagName = assert(function( div ) {
1405                 div.appendChild( doc.createComment("") );
1406                 return !div.getElementsByTagName("*").length;
1407         });
1408
1409         // Check if getElementsByClassName can be trusted
1410         support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1411                 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1412
1413                 // Support: Safari<4
1414                 // Catch class over-caching
1415                 div.firstChild.className = "i";
1416                 // Support: Opera<10
1417                 // Catch gEBCN failure to find non-leading classes
1418                 return div.getElementsByClassName("i").length === 2;
1419         });
1420
1421         // Support: IE<10
1422         // Check if getElementById returns elements by name
1423         // The broken getElementById methods don't pick up programatically-set names,
1424         // so use a roundabout getElementsByName test
1425         support.getById = assert(function( div ) {
1426                 docElem.appendChild( div ).id = expando;
1427                 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1428         });
1429
1430         // ID find and filter
1431         if ( support.getById ) {
1432                 Expr.find["ID"] = function( id, context ) {
1433                         if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1434                                 var m = context.getElementById( id );
1435                                 // Check parentNode to catch when Blackberry 4.6 returns
1436                                 // nodes that are no longer in the document #6963
1437                                 return m && m.parentNode ? [m] : [];
1438                         }
1439                 };
1440                 Expr.filter["ID"] = function( id ) {
1441                         var attrId = id.replace( runescape, funescape );
1442                         return function( elem ) {
1443                                 return elem.getAttribute("id") === attrId;
1444                         };
1445                 };
1446         } else {
1447                 // Support: IE6/7
1448                 // getElementById is not reliable as a find shortcut
1449                 delete Expr.find["ID"];
1450
1451                 Expr.filter["ID"] =  function( id ) {
1452                         var attrId = id.replace( runescape, funescape );
1453                         return function( elem ) {
1454                                 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1455                                 return node && node.value === attrId;
1456                         };
1457                 };
1458         }
1459
1460         // Tag
1461         Expr.find["TAG"] = support.getElementsByTagName ?
1462                 function( tag, context ) {
1463                         if ( typeof context.getElementsByTagName !== strundefined ) {
1464                                 return context.getElementsByTagName( tag );
1465                         }
1466                 } :
1467                 function( tag, context ) {
1468                         var elem,
1469                                 tmp = [],
1470                                 i = 0,
1471                                 results = context.getElementsByTagName( tag );
1472
1473                         // Filter out possible comments
1474                         if ( tag === "*" ) {
1475                                 while ( (elem = results[i++]) ) {
1476                                         if ( elem.nodeType === 1 ) {
1477                                                 tmp.push( elem );
1478                                         }
1479                                 }
1480
1481                                 return tmp;
1482                         }
1483                         return results;
1484                 };
1485
1486         // Class
1487         Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1488                 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1489                         return context.getElementsByClassName( className );
1490                 }
1491         };
1492
1493         /* QSA/matchesSelector
1494         ---------------------------------------------------------------------- */
1495
1496         // QSA and matchesSelector support
1497
1498         // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1499         rbuggyMatches = [];
1500
1501         // qSa(:focus) reports false when true (Chrome 21)
1502         // We allow this because of a bug in IE8/9 that throws an error
1503         // whenever `document.activeElement` is accessed on an iframe
1504         // So, we allow :focus to pass through QSA all the time to avoid the IE error
1505         // See http://bugs.jquery.com/ticket/13378
1506         rbuggyQSA = [];
1507
1508         if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1509                 // Build QSA regex
1510                 // Regex strategy adopted from Diego Perini
1511                 assert(function( div ) {
1512                         // Select is set to empty string on purpose
1513                         // This is to test IE's treatment of not explicitly
1514                         // setting a boolean content attribute,
1515                         // since its presence should be enough
1516                         // http://bugs.jquery.com/ticket/12359
1517                         div.innerHTML = "<select t=''><option selected=''></option></select>";
1518
1519                         // Support: IE8, Opera 10-12
1520                         // Nothing should be selected when empty strings follow ^= or $= or *=
1521                         if ( div.querySelectorAll("[t^='']").length ) {
1522                                 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1523                         }
1524
1525                         // Support: IE8
1526                         // Boolean attributes and "value" are not treated correctly
1527                         if ( !div.querySelectorAll("[selected]").length ) {
1528                                 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1529                         }
1530
1531                         // Webkit/Opera - :checked should return selected option elements
1532                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1533                         // IE8 throws error here and will not see later tests
1534                         if ( !div.querySelectorAll(":checked").length ) {
1535                                 rbuggyQSA.push(":checked");
1536                         }
1537                 });
1538
1539                 assert(function( div ) {
1540                         // Support: Windows 8 Native Apps
1541                         // The type and name attributes are restricted during .innerHTML assignment
1542                         var input = doc.createElement("input");
1543                         input.setAttribute( "type", "hidden" );
1544                         div.appendChild( input ).setAttribute( "name", "D" );
1545
1546                         // Support: IE8
1547                         // Enforce case-sensitivity of name attribute
1548                         if ( div.querySelectorAll("[name=d]").length ) {
1549                                 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1550                         }
1551
1552                         // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1553                         // IE8 throws error here and will not see later tests
1554                         if ( !div.querySelectorAll(":enabled").length ) {
1555                                 rbuggyQSA.push( ":enabled", ":disabled" );
1556                         }
1557
1558                         // Opera 10-11 does not throw on post-comma invalid pseudos
1559                         div.querySelectorAll("*,:x");
1560                         rbuggyQSA.push(",.*:");
1561                 });
1562         }
1563
1564         if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1565                 docElem.mozMatchesSelector ||
1566                 docElem.oMatchesSelector ||
1567                 docElem.msMatchesSelector) )) ) {
1568
1569                 assert(function( div ) {
1570                         // Check to see if it's possible to do matchesSelector
1571                         // on a disconnected node (IE 9)
1572                         support.disconnectedMatch = matches.call( div, "div" );
1573
1574                         // This should fail with an exception
1575                         // Gecko does not error, returns false instead
1576                         matches.call( div, "[s!='']:x" );
1577                         rbuggyMatches.push( "!=", pseudos );
1578                 });
1579         }
1580
1581         rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1582         rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1583
1584         /* Contains
1585         ---------------------------------------------------------------------- */
1586         hasCompare = rnative.test( docElem.compareDocumentPosition );
1587
1588         // Element contains another
1589         // Purposefully does not implement inclusive descendent
1590         // As in, an element does not contain itself
1591         contains = hasCompare || rnative.test( docElem.contains ) ?
1592                 function( a, b ) {
1593                         var adown = a.nodeType === 9 ? a.documentElement : a,
1594                                 bup = b && b.parentNode;
1595                         return a === bup || !!( bup && bup.nodeType === 1 && (
1596                                 adown.contains ?
1597                                         adown.contains( bup ) :
1598                                         a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1599                         ));
1600                 } :
1601                 function( a, b ) {
1602                         if ( b ) {
1603                                 while ( (b = b.parentNode) ) {
1604                                         if ( b === a ) {
1605                                                 return true;
1606                                         }
1607                                 }
1608                         }
1609                         return false;
1610                 };
1611
1612         /* Sorting
1613         ---------------------------------------------------------------------- */
1614
1615         // Document order sorting
1616         sortOrder = hasCompare ?
1617         function( a, b ) {
1618
1619                 // Flag for duplicate removal
1620                 if ( a === b ) {
1621                         hasDuplicate = true;
1622                         return 0;
1623                 }
1624
1625                 // Sort on method existence if only one input has compareDocumentPosition
1626                 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1627                 if ( compare ) {
1628                         return compare;
1629                 }
1630
1631                 // Calculate position if both inputs belong to the same document
1632                 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1633                         a.compareDocumentPosition( b ) :
1634
1635                         // Otherwise we know they are disconnected
1636                         1;
1637
1638                 // Disconnected nodes
1639                 if ( compare & 1 ||
1640                         (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1641
1642                         // Choose the first element that is related to our preferred document
1643                         if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1644                                 return -1;
1645                         }
1646                         if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1647                                 return 1;
1648                         }
1649
1650                         // Maintain original order
1651                         return sortInput ?
1652                                 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1653                                 0;
1654                 }
1655
1656                 return compare & 4 ? -1 : 1;
1657         } :
1658         function( a, b ) {
1659                 // Exit early if the nodes are identical
1660                 if ( a === b ) {
1661                         hasDuplicate = true;
1662                         return 0;
1663                 }
1664
1665                 var cur,
1666                         i = 0,
1667                         aup = a.parentNode,
1668                         bup = b.parentNode,
1669                         ap = [ a ],
1670                         bp = [ b ];
1671
1672                 // Parentless nodes are either documents or disconnected
1673                 if ( !aup || !bup ) {
1674                         return a === doc ? -1 :
1675                                 b === doc ? 1 :
1676                                 aup ? -1 :
1677                                 bup ? 1 :
1678                                 sortInput ?
1679                                 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1680                                 0;
1681
1682                 // If the nodes are siblings, we can do a quick check
1683                 } else if ( aup === bup ) {
1684                         return siblingCheck( a, b );
1685                 }
1686
1687                 // Otherwise we need full lists of their ancestors for comparison
1688                 cur = a;
1689                 while ( (cur = cur.parentNode) ) {
1690                         ap.unshift( cur );
1691                 }
1692                 cur = b;
1693                 while ( (cur = cur.parentNode) ) {
1694                         bp.unshift( cur );
1695                 }
1696
1697                 // Walk down the tree looking for a discrepancy
1698                 while ( ap[i] === bp[i] ) {
1699                         i++;
1700                 }
1701
1702                 return i ?
1703                         // Do a sibling check if the nodes have a common ancestor
1704                         siblingCheck( ap[i], bp[i] ) :
1705
1706                         // Otherwise nodes in our document sort first
1707                         ap[i] === preferredDoc ? -1 :
1708                         bp[i] === preferredDoc ? 1 :
1709                         0;
1710         };
1711
1712         return doc;
1713 };
1714
1715 Sizzle.matches = function( expr, elements ) {
1716         return Sizzle( expr, null, null, elements );
1717 };
1718
1719 Sizzle.matchesSelector = function( elem, expr ) {
1720         // Set document vars if needed
1721         if ( ( elem.ownerDocument || elem ) !== document ) {
1722                 setDocument( elem );
1723         }
1724
1725         // Make sure that attribute selectors are quoted
1726         expr = expr.replace( rattributeQuotes, "='$1']" );
1727
1728         if ( support.matchesSelector && documentIsHTML &&
1729                 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1730                 ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1731
1732                 try {
1733                         var ret = matches.call( elem, expr );
1734
1735                         // IE 9's matchesSelector returns false on disconnected nodes
1736                         if ( ret || support.disconnectedMatch ||
1737                                         // As well, disconnected nodes are said to be in a document
1738                                         // fragment in IE 9
1739                                         elem.document && elem.document.nodeType !== 11 ) {
1740                                 return ret;
1741                         }
1742                 } catch(e) {}
1743         }
1744
1745         return Sizzle( expr, document, null, [elem] ).length > 0;
1746 };
1747
1748 Sizzle.contains = function( context, elem ) {
1749         // Set document vars if needed
1750         if ( ( context.ownerDocument || context ) !== document ) {
1751                 setDocument( context );
1752         }
1753         return contains( context, elem );
1754 };
1755
1756 Sizzle.attr = function( elem, name ) {
1757         // Set document vars if needed
1758         if ( ( elem.ownerDocument || elem ) !== document ) {
1759                 setDocument( elem );
1760         }
1761
1762         var fn = Expr.attrHandle[ name.toLowerCase() ],
1763                 // Don't get fooled by Object.prototype properties (jQuery #13807)
1764                 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1765                         fn( elem, name, !documentIsHTML ) :
1766                         undefined;
1767
1768         return val !== undefined ?
1769                 val :
1770                 support.attributes || !documentIsHTML ?
1771                         elem.getAttribute( name ) :
1772                         (val = elem.getAttributeNode(name)) && val.specified ?
1773                                 val.value :
1774                                 null;
1775 };
1776
1777 Sizzle.error = function( msg ) {
1778         throw new Error( "Syntax error, unrecognized expression: " + msg );
1779 };
1780
1781 /**
1782  * Document sorting and removing duplicates
1783  * @param {ArrayLike} results
1784  */
1785 Sizzle.uniqueSort = function( results ) {
1786         var elem,
1787                 duplicates = [],
1788                 j = 0,
1789                 i = 0;
1790
1791         // Unless we *know* we can detect duplicates, assume their presence
1792         hasDuplicate = !support.detectDuplicates;
1793         sortInput = !support.sortStable && results.slice( 0 );
1794         results.sort( sortOrder );
1795
1796         if ( hasDuplicate ) {
1797                 while ( (elem = results[i++]) ) {
1798                         if ( elem === results[ i ] ) {
1799                                 j = duplicates.push( i );
1800                         }
1801                 }
1802                 while ( j-- ) {
1803                         results.splice( duplicates[ j ], 1 );
1804                 }
1805         }
1806
1807         // Clear input after sorting to release objects
1808         // See https://github.com/jquery/sizzle/pull/225
1809         sortInput = null;
1810
1811         return results;
1812 };
1813
1814 /**
1815  * Utility function for retrieving the text value of an array of DOM nodes
1816  * @param {Array|Element} elem
1817  */
1818 getText = Sizzle.getText = function( elem ) {
1819         var node,
1820                 ret = "",
1821                 i = 0,
1822                 nodeType = elem.nodeType;
1823
1824         if ( !nodeType ) {
1825                 // If no nodeType, this is expected to be an array
1826                 while ( (node = elem[i++]) ) {
1827                         // Do not traverse comment nodes
1828                         ret += getText( node );
1829                 }
1830         } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1831                 // Use textContent for elements
1832                 // innerText usage removed for consistency of new lines (jQuery #11153)
1833                 if ( typeof elem.textContent === "string" ) {
1834                         return elem.textContent;
1835                 } else {
1836                         // Traverse its children
1837                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1838                                 ret += getText( elem );
1839                         }
1840                 }
1841         } else if ( nodeType === 3 || nodeType === 4 ) {
1842                 return elem.nodeValue;
1843         }
1844         // Do not include comment or processing instruction nodes
1845
1846         return ret;
1847 };
1848
1849 Expr = Sizzle.selectors = {
1850
1851         // Can be adjusted by the user
1852         cacheLength: 50,
1853
1854         createPseudo: markFunction,
1855
1856         match: matchExpr,
1857
1858         attrHandle: {},
1859
1860         find: {},
1861
1862         relative: {
1863                 ">": { dir: "parentNode", first: true },
1864                 " ": { dir: "parentNode" },
1865                 "+": { dir: "previousSibling", first: true },
1866                 "~": { dir: "previousSibling" }
1867         },
1868
1869         preFilter: {
1870                 "ATTR": function( match ) {
1871                         match[1] = match[1].replace( runescape, funescape );
1872
1873                         // Move the given value to match[3] whether quoted or unquoted
1874                         match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1875
1876                         if ( match[2] === "~=" ) {
1877                                 match[3] = " " + match[3] + " ";
1878                         }
1879
1880                         return match.slice( 0, 4 );
1881                 },
1882
1883                 "CHILD": function( match ) {
1884                         /* matches from matchExpr["CHILD"]
1885                                 1 type (only|nth|...)
1886                                 2 what (child|of-type)
1887                                 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1888                                 4 xn-component of xn+y argument ([+-]?\d*n|)
1889                                 5 sign of xn-component
1890                                 6 x of xn-component
1891                                 7 sign of y-component
1892                                 8 y of y-component
1893                         */
1894                         match[1] = match[1].toLowerCase();
1895
1896                         if ( match[1].slice( 0, 3 ) === "nth" ) {
1897                                 // nth-* requires argument
1898                                 if ( !match[3] ) {
1899                                         Sizzle.error( match[0] );
1900                                 }
1901
1902                                 // numeric x and y parameters for Expr.filter.CHILD
1903                                 // remember that false/true cast respectively to 0/1
1904                                 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1905                                 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1906
1907                         // other types prohibit arguments
1908                         } else if ( match[3] ) {
1909                                 Sizzle.error( match[0] );
1910                         }
1911
1912                         return match;
1913                 },
1914
1915                 "PSEUDO": function( match ) {
1916                         var excess,
1917                                 unquoted = !match[5] && match[2];
1918
1919                         if ( matchExpr["CHILD"].test( match[0] ) ) {
1920                                 return null;
1921                         }
1922
1923                         // Accept quoted arguments as-is
1924                         if ( match[3] && match[4] !== undefined ) {
1925                                 match[2] = match[4];
1926
1927                         // Strip excess characters from unquoted arguments
1928                         } else if ( unquoted && rpseudo.test( unquoted ) &&
1929                                 // Get excess from tokenize (recursively)
1930                                 (excess = tokenize( unquoted, true )) &&
1931                                 // advance to the next closing parenthesis
1932                                 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1933
1934                                 // excess is a negative index
1935                                 match[0] = match[0].slice( 0, excess );
1936                                 match[2] = unquoted.slice( 0, excess );
1937                         }
1938
1939                         // Return only captures needed by the pseudo filter method (type and argument)
1940                         return match.slice( 0, 3 );
1941                 }
1942         },
1943
1944         filter: {
1945
1946                 "TAG": function( nodeNameSelector ) {
1947                         var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1948                         return nodeNameSelector === "*" ?
1949                                 function() { return true; } :
1950                                 function( elem ) {
1951                                         return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1952                                 };
1953                 },
1954
1955                 "CLASS": function( className ) {
1956                         var pattern = classCache[ className + " " ];
1957
1958                         return pattern ||
1959                                 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1960                                 classCache( className, function( elem ) {
1961                                         return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1962                                 });
1963                 },
1964
1965                 "ATTR": function( name, operator, check ) {
1966                         return function( elem ) {
1967                                 var result = Sizzle.attr( elem, name );
1968
1969                                 if ( result == null ) {
1970                                         return operator === "!=";
1971                                 }
1972                                 if ( !operator ) {
1973                                         return true;
1974                                 }
1975
1976                                 result += "";
1977
1978                                 return operator === "=" ? result === check :
1979                                         operator === "!=" ? result !== check :
1980                                         operator === "^=" ? check && result.indexOf( check ) === 0 :
1981                                         operator === "*=" ? check && result.indexOf( check ) > -1 :
1982                                         operator === "$=" ? check && result.slice( -check.length ) === check :
1983                                         operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1984                                         operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1985                                         false;
1986                         };
1987                 },
1988
1989                 "CHILD": function( type, what, argument, first, last ) {
1990                         var simple = type.slice( 0, 3 ) !== "nth",
1991                                 forward = type.slice( -4 ) !== "last",
1992                                 ofType = what === "of-type";
1993
1994                         return first === 1 && last === 0 ?
1995
1996                                 // Shortcut for :nth-*(n)
1997                                 function( elem ) {
1998                                         return !!elem.parentNode;
1999                                 } :
2000
2001                                 function( elem, context, xml ) {
2002                                         var cache, outerCache, node, diff, nodeIndex, start,
2003                                                 dir = simple !== forward ? "nextSibling" : "previousSibling",
2004                                                 parent = elem.parentNode,
2005                                                 name = ofType && elem.nodeName.toLowerCase(),
2006                                                 useCache = !xml && !ofType;
2007
2008                                         if ( parent ) {
2009
2010                                                 // :(first|last|only)-(child|of-type)
2011                                                 if ( simple ) {
2012                                                         while ( dir ) {
2013                                                                 node = elem;
2014                                                                 while ( (node = node[ dir ]) ) {
2015                                                                         if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
2016                                                                                 return false;
2017                                                                         }
2018                                                                 }
2019                                                                 // Reverse direction for :only-* (if we haven't yet done so)
2020                                                                 start = dir = type === "only" && !start && "nextSibling";
2021                                                         }
2022                                                         return true;
2023                                                 }
2024
2025                                                 start = [ forward ? parent.firstChild : parent.lastChild ];
2026
2027                                                 // non-xml :nth-child(...) stores cache data on `parent`
2028                                                 if ( forward && useCache ) {
2029                                                         // Seek `elem` from a previously-cached index
2030                                                         outerCache = parent[ expando ] || (parent[ expando ] = {});
2031                                                         cache = outerCache[ type ] || [];
2032                                                         nodeIndex = cache[0] === dirruns && cache[1];
2033                                                         diff = cache[0] === dirruns && cache[2];
2034                                                         node = nodeIndex && parent.childNodes[ nodeIndex ];
2035
2036                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
2037
2038                                                                 // Fallback to seeking `elem` from the start
2039                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
2040
2041                                                                 // When found, cache indexes on `parent` and break
2042                                                                 if ( node.nodeType === 1 && ++diff && node === elem ) {
2043                                                                         outerCache[ type ] = [ dirruns, nodeIndex, diff ];
2044                                                                         break;
2045                                                                 }
2046                                                         }
2047
2048                                                 // Use previously-cached element index if available
2049                                                 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
2050                                                         diff = cache[1];
2051
2052                                                 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
2053                                                 } else {
2054                                                         // Use the same loop as above to seek `elem` from the start
2055                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
2056                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
2057
2058                                                                 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
2059                                                                         // Cache the index of each encountered element
2060                                                                         if ( useCache ) {
2061                                                                                 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
2062                                                                         }
2063
2064                                                                         if ( node === elem ) {
2065                                                                                 break;
2066                                                                         }
2067                                                                 }
2068                                                         }
2069                                                 }
2070
2071                                                 // Incorporate the offset, then check against cycle size
2072                                                 diff -= last;
2073                                                 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2074                                         }
2075                                 };
2076                 },
2077
2078                 "PSEUDO": function( pseudo, argument ) {
2079                         // pseudo-class names are case-insensitive
2080                         // http://www.w3.org/TR/selectors/#pseudo-classes
2081                         // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2082                         // Remember that setFilters inherits from pseudos
2083                         var args,
2084                                 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2085                                         Sizzle.error( "unsupported pseudo: " + pseudo );
2086
2087                         // The user may use createPseudo to indicate that
2088                         // arguments are needed to create the filter function
2089                         // just as Sizzle does
2090                         if ( fn[ expando ] ) {
2091                                 return fn( argument );
2092                         }
2093
2094                         // But maintain support for old signatures
2095                         if ( fn.length > 1 ) {
2096                                 args = [ pseudo, pseudo, "", argument ];
2097                                 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2098                                         markFunction(function( seed, matches ) {
2099                                                 var idx,
2100                                                         matched = fn( seed, argument ),
2101                                                         i = matched.length;
2102                                                 while ( i-- ) {
2103                                                         idx = indexOf.call( seed, matched[i] );
2104                                                         seed[ idx ] = !( matches[ idx ] = matched[i] );
2105                                                 }
2106                                         }) :
2107                                         function( elem ) {
2108                                                 return fn( elem, 0, args );
2109                                         };
2110                         }
2111
2112                         return fn;
2113                 }
2114         },
2115
2116         pseudos: {
2117                 // Potentially complex pseudos
2118                 "not": markFunction(function( selector ) {
2119                         // Trim the selector passed to compile
2120                         // to avoid treating leading and trailing
2121                         // spaces as combinators
2122                         var input = [],
2123                                 results = [],
2124                                 matcher = compile( selector.replace( rtrim, "$1" ) );
2125
2126                         return matcher[ expando ] ?
2127                                 markFunction(function( seed, matches, context, xml ) {
2128                                         var elem,
2129                                                 unmatched = matcher( seed, null, xml, [] ),
2130                                                 i = seed.length;
2131
2132                                         // Match elements unmatched by `matcher`
2133                                         while ( i-- ) {
2134                                                 if ( (elem = unmatched[i]) ) {
2135                                                         seed[i] = !(matches[i] = elem);
2136                                                 }
2137                                         }
2138                                 }) :
2139                                 function( elem, context, xml ) {
2140                                         input[0] = elem;
2141                                         matcher( input, null, xml, results );
2142                                         return !results.pop();
2143                                 };
2144                 }),
2145
2146                 "has": markFunction(function( selector ) {
2147                         return function( elem ) {
2148                                 return Sizzle( selector, elem ).length > 0;
2149                         };
2150                 }),
2151
2152                 "contains": markFunction(function( text ) {
2153                         return function( elem ) {
2154                                 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2155                         };
2156                 }),
2157
2158                 // "Whether an element is represented by a :lang() selector
2159                 // is based solely on the element's language value
2160                 // being equal to the identifier C,
2161                 // or beginning with the identifier C immediately followed by "-".
2162                 // The matching of C against the element's language value is performed case-insensitively.
2163                 // The identifier C does not have to be a valid language name."
2164                 // http://www.w3.org/TR/selectors/#lang-pseudo
2165                 "lang": markFunction( function( lang ) {
2166                         // lang value must be a valid identifier
2167                         if ( !ridentifier.test(lang || "") ) {
2168                                 Sizzle.error( "unsupported lang: " + lang );
2169                         }
2170                         lang = lang.replace( runescape, funescape ).toLowerCase();
2171                         return function( elem ) {
2172                                 var elemLang;
2173                                 do {
2174                                         if ( (elemLang = documentIsHTML ?
2175                                                 elem.lang :
2176                                                 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2177
2178                                                 elemLang = elemLang.toLowerCase();
2179                                                 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2180                                         }
2181                                 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2182                                 return false;
2183                         };
2184                 }),
2185
2186                 // Miscellaneous
2187                 "target": function( elem ) {
2188                         var hash = window.location && window.location.hash;
2189                         return hash && hash.slice( 1 ) === elem.id;
2190                 },
2191
2192                 "root": function( elem ) {
2193                         return elem === docElem;
2194                 },
2195
2196                 "focus": function( elem ) {
2197                         return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2198                 },
2199
2200                 // Boolean properties
2201                 "enabled": function( elem ) {
2202                         return elem.disabled === false;
2203                 },
2204
2205                 "disabled": function( elem ) {
2206                         return elem.disabled === true;
2207                 },
2208
2209                 "checked": function( elem ) {
2210                         // In CSS3, :checked should return both checked and selected elements
2211                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2212                         var nodeName = elem.nodeName.toLowerCase();
2213                         return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2214                 },
2215
2216                 "selected": function( elem ) {
2217                         // Accessing this property makes selected-by-default
2218                         // options in Safari work properly
2219                         if ( elem.parentNode ) {
2220                                 elem.parentNode.selectedIndex;
2221                         }
2222
2223                         return elem.selected === true;
2224                 },
2225
2226                 // Contents
2227                 "empty": function( elem ) {
2228                         // http://www.w3.org/TR/selectors/#empty-pseudo
2229                         // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2230                         //   but not by others (comment: 8; processing instruction: 7; etc.)
2231                         // nodeType < 6 works because attributes (2) do not appear as children
2232                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2233                                 if ( elem.nodeType < 6 ) {
2234                                         return false;
2235                                 }
2236                         }
2237                         return true;
2238                 },
2239
2240                 "parent": function( elem ) {
2241                         return !Expr.pseudos["empty"]( elem );
2242                 },
2243
2244                 // Element/input types
2245                 "header": function( elem ) {
2246                         return rheader.test( elem.nodeName );
2247                 },
2248
2249                 "input": function( elem ) {
2250                         return rinputs.test( elem.nodeName );
2251                 },
2252
2253                 "button": function( elem ) {
2254                         var name = elem.nodeName.toLowerCase();
2255                         return name === "input" && elem.type === "button" || name === "button";
2256                 },
2257
2258                 "text": function( elem ) {
2259                         var attr;
2260                         return elem.nodeName.toLowerCase() === "input" &&
2261                                 elem.type === "text" &&
2262
2263                                 // Support: IE<8
2264                                 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2265                                 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2266                 },
2267
2268                 // Position-in-collection
2269                 "first": createPositionalPseudo(function() {
2270                         return [ 0 ];
2271                 }),
2272
2273                 "last": createPositionalPseudo(function( matchIndexes, length ) {
2274                         return [ length - 1 ];
2275                 }),
2276
2277                 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2278                         return [ argument < 0 ? argument + length : argument ];
2279                 }),
2280
2281                 "even": createPositionalPseudo(function( matchIndexes, length ) {
2282                         var i = 0;
2283                         for ( ; i < length; i += 2 ) {
2284                                 matchIndexes.push( i );
2285                         }
2286                         return matchIndexes;
2287                 }),
2288
2289                 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2290                         var i = 1;
2291                         for ( ; i < length; i += 2 ) {
2292                                 matchIndexes.push( i );
2293                         }
2294                         return matchIndexes;
2295                 }),
2296
2297                 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2298                         var i = argument < 0 ? argument + length : argument;
2299                         for ( ; --i >= 0; ) {
2300                                 matchIndexes.push( i );
2301                         }
2302                         return matchIndexes;
2303                 }),
2304
2305                 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2306                         var i = argument < 0 ? argument + length : argument;
2307                         for ( ; ++i < length; ) {
2308                                 matchIndexes.push( i );
2309                         }
2310                         return matchIndexes;
2311                 })
2312         }
2313 };
2314
2315 Expr.pseudos["nth"] = Expr.pseudos["eq"];
2316
2317 // Add button/input type pseudos
2318 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2319         Expr.pseudos[ i ] = createInputPseudo( i );
2320 }
2321 for ( i in { submit: true, reset: true } ) {
2322         Expr.pseudos[ i ] = createButtonPseudo( i );
2323 }
2324
2325 // Easy API for creating new setFilters
2326 function setFilters() {}
2327 setFilters.prototype = Expr.filters = Expr.pseudos;
2328 Expr.setFilters = new setFilters();
2329
2330 function tokenize( selector, parseOnly ) {
2331         var matched, match, tokens, type,
2332                 soFar, groups, preFilters,
2333                 cached = tokenCache[ selector + " " ];
2334
2335         if ( cached ) {
2336                 return parseOnly ? 0 : cached.slice( 0 );
2337         }
2338
2339         soFar = selector;
2340         groups = [];
2341         preFilters = Expr.preFilter;
2342
2343         while ( soFar ) {
2344
2345                 // Comma and first run
2346                 if ( !matched || (match = rcomma.exec( soFar )) ) {
2347                         if ( match ) {
2348                                 // Don't consume trailing commas as valid
2349                                 soFar = soFar.slice( match[0].length ) || soFar;
2350                         }
2351                         groups.push( (tokens = []) );
2352                 }
2353
2354                 matched = false;
2355
2356                 // Combinators
2357                 if ( (match = rcombinators.exec( soFar )) ) {
2358                         matched = match.shift();
2359                         tokens.push({
2360                                 value: matched,
2361                                 // Cast descendant combinators to space
2362                                 type: match[0].replace( rtrim, " " )
2363                         });
2364                         soFar = soFar.slice( matched.length );
2365                 }
2366
2367                 // Filters
2368                 for ( type in Expr.filter ) {
2369                         if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2370                                 (match = preFilters[ type ]( match ))) ) {
2371                                 matched = match.shift();
2372                                 tokens.push({
2373                                         value: matched,
2374                                         type: type,
2375                                         matches: match
2376                                 });
2377                                 soFar = soFar.slice( matched.length );
2378                         }
2379                 }
2380
2381                 if ( !matched ) {
2382                         break;
2383                 }
2384         }
2385
2386         // Return the length of the invalid excess
2387         // if we're just parsing
2388         // Otherwise, throw an error or return tokens
2389         return parseOnly ?
2390                 soFar.length :
2391                 soFar ?
2392                         Sizzle.error( selector ) :
2393                         // Cache the tokens
2394                         tokenCache( selector, groups ).slice( 0 );
2395 }
2396
2397 function toSelector( tokens ) {
2398         var i = 0,
2399                 len = tokens.length,
2400                 selector = "";
2401         for ( ; i < len; i++ ) {
2402                 selector += tokens[i].value;
2403         }
2404         return selector;
2405 }
2406
2407 function addCombinator( matcher, combinator, base ) {
2408         var dir = combinator.dir,
2409                 checkNonElements = base && dir === "parentNode",
2410                 doneName = done++;
2411
2412         return combinator.first ?
2413                 // Check against closest ancestor/preceding element
2414                 function( elem, context, xml ) {
2415                         while ( (elem = elem[ dir ]) ) {
2416                                 if ( elem.nodeType === 1 || checkNonElements ) {
2417                                         return matcher( elem, context, xml );
2418                                 }
2419                         }
2420                 } :
2421
2422                 // Check against all ancestor/preceding elements
2423                 function( elem, context, xml ) {
2424                         var oldCache, outerCache,
2425                                 newCache = [ dirruns, doneName ];
2426
2427                         // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2428                         if ( xml ) {
2429                                 while ( (elem = elem[ dir ]) ) {
2430                                         if ( elem.nodeType === 1 || checkNonElements ) {
2431                                                 if ( matcher( elem, context, xml ) ) {
2432                                                         return true;
2433                                                 }
2434                                         }
2435                                 }
2436                         } else {
2437                                 while ( (elem = elem[ dir ]) ) {
2438                                         if ( elem.nodeType === 1 || checkNonElements ) {
2439                                                 outerCache = elem[ expando ] || (elem[ expando ] = {});
2440                                                 if ( (oldCache = outerCache[ dir ]) &&
2441                                                         oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2442
2443                                                         // Assign to newCache so results back-propagate to previous elements
2444                                                         return (newCache[ 2 ] = oldCache[ 2 ]);
2445                                                 } else {
2446                                                         // Reuse newcache so results back-propagate to previous elements
2447                                                         outerCache[ dir ] = newCache;
2448
2449                                                         // A match means we're done; a fail means we have to keep checking
2450                                                         if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2451                                                                 return true;
2452                                                         }
2453                                                 }
2454                                         }
2455                                 }
2456                         }
2457                 };
2458 }
2459
2460 function elementMatcher( matchers ) {
2461         return matchers.length > 1 ?
2462                 function( elem, context, xml ) {
2463                         var i = matchers.length;
2464                         while ( i-- ) {
2465                                 if ( !matchers[i]( elem, context, xml ) ) {
2466                                         return false;
2467                                 }
2468                         }
2469                         return true;
2470                 } :
2471                 matchers[0];
2472 }
2473
2474 function multipleContexts( selector, contexts, results ) {
2475         var i = 0,
2476                 len = contexts.length;
2477         for ( ; i < len; i++ ) {
2478                 Sizzle( selector, contexts[i], results );
2479         }
2480         return results;
2481 }
2482
2483 function condense( unmatched, map, filter, context, xml ) {
2484         var elem,
2485                 newUnmatched = [],
2486                 i = 0,
2487                 len = unmatched.length,
2488                 mapped = map != null;
2489
2490         for ( ; i < len; i++ ) {
2491                 if ( (elem = unmatched[i]) ) {
2492                         if ( !filter || filter( elem, context, xml ) ) {
2493                                 newUnmatched.push( elem );
2494                                 if ( mapped ) {
2495                                         map.push( i );
2496                                 }
2497                         }
2498                 }
2499         }
2500
2501         return newUnmatched;
2502 }
2503
2504 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2505         if ( postFilter && !postFilter[ expando ] ) {
2506                 postFilter = setMatcher( postFilter );
2507         }
2508         if ( postFinder && !postFinder[ expando ] ) {
2509                 postFinder = setMatcher( postFinder, postSelector );
2510         }
2511         return markFunction(function( seed, results, context, xml ) {
2512                 var temp, i, elem,
2513                         preMap = [],
2514                         postMap = [],
2515                         preexisting = results.length,
2516
2517                         // Get initial elements from seed or context
2518                         elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2519
2520                         // Prefilter to get matcher input, preserving a map for seed-results synchronization
2521                         matcherIn = preFilter && ( seed || !selector ) ?
2522                                 condense( elems, preMap, preFilter, context, xml ) :
2523                                 elems,
2524
2525                         matcherOut = matcher ?
2526                                 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2527                                 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2528
2529                                         // ...intermediate processing is necessary
2530                                         [] :
2531
2532                                         // ...otherwise use results directly
2533                                         results :
2534                                 matcherIn;
2535
2536                 // Find primary matches
2537                 if ( matcher ) {
2538                         matcher( matcherIn, matcherOut, context, xml );
2539                 }
2540
2541                 // Apply postFilter
2542                 if ( postFilter ) {
2543                         temp = condense( matcherOut, postMap );
2544                         postFilter( temp, [], context, xml );
2545
2546                         // Un-match failing elements by moving them back to matcherIn
2547                         i = temp.length;
2548                         while ( i-- ) {
2549                                 if ( (elem = temp[i]) ) {
2550                                         matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2551                                 }
2552                         }
2553                 }
2554
2555                 if ( seed ) {
2556                         if ( postFinder || preFilter ) {
2557                                 if ( postFinder ) {
2558                                         // Get the final matcherOut by condensing this intermediate into postFinder contexts
2559                                         temp = [];
2560                                         i = matcherOut.length;
2561                                         while ( i-- ) {
2562                                                 if ( (elem = matcherOut[i]) ) {
2563                                                         // Restore matcherIn since elem is not yet a final match
2564                                                         temp.push( (matcherIn[i] = elem) );
2565                                                 }
2566                                         }
2567                                         postFinder( null, (matcherOut = []), temp, xml );
2568                                 }
2569
2570                                 // Move matched elements from seed to results to keep them synchronized
2571                                 i = matcherOut.length;
2572                                 while ( i-- ) {
2573                                         if ( (elem = matcherOut[i]) &&
2574                                                 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2575
2576                                                 seed[temp] = !(results[temp] = elem);
2577                                         }
2578                                 }
2579                         }
2580
2581                 // Add elements to results, through postFinder if defined
2582                 } else {
2583                         matcherOut = condense(
2584                                 matcherOut === results ?
2585                                         matcherOut.splice( preexisting, matcherOut.length ) :
2586                                         matcherOut
2587                         );
2588                         if ( postFinder ) {
2589                                 postFinder( null, results, matcherOut, xml );
2590                         } else {
2591                                 push.apply( results, matcherOut );
2592                         }
2593                 }
2594         });
2595 }
2596
2597 function matcherFromTokens( tokens ) {
2598         var checkContext, matcher, j,
2599                 len = tokens.length,
2600                 leadingRelative = Expr.relative[ tokens[0].type ],
2601                 implicitRelative = leadingRelative || Expr.relative[" "],
2602                 i = leadingRelative ? 1 : 0,
2603
2604                 // The foundational matcher ensures that elements are reachable from top-level context(s)
2605                 matchContext = addCombinator( function( elem ) {
2606                         return elem === checkContext;
2607                 }, implicitRelative, true ),
2608                 matchAnyContext = addCombinator( function( elem ) {
2609                         return indexOf.call( checkContext, elem ) > -1;
2610                 }, implicitRelative, true ),
2611                 matchers = [ function( elem, context, xml ) {
2612                         return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2613                                 (checkContext = context).nodeType ?
2614                                         matchContext( elem, context, xml ) :
2615                                         matchAnyContext( elem, context, xml ) );
2616                 } ];
2617
2618         for ( ; i < len; i++ ) {
2619                 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2620                         matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2621                 } else {
2622                         matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2623
2624                         // Return special upon seeing a positional matcher
2625                         if ( matcher[ expando ] ) {
2626                                 // Find the next relative operator (if any) for proper handling
2627                                 j = ++i;
2628                                 for ( ; j < len; j++ ) {
2629                                         if ( Expr.relative[ tokens[j].type ] ) {
2630                                                 break;
2631                                         }
2632                                 }
2633                                 return setMatcher(
2634                                         i > 1 && elementMatcher( matchers ),
2635                                         i > 1 && toSelector(
2636                                                 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2637                                                 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2638                                         ).replace( rtrim, "$1" ),
2639                                         matcher,
2640                                         i < j && matcherFromTokens( tokens.slice( i, j ) ),
2641                                         j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2642                                         j < len && toSelector( tokens )
2643                                 );
2644                         }
2645                         matchers.push( matcher );
2646                 }
2647         }
2648
2649         return elementMatcher( matchers );
2650 }
2651
2652 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2653         var bySet = setMatchers.length > 0,
2654                 byElement = elementMatchers.length > 0,
2655                 superMatcher = function( seed, context, xml, results, outermost ) {
2656                         var elem, j, matcher,
2657                                 matchedCount = 0,
2658                                 i = "0",
2659                                 unmatched = seed && [],
2660                                 setMatched = [],
2661                                 contextBackup = outermostContext,
2662                                 // We must always have either seed elements or outermost context
2663                                 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2664                                 // Use integer dirruns iff this is the outermost matcher
2665                                 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2666                                 len = elems.length;
2667
2668                         if ( outermost ) {
2669                                 outermostContext = context !== document && context;
2670                         }
2671
2672                         // Add elements passing elementMatchers directly to results
2673                         // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2674                         // Support: IE<9, Safari
2675                         // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2676                         for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2677                                 if ( byElement && elem ) {
2678                                         j = 0;
2679                                         while ( (matcher = elementMatchers[j++]) ) {
2680                                                 if ( matcher( elem, context, xml ) ) {
2681                                                         results.push( elem );
2682                                                         break;
2683                                                 }
2684                                         }
2685                                         if ( outermost ) {
2686                                                 dirruns = dirrunsUnique;
2687                                         }
2688                                 }
2689
2690                                 // Track unmatched elements for set filters
2691                                 if ( bySet ) {
2692                                         // They will have gone through all possible matchers
2693                                         if ( (elem = !matcher && elem) ) {
2694                                                 matchedCount--;
2695                                         }
2696
2697                                         // Lengthen the array for every element, matched or not
2698                                         if ( seed ) {
2699                                                 unmatched.push( elem );
2700                                         }
2701                                 }
2702                         }
2703
2704                         // Apply set filters to unmatched elements
2705                         matchedCount += i;
2706                         if ( bySet && i !== matchedCount ) {
2707                                 j = 0;
2708                                 while ( (matcher = setMatchers[j++]) ) {
2709                                         matcher( unmatched, setMatched, context, xml );
2710                                 }
2711
2712                                 if ( seed ) {
2713                                         // Reintegrate element matches to eliminate the need for sorting
2714                                         if ( matchedCount > 0 ) {
2715                                                 while ( i-- ) {
2716                                                         if ( !(unmatched[i] || setMatched[i]) ) {
2717                                                                 setMatched[i] = pop.call( results );
2718                                                         }
2719                                                 }
2720                                         }
2721
2722                                         // Discard index placeholder values to get only actual matches
2723                                         setMatched = condense( setMatched );
2724                                 }
2725
2726                                 // Add matches to results
2727                                 push.apply( results, setMatched );
2728
2729                                 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2730                                 if ( outermost && !seed && setMatched.length > 0 &&
2731                                         ( matchedCount + setMatchers.length ) > 1 ) {
2732
2733                                         Sizzle.uniqueSort( results );
2734                                 }
2735                         }
2736
2737                         // Override manipulation of globals by nested matchers
2738                         if ( outermost ) {
2739                                 dirruns = dirrunsUnique;
2740                                 outermostContext = contextBackup;
2741                         }
2742
2743                         return unmatched;
2744                 };
2745
2746         return bySet ?
2747                 markFunction( superMatcher ) :
2748                 superMatcher;
2749 }
2750
2751 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2752         var i,
2753                 setMatchers = [],
2754                 elementMatchers = [],
2755                 cached = compilerCache[ selector + " " ];
2756
2757         if ( !cached ) {
2758                 // Generate a function of recursive functions that can be used to check each element
2759                 if ( !match ) {
2760                         match = tokenize( selector );
2761                 }
2762                 i = match.length;
2763                 while ( i-- ) {
2764                         cached = matcherFromTokens( match[i] );
2765                         if ( cached[ expando ] ) {
2766                                 setMatchers.push( cached );
2767                         } else {
2768                                 elementMatchers.push( cached );
2769                         }
2770                 }
2771
2772                 // Cache the compiled function
2773                 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2774
2775                 // Save selector and tokenization
2776                 cached.selector = selector;
2777         }
2778         return cached;
2779 };
2780
2781 /**
2782  * A low-level selection function that works with Sizzle's compiled
2783  *  selector functions
2784  * @param {String|Function} selector A selector or a pre-compiled
2785  *  selector function built with Sizzle.compile
2786  * @param {Element} context
2787  * @param {Array} [results]
2788  * @param {Array} [seed] A set of elements to match against
2789  */
2790 select = Sizzle.select = function( selector, context, results, seed ) {
2791         var i, tokens, token, type, find,
2792                 compiled = typeof selector === "function" && selector,
2793                 match = !seed && tokenize( (selector = compiled.selector || selector) );
2794
2795         results = results || [];
2796
2797         // Try to minimize operations if there is no seed and only one group
2798         if ( match.length === 1 ) {
2799
2800                 // Take a shortcut and set the context if the root selector is an ID
2801                 tokens = match[0] = match[0].slice( 0 );
2802                 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2803                                 support.getById && context.nodeType === 9 && documentIsHTML &&
2804                                 Expr.relative[ tokens[1].type ] ) {
2805
2806                         context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2807                         if ( !context ) {
2808                                 return results;
2809
2810                         // Precompiled matchers will still verify ancestry, so step up a level
2811                         } else if ( compiled ) {
2812                                 context = context.parentNode;
2813                         }
2814
2815                         selector = selector.slice( tokens.shift().value.length );
2816                 }
2817
2818                 // Fetch a seed set for right-to-left matching
2819                 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2820                 while ( i-- ) {
2821                         token = tokens[i];
2822
2823                         // Abort if we hit a combinator
2824                         if ( Expr.relative[ (type = token.type) ] ) {
2825                                 break;
2826                         }
2827                         if ( (find = Expr.find[ type ]) ) {
2828                                 // Search, expanding context for leading sibling combinators
2829                                 if ( (seed = find(
2830                                         token.matches[0].replace( runescape, funescape ),
2831                                         rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2832                                 )) ) {
2833
2834                                         // If seed is empty or no tokens remain, we can return early
2835                                         tokens.splice( i, 1 );
2836                                         selector = seed.length && toSelector( tokens );
2837                                         if ( !selector ) {
2838                                                 push.apply( results, seed );
2839                                                 return results;
2840                                         }
2841
2842                                         break;
2843                                 }
2844                         }
2845                 }
2846         }
2847
2848         // Compile and execute a filtering function if one is not provided
2849         // Provide `match` to avoid retokenization if we modified the selector above
2850         ( compiled || compile( selector, match ) )(
2851                 seed,
2852                 context,
2853                 !documentIsHTML,
2854                 results,
2855                 rsibling.test( selector ) && testContext( context.parentNode ) || context
2856         );
2857         return results;
2858 };
2859
2860 // One-time assignments
2861
2862 // Sort stability
2863 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2864
2865 // Support: Chrome<14
2866 // Always assume duplicates if they aren't passed to the comparison function
2867 support.detectDuplicates = !!hasDuplicate;
2868
2869 // Initialize against the default document
2870 setDocument();
2871
2872 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2873 // Detached nodes confoundingly follow *each other*
2874 support.sortDetached = assert(function( div1 ) {
2875         // Should return 1, but returns 4 (following)
2876         return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2877 });
2878
2879 // Support: IE<8
2880 // Prevent attribute/property "interpolation"
2881 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2882 if ( !assert(function( div ) {
2883         div.innerHTML = "<a href='#'></a>";
2884         return div.firstChild.getAttribute("href") === "#" ;
2885 }) ) {
2886         addHandle( "type|href|height|width", function( elem, name, isXML ) {
2887                 if ( !isXML ) {
2888                         return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2889                 }
2890         });
2891 }
2892
2893 // Support: IE<9
2894 // Use defaultValue in place of getAttribute("value")
2895 if ( !support.attributes || !assert(function( div ) {
2896         div.innerHTML = "<input/>";
2897         div.firstChild.setAttribute( "value", "" );
2898         return div.firstChild.getAttribute( "value" ) === "";
2899 }) ) {
2900         addHandle( "value", function( elem, name, isXML ) {
2901                 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2902                         return elem.defaultValue;
2903                 }
2904         });
2905 }
2906
2907 // Support: IE<9
2908 // Use getAttributeNode to fetch booleans when getAttribute lies
2909 if ( !assert(function( div ) {
2910         return div.getAttribute("disabled") == null;
2911 }) ) {
2912         addHandle( booleans, function( elem, name, isXML ) {
2913                 var val;
2914                 if ( !isXML ) {
2915                         return elem[ name ] === true ? name.toLowerCase() :
2916                                         (val = elem.getAttributeNode( name )) && val.specified ?
2917                                         val.value :
2918                                 null;
2919                 }
2920         });
2921 }
2922
2923 jQuery.find = Sizzle;
2924 jQuery.expr = Sizzle.selectors;
2925 jQuery.expr[":"] = jQuery.expr.pseudos;
2926 jQuery.unique = Sizzle.uniqueSort;
2927 jQuery.text = Sizzle.getText;
2928 jQuery.isXMLDoc = Sizzle.isXML;
2929 jQuery.contains = Sizzle.contains;
2930
2931
2932 })( window );
2933 // String to Object options format cache
2934 var optionsCache = {};
2935
2936 // Convert String-formatted options into Object-formatted ones and store in cache
2937 function createOptions( options ) {
2938         var object = optionsCache[ options ] = {};
2939         jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
2940                 object[ flag ] = true;
2941         });
2942         return object;
2943 }
2944
2945 /*
2946  * Create a callback list using the following parameters:
2947  *
2948  *      options: an optional list of space-separated options that will change how
2949  *                      the callback list behaves or a more traditional option object
2950  *
2951  * By default a callback list will act like an event callback list and can be
2952  * "fired" multiple times.
2953  *
2954  * Possible options:
2955  *
2956  *      once:                   will ensure the callback list can only be fired once (like a Deferred)
2957  *
2958  *      memory:                 will keep track of previous values and will call any callback added
2959  *                                      after the list has been fired right away with the latest "memorized"
2960  *                                      values (like a Deferred)
2961  *
2962  *      unique:                 will ensure a callback can only be added once (no duplicate in the list)
2963  *
2964  *      stopOnFalse:    interrupt callings when a callback returns false
2965  *
2966  */
2967 jQuery.Callbacks = function( options ) {
2968
2969         // Convert options from String-formatted to Object-formatted if needed
2970         // (we check in cache first)
2971         options = typeof options === "string" ?
2972                 ( optionsCache[ options ] || createOptions( options ) ) :
2973                 jQuery.extend( {}, options );
2974
2975         var // Last fire value (for non-forgettable lists)
2976                 memory,
2977                 // Flag to know if list was already fired
2978                 fired,
2979                 // Flag to know if list is currently firing
2980                 firing,
2981                 // First callback to fire (used internally by add and fireWith)
2982                 firingStart,
2983                 // End of the loop when firing
2984                 firingLength,
2985                 // Index of currently firing callback (modified by remove if needed)
2986                 firingIndex,
2987                 // Actual callback list
2988                 list = [],
2989                 // Stack of fire calls for repeatable lists
2990                 stack = !options.once && [],
2991                 // Fire callbacks
2992                 fire = function( data ) {
2993                         memory = options.memory && data;
2994                         fired = true;
2995                         firingIndex = firingStart || 0;
2996                         firingStart = 0;
2997                         firingLength = list.length;
2998                         firing = true;
2999                         for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3000                                 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3001                                         memory = false; // To prevent further calls using add
3002                                         break;
3003                                 }
3004                         }
3005                         firing = false;
3006                         if ( list ) {
3007                                 if ( stack ) {
3008                                         if ( stack.length ) {
3009                                                 fire( stack.shift() );
3010                                         }
3011                                 } else if ( memory ) {
3012                                         list = [];
3013                                 } else {
3014                                         self.disable();
3015                                 }
3016                         }
3017                 },
3018                 // Actual Callbacks object
3019                 self = {
3020                         // Add a callback or a collection of callbacks to the list
3021                         add: function() {
3022                                 if ( list ) {
3023                                         // First, we save the current length
3024                                         var start = list.length;
3025                                         (function add( args ) {
3026                                                 jQuery.each( args, function( _, arg ) {
3027                                                         var type = jQuery.type( arg );
3028                                                         if ( type === "function" ) {
3029                                                                 if ( !options.unique || !self.has( arg ) ) {
3030                                                                         list.push( arg );
3031                                                                 }
3032                                                         } else if ( arg && arg.length && type !== "string" ) {
3033                                                                 // Inspect recursively
3034                                                                 add( arg );
3035                                                         }
3036                                                 });
3037                                         })( arguments );
3038                                         // Do we need to add the callbacks to the
3039                                         // current firing batch?
3040                                         if ( firing ) {
3041                                                 firingLength = list.length;
3042                                         // With memory, if we're not firing then
3043                                         // we should call right away
3044                                         } else if ( memory ) {
3045                                                 firingStart = start;
3046                                                 fire( memory );
3047                                         }
3048                                 }
3049                                 return this;
3050                         },
3051                         // Remove a callback from the list
3052                         remove: function() {
3053                                 if ( list ) {
3054                                         jQuery.each( arguments, function( _, arg ) {
3055                                                 var index;
3056                                                 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3057                                                         list.splice( index, 1 );
3058                                                         // Handle firing indexes
3059                                                         if ( firing ) {
3060                                                                 if ( index <= firingLength ) {
3061                                                                         firingLength--;
3062                                                                 }
3063                                                                 if ( index <= firingIndex ) {
3064                                                                         firingIndex--;
3065                                                                 }
3066                                                         }
3067                                                 }
3068                                         });
3069                                 }
3070                                 return this;
3071                         },
3072                         // Check if a given callback is in the list.
3073                         // If no argument is given, return whether or not list has callbacks attached.
3074                         has: function( fn ) {
3075                                 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3076                         },
3077                         // Remove all callbacks from the list
3078                         empty: function() {
3079                                 list = [];
3080                                 firingLength = 0;
3081                                 return this;
3082                         },
3083                         // Have the list do nothing anymore
3084                         disable: function() {
3085                                 list = stack = memory = undefined;
3086                                 return this;
3087                         },
3088                         // Is it disabled?
3089                         disabled: function() {
3090                                 return !list;
3091                         },
3092                         // Lock the list in its current state
3093                         lock: function() {
3094                                 stack = undefined;
3095                                 if ( !memory ) {
3096                                         self.disable();
3097                                 }
3098                                 return this;
3099                         },
3100                         // Is it locked?
3101                         locked: function() {
3102                                 return !stack;
3103                         },
3104                         // Call all callbacks with the given context and arguments
3105                         fireWith: function( context, args ) {
3106                                 if ( list && ( !fired || stack ) ) {
3107                                         args = args || [];
3108                                         args = [ context, args.slice ? args.slice() : args ];
3109                                         if ( firing ) {
3110                                                 stack.push( args );
3111                                         } else {
3112                                                 fire( args );
3113                                         }
3114                                 }
3115                                 return this;
3116                         },
3117                         // Call all the callbacks with the given arguments
3118                         fire: function() {
3119                                 self.fireWith( this, arguments );
3120                                 return this;
3121                         },
3122                         // To know if the callbacks have already been called at least once
3123                         fired: function() {
3124                                 return !!fired;
3125                         }
3126                 };
3127
3128         return self;
3129 };
3130 jQuery.extend({
3131
3132         Deferred: function( func ) {
3133                 var tuples = [
3134                                 // action, add listener, listener list, final state
3135                                 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3136                                 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3137                                 [ "notify", "progress", jQuery.Callbacks("memory") ]
3138                         ],
3139                         state = "pending",
3140                         promise = {
3141                                 state: function() {
3142                                         return state;
3143                                 },
3144                                 always: function() {
3145                                         deferred.done( arguments ).fail( arguments );
3146                                         return this;
3147                                 },
3148                                 then: function( /* fnDone, fnFail, fnProgress */ ) {
3149                                         var fns = arguments;
3150                                         return jQuery.Deferred(function( newDefer ) {
3151                                                 jQuery.each( tuples, function( i, tuple ) {
3152                                                         var action = tuple[ 0 ],
3153                                                                 fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3154                                                         // deferred[ done | fail | progress ] for forwarding actions to newDefer
3155                                                         deferred[ tuple[1] ](function() {
3156                                                                 var returned = fn && fn.apply( this, arguments );
3157                                                                 if ( returned && jQuery.isFunction( returned.promise ) ) {
3158                                                                         returned.promise()
3159                                                                                 .done( newDefer.resolve )
3160                                                                                 .fail( newDefer.reject )
3161                                                                                 .progress( newDefer.notify );
3162                                                                 } else {
3163                                                                         newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3164                                                                 }
3165                                                         });
3166                                                 });
3167                                                 fns = null;
3168                                         }).promise();
3169                                 },
3170                                 // Get a promise for this deferred
3171                                 // If obj is provided, the promise aspect is added to the object
3172                                 promise: function( obj ) {
3173                                         return obj != null ? jQuery.extend( obj, promise ) : promise;
3174                                 }
3175                         },
3176                         deferred = {};
3177
3178                 // Keep pipe for back-compat
3179                 promise.pipe = promise.then;
3180
3181                 // Add list-specific methods
3182                 jQuery.each( tuples, function( i, tuple ) {
3183                         var list = tuple[ 2 ],
3184                                 stateString = tuple[ 3 ];
3185
3186                         // promise[ done | fail | progress ] = list.add
3187                         promise[ tuple[1] ] = list.add;
3188
3189                         // Handle state
3190                         if ( stateString ) {
3191                                 list.add(function() {
3192                                         // state = [ resolved | rejected ]
3193                                         state = stateString;
3194
3195                                 // [ reject_list | resolve_list ].disable; progress_list.lock
3196                                 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3197                         }
3198
3199                         // deferred[ resolve | reject | notify ]
3200                         deferred[ tuple[0] ] = function() {
3201                                 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3202                                 return this;
3203                         };
3204                         deferred[ tuple[0] + "With" ] = list.fireWith;
3205                 });
3206
3207                 // Make the deferred a promise
3208                 promise.promise( deferred );
3209
3210                 // Call given func if any
3211                 if ( func ) {
3212                         func.call( deferred, deferred );
3213                 }
3214
3215                 // All done!
3216                 return deferred;
3217         },
3218
3219         // Deferred helper
3220         when: function( subordinate /* , ..., subordinateN */ ) {
3221                 var i = 0,
3222                         resolveValues = core_slice.call( arguments ),
3223                         length = resolveValues.length,
3224
3225                         // the count of uncompleted subordinates
3226                         remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3227
3228                         // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3229                         deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3230
3231                         // Update function for both resolve and progress values
3232                         updateFunc = function( i, contexts, values ) {
3233                                 return function( value ) {
3234                                         contexts[ i ] = this;
3235                                         values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
3236                                         if( values === progressValues ) {
3237                                                 deferred.notifyWith( contexts, values );
3238                                         } else if ( !( --remaining ) ) {
3239                                                 deferred.resolveWith( contexts, values );
3240                                         }
3241                                 };
3242                         },
3243
3244                         progressValues, progressContexts, resolveContexts;
3245
3246                 // add listeners to Deferred subordinates; treat others as resolved
3247                 if ( length > 1 ) {
3248                         progressValues = new Array( length );
3249                         progressContexts = new Array( length );
3250                         resolveContexts = new Array( length );
3251                         for ( ; i < length; i++ ) {
3252                                 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3253                                         resolveValues[ i ].promise()
3254                                                 .done( updateFunc( i, resolveContexts, resolveValues ) )
3255                                                 .fail( deferred.reject )
3256                                                 .progress( updateFunc( i, progressContexts, progressValues ) );
3257                                 } else {
3258                                         --remaining;
3259                                 }
3260                         }
3261                 }
3262
3263                 // if we're not waiting on anything, resolve the master
3264                 if ( !remaining ) {
3265                         deferred.resolveWith( resolveContexts, resolveValues );
3266                 }
3267
3268                 return deferred.promise();
3269         }
3270 });
3271 jQuery.support = (function( support ) {
3272         var input = document.createElement("input"),
3273                 fragment = document.createDocumentFragment(),
3274                 div = document.createElement("div"),
3275                 select = document.createElement("select"),
3276                 opt = select.appendChild( document.createElement("option") );
3277
3278         // Finish early in limited environments
3279         if ( !input.type ) {
3280                 return support;
3281         }
3282
3283         input.type = "checkbox";
3284
3285         // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
3286         // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
3287         support.checkOn = input.value !== "";
3288
3289         // Must access the parent to make an option select properly
3290         // Support: IE9, IE10
3291         support.optSelected = opt.selected;
3292
3293         // Will be defined later
3294         support.reliableMarginRight = true;
3295         support.boxSizingReliable = true;
3296         support.pixelPosition = false;
3297
3298         // Make sure checked status is properly cloned
3299         // Support: IE9, IE10
3300         input.checked = true;
3301         support.noCloneChecked = input.cloneNode( true ).checked;
3302
3303         // Make sure that the options inside disabled selects aren't marked as disabled
3304         // (WebKit marks them as disabled)
3305         select.disabled = true;
3306         support.optDisabled = !opt.disabled;
3307
3308         // Check if an input maintains its value after becoming a radio
3309         // Support: IE9, IE10
3310         input = document.createElement("input");
3311         input.value = "t";
3312         input.type = "radio";
3313         support.radioValue = input.value === "t";
3314
3315         // #11217 - WebKit loses check when the name is after the checked attribute
3316         input.setAttribute( "checked", "t" );
3317         input.setAttribute( "name", "t" );
3318
3319         fragment.appendChild( input );
3320
3321         // Support: Safari 5.1, Android 4.x, Android 2.3
3322         // old WebKit doesn't clone checked state correctly in fragments
3323         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
3324
3325         // Support: Firefox, Chrome, Safari
3326         // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
3327         support.focusinBubbles = "onfocusin" in window;
3328
3329         div.style.backgroundClip = "content-box";
3330         div.cloneNode( true ).style.backgroundClip = "";
3331         support.clearCloneStyle = div.style.backgroundClip === "content-box";
3332
3333         // Run tests that need a body at doc ready
3334         jQuery(function() {
3335                 var container, marginDiv,
3336                         // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
3337                         divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",
3338                         body = document.getElementsByTagName("body")[ 0 ];
3339
3340                 if ( !body ) {
3341                         // Return for frameset docs that don't have a body
3342                         return;
3343                 }
3344
3345                 container = document.createElement("div");
3346                 container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
3347
3348                 // Check box-sizing and margin behavior.
3349                 body.appendChild( container ).appendChild( div );
3350                 div.innerHTML = "";
3351                 // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
3352                 div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%";
3353
3354                 // Workaround failing boxSizing test due to offsetWidth returning wrong value
3355                 // with some non-1 values of body zoom, ticket #13543
3356                 jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
3357                         support.boxSizing = div.offsetWidth === 4;
3358                 });
3359
3360                 // Use window.getComputedStyle because jsdom on node.js will break without it.
3361                 if ( window.getComputedStyle ) {
3362                         support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
3363                         support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
3364
3365                         // Support: Android 2.3
3366                         // Check if div with explicit width and no margin-right incorrectly
3367                         // gets computed margin-right based on width of container. (#3333)
3368                         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
3369                         marginDiv = div.appendChild( document.createElement("div") );
3370                         marginDiv.style.cssText = div.style.cssText = divReset;
3371                         marginDiv.style.marginRight = marginDiv.style.width = "0";
3372                         div.style.width = "1px";
3373
3374                         support.reliableMarginRight =
3375                                 !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
3376                 }
3377
3378                 body.removeChild( container );
3379         });
3380
3381         return support;
3382 })( {} );
3383
3384 /*
3385         Implementation Summary
3386
3387         1. Enforce API surface and semantic compatibility with 1.9.x branch
3388         2. Improve the module's maintainability by reducing the storage
3389                 paths to a single mechanism.
3390         3. Use the same single mechanism to support "private" and "user" data.
3391         4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3392         5. Avoid exposing implementation details on user objects (eg. expando properties)
3393         6. Provide a clear path for implementation upgrade to WeakMap in 2014
3394 */
3395 var data_user, data_priv,
3396         rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
3397         rmultiDash = /([A-Z])/g;
3398
3399 function Data() {
3400         // Support: Android < 4,
3401         // Old WebKit does not have Object.preventExtensions/freeze method,
3402         // return new empty object instead with no [[set]] accessor
3403         Object.defineProperty( this.cache = {}, 0, {
3404                 get: function() {
3405                         return {};
3406                 }
3407         });
3408
3409         this.expando = jQuery.expando + Math.random();
3410 }
3411
3412 Data.uid = 1;
3413
3414 Data.accepts = function( owner ) {
3415         // Accepts only:
3416         //  - Node
3417         //    - Node.ELEMENT_NODE
3418         //    - Node.DOCUMENT_NODE
3419         //  - Object
3420         //    - Any
3421         return owner.nodeType ?
3422                 owner.nodeType === 1 || owner.nodeType === 9 : true;
3423 };
3424
3425 Data.prototype = {
3426         key: function( owner ) {
3427                 // We can accept data for non-element nodes in modern browsers,
3428                 // but we should not, see #8335.
3429                 // Always return the key for a frozen object.
3430                 if ( !Data.accepts( owner ) ) {
3431                         return 0;
3432                 }
3433
3434                 var descriptor = {},
3435                         // Check if the owner object already has a cache key
3436                         unlock = owner[ this.expando ];
3437
3438                 // If not, create one
3439                 if ( !unlock ) {
3440                         unlock = Data.uid++;
3441
3442                         // Secure it in a non-enumerable, non-writable property
3443                         try {
3444                                 descriptor[ this.expando ] = { value: unlock };
3445                                 Object.defineProperties( owner, descriptor );
3446
3447                         // Support: Android < 4
3448                         // Fallback to a less secure definition
3449                         } catch ( e ) {
3450                                 descriptor[ this.expando ] = unlock;
3451                                 jQuery.extend( owner, descriptor );
3452                         }
3453                 }
3454
3455                 // Ensure the cache object
3456                 if ( !this.cache[ unlock ] ) {
3457                         this.cache[ unlock ] = {};
3458                 }
3459
3460                 return unlock;
3461         },
3462         set: function( owner, data, value ) {
3463                 var prop,
3464                         // There may be an unlock assigned to this node,
3465                         // if there is no entry for this "owner", create one inline
3466                         // and set the unlock as though an owner entry had always existed
3467                         unlock = this.key( owner ),
3468                         cache = this.cache[ unlock ];
3469
3470                 // Handle: [ owner, key, value ] args
3471                 if ( typeof data === "string" ) {
3472                         cache[ data ] = value;
3473
3474                 // Handle: [ owner, { properties } ] args
3475                 } else {
3476                         // Fresh assignments by object are shallow copied
3477                         if ( jQuery.isEmptyObject( cache ) ) {
3478                                 jQuery.extend( this.cache[ unlock ], data );
3479                         // Otherwise, copy the properties one-by-one to the cache object
3480                         } else {
3481                                 for ( prop in data ) {
3482                                         cache[ prop ] = data[ prop ];
3483                                 }
3484                         }
3485                 }
3486                 return cache;
3487         },
3488         get: function( owner, key ) {
3489                 // Either a valid cache is found, or will be created.
3490                 // New caches will be created and the unlock returned,
3491                 // allowing direct access to the newly created
3492                 // empty data object. A valid owner object must be provided.
3493                 var cache = this.cache[ this.key( owner ) ];
3494
3495                 return key === undefined ?
3496                         cache : cache[ key ];
3497         },
3498         access: function( owner, key, value ) {
3499                 var stored;
3500                 // In cases where either:
3501                 //
3502                 //   1. No key was specified
3503                 //   2. A string key was specified, but no value provided
3504                 //
3505                 // Take the "read" path and allow the get method to determine
3506                 // which value to return, respectively either:
3507                 //
3508                 //   1. The entire cache object
3509                 //   2. The data stored at the key
3510                 //
3511                 if ( key === undefined ||
3512                                 ((key && typeof key === "string") && value === undefined) ) {
3513
3514                         stored = this.get( owner, key );
3515
3516                         return stored !== undefined ?
3517                                 stored : this.get( owner, jQuery.camelCase(key) );
3518                 }
3519
3520                 // [*]When the key is not a string, or both a key and value
3521                 // are specified, set or extend (existing objects) with either:
3522                 //
3523                 //   1. An object of properties
3524                 //   2. A key and value
3525                 //
3526                 this.set( owner, key, value );
3527
3528                 // Since the "set" path can have two possible entry points
3529                 // return the expected data based on which path was taken[*]
3530                 return value !== undefined ? value : key;
3531         },
3532         remove: function( owner, key ) {
3533                 var i, name, camel,
3534                         unlock = this.key( owner ),
3535                         cache = this.cache[ unlock ];
3536
3537                 if ( key === undefined ) {
3538                         this.cache[ unlock ] = {};
3539
3540                 } else {
3541                         // Support array or space separated string of keys
3542                         if ( jQuery.isArray( key ) ) {
3543                                 // If "name" is an array of keys...
3544                                 // When data is initially created, via ("key", "val") signature,
3545                                 // keys will be converted to camelCase.
3546                                 // Since there is no way to tell _how_ a key was added, remove
3547                                 // both plain key and camelCase key. #12786
3548                                 // This will only penalize the array argument path.
3549                                 name = key.concat( key.map( jQuery.camelCase ) );
3550                         } else {
3551                                 camel = jQuery.camelCase( key );
3552                                 // Try the string as a key before any manipulation
3553                                 if ( key in cache ) {
3554                                         name = [ key, camel ];
3555                                 } else {
3556                                         // If a key with the spaces exists, use it.
3557                                         // Otherwise, create an array by matching non-whitespace
3558                                         name = camel;
3559                                         name = name in cache ?
3560                                                 [ name ] : ( name.match( core_rnotwhite ) || [] );
3561                                 }
3562                         }
3563
3564                         i = name.length;
3565                         while ( i-- ) {
3566                                 delete cache[ name[ i ] ];
3567                         }
3568                 }
3569         },
3570         hasData: function( owner ) {
3571                 return !jQuery.isEmptyObject(
3572                         this.cache[ owner[ this.expando ] ] || {}
3573                 );
3574         },
3575         discard: function( owner ) {
3576                 if ( owner[ this.expando ] ) {
3577                         delete this.cache[ owner[ this.expando ] ];
3578                 }
3579         }
3580 };
3581
3582 // These may be used throughout the jQuery core codebase
3583 data_user = new Data();
3584 data_priv = new Data();
3585
3586
3587 jQuery.extend({
3588         acceptData: Data.accepts,
3589
3590         hasData: function( elem ) {
3591                 return data_user.hasData( elem ) || data_priv.hasData( elem );
3592         },
3593
3594         data: function( elem, name, data ) {
3595                 return data_user.access( elem, name, data );
3596         },
3597
3598         removeData: function( elem, name ) {
3599                 data_user.remove( elem, name );
3600         },
3601
3602         // TODO: Now that all calls to _data and _removeData have been replaced
3603         // with direct calls to data_priv methods, these can be deprecated.
3604         _data: function( elem, name, data ) {
3605                 return data_priv.access( elem, name, data );
3606         },
3607
3608         _removeData: function( elem, name ) {
3609                 data_priv.remove( elem, name );
3610         }
3611 });
3612
3613 jQuery.fn.extend({
3614         data: function( key, value ) {
3615                 var attrs, name,
3616                         elem = this[ 0 ],
3617                         i = 0,
3618                         data = null;
3619
3620                 // Gets all values
3621                 if ( key === undefined ) {
3622                         if ( this.length ) {
3623                                 data = data_user.get( elem );
3624
3625                                 if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3626                                         attrs = elem.attributes;
3627                                         for ( ; i < attrs.length; i++ ) {
3628                                                 name = attrs[ i ].name;
3629
3630                                                 if ( name.indexOf( "data-" ) === 0 ) {
3631                                                         name = jQuery.camelCase( name.slice(5) );
3632                                                         dataAttr( elem, name, data[ name ] );
3633                                                 }
3634                                         }
3635                                         data_priv.set( elem, "hasDataAttrs", true );
3636                                 }
3637                         }
3638
3639                         return data;
3640                 }
3641
3642                 // Sets multiple values
3643                 if ( typeof key === "object" ) {
3644                         return this.each(function() {
3645                                 data_user.set( this, key );
3646                         });
3647                 }
3648
3649                 return jQuery.access( this, function( value ) {
3650                         var data,
3651                                 camelKey = jQuery.camelCase( key );
3652
3653                         // The calling jQuery object (element matches) is not empty
3654                         // (and therefore has an element appears at this[ 0 ]) and the
3655                         // `value` parameter was not undefined. An empty jQuery object
3656                         // will result in `undefined` for elem = this[ 0 ] which will
3657                         // throw an exception if an attempt to read a data cache is made.
3658                         if ( elem && value === undefined ) {
3659                                 // Attempt to get data from the cache
3660                                 // with the key as-is
3661                                 data = data_user.get( elem, key );
3662                                 if ( data !== undefined ) {
3663                                         return data;
3664                                 }
3665
3666                                 // Attempt to get data from the cache
3667                                 // with the key camelized
3668                                 data = data_user.get( elem, camelKey );
3669                                 if ( data !== undefined ) {
3670                                         return data;
3671                                 }
3672
3673                                 // Attempt to "discover" the data in
3674                                 // HTML5 custom data-* attrs
3675                                 data = dataAttr( elem, camelKey, undefined );
3676                                 if ( data !== undefined ) {
3677                                         return data;
3678                                 }
3679
3680                                 // We tried really hard, but the data doesn't exist.
3681                                 return;
3682                         }
3683
3684                         // Set the data...
3685                         this.each(function() {
3686                                 // First, attempt to store a copy or reference of any
3687                                 // data that might've been store with a camelCased key.
3688                                 var data = data_user.get( this, camelKey );
3689
3690                                 // For HTML5 data-* attribute interop, we have to
3691                                 // store property names with dashes in a camelCase form.
3692                                 // This might not apply to all properties...*
3693                                 data_user.set( this, camelKey, value );
3694
3695                                 // *... In the case of properties that might _actually_
3696                                 // have dashes, we need to also store a copy of that
3697                                 // unchanged property.
3698                                 if ( key.indexOf("-") !== -1 && data !== undefined ) {
3699                                         data_user.set( this, key, value );
3700                                 }
3701                         });
3702                 }, null, value, arguments.length > 1, null, true );
3703         },
3704
3705         removeData: function( key ) {
3706                 return this.each(function() {
3707                         data_user.remove( this, key );
3708                 });
3709         }
3710 });
3711
3712 function dataAttr( elem, key, data ) {
3713         var name;
3714
3715         // If nothing was found internally, try to fetch any
3716         // data from the HTML5 data-* attribute
3717         if ( data === undefined && elem.nodeType === 1 ) {
3718                 name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3719                 data = elem.getAttribute( name );
3720
3721                 if ( typeof data === "string" ) {
3722                         try {
3723                                 data = data === "true" ? true :
3724                                         data === "false" ? false :
3725                                         data === "null" ? null :
3726                                         // Only convert to a number if it doesn't change the string
3727                                         +data + "" === data ? +data :
3728                                         rbrace.test( data ) ? JSON.parse( data ) :
3729                                         data;
3730                         } catch( e ) {}
3731
3732                         // Make sure we set the data so it isn't changed later
3733                         data_user.set( elem, key, data );
3734                 } else {
3735                         data = undefined;
3736                 }
3737         }
3738         return data;
3739 }
3740 jQuery.extend({
3741         queue: function( elem, type, data ) {
3742                 var queue;
3743
3744                 if ( elem ) {
3745                         type = ( type || "fx" ) + "queue";
3746                         queue = data_priv.get( elem, type );
3747
3748                         // Speed up dequeue by getting out quickly if this is just a lookup
3749                         if ( data ) {
3750                                 if ( !queue || jQuery.isArray( data ) ) {
3751                                         queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3752                                 } else {
3753                                         queue.push( data );
3754                                 }
3755                         }
3756                         return queue || [];
3757                 }
3758         },
3759
3760         dequeue: function( elem, type ) {
3761                 type = type || "fx";
3762
3763                 var queue = jQuery.queue( elem, type ),
3764                         startLength = queue.length,
3765                         fn = queue.shift(),
3766                         hooks = jQuery._queueHooks( elem, type ),
3767                         next = function() {
3768                                 jQuery.dequeue( elem, type );
3769                         };
3770
3771                 // If the fx queue is dequeued, always remove the progress sentinel
3772                 if ( fn === "inprogress" ) {
3773                         fn = queue.shift();
3774                         startLength--;
3775                 }
3776
3777                 if ( fn ) {
3778
3779                         // Add a progress sentinel to prevent the fx queue from being
3780                         // automatically dequeued
3781                         if ( type === "fx" ) {
3782                                 queue.unshift( "inprogress" );
3783                         }
3784
3785                         // clear up the last queue stop function
3786                         delete hooks.stop;
3787                         fn.call( elem, next, hooks );
3788                 }
3789
3790                 if ( !startLength && hooks ) {
3791                         hooks.empty.fire();
3792                 }
3793         },
3794
3795         // not intended for public consumption - generates a queueHooks object, or returns the current one
3796         _queueHooks: function( elem, type ) {
3797                 var key = type + "queueHooks";
3798                 return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3799                         empty: jQuery.Callbacks("once memory").add(function() {
3800                                 data_priv.remove( elem, [ type + "queue", key ] );
3801                         })
3802                 });
3803         }
3804 });
3805
3806 jQuery.fn.extend({
3807         queue: function( type, data ) {
3808                 var setter = 2;
3809
3810                 if ( typeof type !== "string" ) {
3811                         data = type;
3812                         type = "fx";
3813                         setter--;
3814                 }
3815
3816                 if ( arguments.length < setter ) {
3817                         return jQuery.queue( this[0], type );
3818                 }
3819
3820                 return data === undefined ?
3821                         this :
3822                         this.each(function() {
3823                                 var queue = jQuery.queue( this, type, data );
3824
3825                                 // ensure a hooks for this queue
3826                                 jQuery._queueHooks( this, type );
3827
3828                                 if ( type === "fx" && queue[0] !== "inprogress" ) {
3829                                         jQuery.dequeue( this, type );
3830                                 }
3831                         });
3832         },
3833         dequeue: function( type ) {
3834                 return this.each(function() {
3835                         jQuery.dequeue( this, type );
3836                 });
3837         },
3838         // Based off of the plugin by Clint Helfers, with permission.
3839         // http://blindsignals.com/index.php/2009/07/jquery-delay/
3840         delay: function( time, type ) {
3841                 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
3842                 type = type || "fx";
3843
3844                 return this.queue( type, function( next, hooks ) {
3845                         var timeout = setTimeout( next, time );
3846                         hooks.stop = function() {
3847                                 clearTimeout( timeout );
3848                         };
3849                 });
3850         },
3851         clearQueue: function( type ) {
3852                 return this.queue( type || "fx", [] );
3853         },
3854         // Get a promise resolved when queues of a certain type
3855         // are emptied (fx is the type by default)
3856         promise: function( type, obj ) {
3857                 var tmp,
3858                         count = 1,
3859                         defer = jQuery.Deferred(),
3860                         elements = this,
3861                         i = this.length,
3862                         resolve = function() {
3863                                 if ( !( --count ) ) {
3864                                         defer.resolveWith( elements, [ elements ] );
3865                                 }
3866                         };
3867
3868                 if ( typeof type !== "string" ) {
3869                         obj = type;
3870                         type = undefined;
3871                 }
3872                 type = type || "fx";
3873
3874                 while( i-- ) {
3875                         tmp = data_priv.get( elements[ i ], type + "queueHooks" );
3876                         if ( tmp && tmp.empty ) {
3877                                 count++;
3878                                 tmp.empty.add( resolve );
3879                         }
3880                 }
3881                 resolve();
3882                 return defer.promise( obj );
3883         }
3884 });
3885 var nodeHook, boolHook,
3886         rclass = /[\t\r\n\f]/g,
3887         rreturn = /\r/g,
3888         rfocusable = /^(?:input|select|textarea|button)$/i;
3889
3890 jQuery.fn.extend({
3891         attr: function( name, value ) {
3892                 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
3893         },
3894
3895         removeAttr: function( name ) {
3896                 return this.each(function() {
3897                         jQuery.removeAttr( this, name );
3898                 });
3899         },
3900
3901         prop: function( name, value ) {
3902                 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
3903         },
3904
3905         removeProp: function( name ) {
3906                 return this.each(function() {
3907                         delete this[ jQuery.propFix[ name ] || name ];
3908                 });
3909         },
3910
3911         addClass: function( value ) {
3912                 var classes, elem, cur, clazz, j,
3913                         i = 0,
3914                         len = this.length,
3915                         proceed = typeof value === "string" && value;
3916
3917                 if ( jQuery.isFunction( value ) ) {
3918                         return this.each(function( j ) {
3919                                 jQuery( this ).addClass( value.call( this, j, this.className ) );
3920                         });
3921                 }
3922
3923                 if ( proceed ) {
3924                         // The disjunction here is for better compressibility (see removeClass)
3925                         classes = ( value || "" ).match( core_rnotwhite ) || [];
3926
3927                         for ( ; i < len; i++ ) {
3928                                 elem = this[ i ];
3929                                 cur = elem.nodeType === 1 && ( elem.className ?
3930                                         ( " " + elem.className + " " ).replace( rclass, " " ) :
3931                                         " "
3932                                 );
3933
3934                                 if ( cur ) {
3935                                         j = 0;
3936                                         while ( (clazz = classes[j++]) ) {
3937                                                 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
3938                                                         cur += clazz + " ";
3939                                                 }
3940                                         }
3941                                         elem.className = jQuery.trim( cur );
3942
3943                                 }
3944                         }
3945                 }
3946
3947                 return this;
3948         },
3949
3950         removeClass: function( value ) {
3951                 var classes, elem, cur, clazz, j,
3952                         i = 0,
3953                         len = this.length,
3954                         proceed = arguments.length === 0 || typeof value === "string" && value;
3955
3956                 if ( jQuery.isFunction( value ) ) {
3957                         return this.each(function( j ) {
3958                                 jQuery( this ).removeClass( value.call( this, j, this.className ) );
3959                         });
3960                 }
3961                 if ( proceed ) {
3962                         classes = ( value || "" ).match( core_rnotwhite ) || [];
3963
3964                         for ( ; i < len; i++ ) {
3965                                 elem = this[ i ];
3966                                 // This expression is here for better compressibility (see addClass)
3967                                 cur = elem.nodeType === 1 && ( elem.className ?
3968                                         ( " " + elem.className + " " ).replace( rclass, " " ) :
3969                                         ""
3970                                 );
3971
3972                                 if ( cur ) {
3973                                         j = 0;
3974                                         while ( (clazz = classes[j++]) ) {
3975                                                 // Remove *all* instances
3976                                                 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
3977                                                         cur = cur.replace( " " + clazz + " ", " " );
3978                                                 }
3979                                         }
3980                                         elem.className = value ? jQuery.trim( cur ) : "";
3981                                 }
3982                         }
3983                 }
3984
3985                 return this;
3986         },
3987
3988         toggleClass: function( value, stateVal ) {
3989                 var type = typeof value;
3990
3991                 if ( typeof stateVal === "boolean" && type === "string" ) {
3992                         return stateVal ? this.addClass( value ) : this.removeClass( value );
3993                 }
3994
3995                 if ( jQuery.isFunction( value ) ) {
3996                         return this.each(function( i ) {
3997                                 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
3998                         });
3999                 }
4000
4001                 return this.each(function() {
4002                         if ( type === "string" ) {
4003                                 // toggle individual class names
4004                                 var className,
4005                                         i = 0,
4006                                         self = jQuery( this ),
4007                                         classNames = value.match( core_rnotwhite ) || [];
4008
4009                                 while ( (className = classNames[ i++ ]) ) {
4010                                         // check each className given, space separated list
4011                                         if ( self.hasClass( className ) ) {
4012                                                 self.removeClass( className );
4013                                         } else {
4014                                                 self.addClass( className );
4015                                         }
4016                                 }
4017
4018                         // Toggle whole class name
4019                         } else if ( type === core_strundefined || type === "boolean" ) {
4020                                 if ( this.className ) {
4021                                         // store className if set
4022                                         data_priv.set( this, "__className__", this.className );
4023                                 }
4024
4025                                 // If the element has a class name or if we're passed "false",
4026                                 // then remove the whole classname (if there was one, the above saved it).
4027                                 // Otherwise bring back whatever was previously saved (if anything),
4028                                 // falling back to the empty string if nothing was stored.
4029                                 this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
4030                         }
4031                 });
4032         },
4033
4034         hasClass: function( selector ) {
4035                 var className = " " + selector + " ",
4036                         i = 0,
4037                         l = this.length;
4038                 for ( ; i < l; i++ ) {
4039                         if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
4040                                 return true;
4041                         }
4042                 }
4043
4044                 return false;
4045         },
4046
4047         val: function( value ) {
4048                 var hooks, ret, isFunction,
4049                         elem = this[0];
4050
4051                 if ( !arguments.length ) {
4052                         if ( elem ) {
4053                                 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
4054
4055                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
4056                                         return ret;
4057                                 }
4058
4059                                 ret = elem.value;
4060
4061                                 return typeof ret === "string" ?
4062                                         // handle most common string cases
4063                                         ret.replace(rreturn, "") :
4064                                         // handle cases where value is null/undef or number
4065                                         ret == null ? "" : ret;
4066                         }
4067
4068                         return;
4069                 }
4070
4071                 isFunction = jQuery.isFunction( value );
4072
4073                 return this.each(function( i ) {
4074                         var val;
4075
4076                         if ( this.nodeType !== 1 ) {
4077                                 return;
4078                         }
4079
4080                         if ( isFunction ) {
4081                                 val = value.call( this, i, jQuery( this ).val() );
4082                         } else {
4083                                 val = value;
4084                         }
4085
4086                         // Treat null/undefined as ""; convert numbers to string
4087                         if ( val == null ) {
4088                                 val = "";
4089                         } else if ( typeof val === "number" ) {
4090                                 val += "";
4091                         } else if ( jQuery.isArray( val ) ) {
4092                                 val = jQuery.map(val, function ( value ) {
4093                                         return value == null ? "" : value + "";
4094                                 });
4095                         }
4096
4097                         hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
4098
4099                         // If set returns undefined, fall back to normal setting
4100                         if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
4101                                 this.value = val;
4102                         }
4103                 });
4104         }
4105 });
4106
4107 jQuery.extend({
4108         valHooks: {
4109                 option: {
4110                         get: function( elem ) {
4111                                 // attributes.value is undefined in Blackberry 4.7 but
4112                                 // uses .value. See #6932
4113                                 var val = elem.attributes.value;
4114                                 return !val || val.specified ? elem.value : elem.text;
4115                         }
4116                 },
4117                 select: {
4118                         get: function( elem ) {
4119                                 var value, option,
4120                                         options = elem.options,
4121                                         index = elem.selectedIndex,
4122                                         one = elem.type === "select-one" || index < 0,
4123                                         values = one ? null : [],
4124                                         max = one ? index + 1 : options.length,
4125                                         i = index < 0 ?
4126                                                 max :
4127                                                 one ? index : 0;
4128
4129                                 // Loop through all the selected options
4130                                 for ( ; i < max; i++ ) {
4131                                         option = options[ i ];
4132
4133                                         // IE6-9 doesn't update selected after form reset (#2551)
4134                                         if ( ( option.selected || i === index ) &&
4135                                                         // Don't return options that are disabled or in a disabled optgroup
4136                                                         ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
4137                                                         ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
4138
4139                                                 // Get the specific value for the option
4140                                                 value = jQuery( option ).val();
4141
4142                                                 // We don't need an array for one selects
4143                                                 if ( one ) {
4144                                                         return value;
4145                                                 }
4146
4147                                                 // Multi-Selects return an array
4148                                                 values.push( value );
4149                                         }
4150                                 }
4151
4152                                 return values;
4153                         },
4154
4155                         set: function( elem, value ) {
4156                                 var optionSet, option,
4157                                         options = elem.options,
4158                                         values = jQuery.makeArray( value ),
4159                                         i = options.length;
4160
4161                                 while ( i-- ) {
4162                                         option = options[ i ];
4163                                         if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
4164                                                 optionSet = true;
4165                                         }
4166                                 }
4167
4168                                 // force browsers to behave consistently when non-matching value is set
4169                                 if ( !optionSet ) {
4170                                         elem.selectedIndex = -1;
4171                                 }
4172                                 return values;
4173                         }
4174                 }
4175         },
4176
4177         attr: function( elem, name, value ) {
4178                 var hooks, ret,
4179                         nType = elem.nodeType;
4180
4181                 // don't get/set attributes on text, comment and attribute nodes
4182                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
4183                         return;
4184                 }
4185
4186                 // Fallback to prop when attributes are not supported
4187                 if ( typeof elem.getAttribute === core_strundefined ) {
4188                         return jQuery.prop( elem, name, value );
4189                 }
4190
4191                 // All attributes are lowercase
4192                 // Grab necessary hook if one is defined
4193                 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
4194                         name = name.toLowerCase();
4195                         hooks = jQuery.attrHooks[ name ] ||
4196                                 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
4197                 }
4198
4199                 if ( value !== undefined ) {
4200
4201                         if ( value === null ) {
4202                                 jQuery.removeAttr( elem, name );
4203
4204                         } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
4205                                 return ret;
4206
4207                         } else {
4208                                 elem.setAttribute( name, value + "" );
4209                                 return value;
4210                         }
4211
4212                 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
4213                         return ret;
4214
4215                 } else {
4216                         ret = jQuery.find.attr( elem, name );
4217
4218                         // Non-existent attributes return null, we normalize to undefined
4219                         return ret == null ?
4220                                 undefined :
4221                                 ret;
4222                 }
4223         },
4224
4225         removeAttr: function( elem, value ) {
4226                 var name, propName,
4227                         i = 0,
4228                         attrNames = value && value.match( core_rnotwhite );
4229
4230                 if ( attrNames && elem.nodeType === 1 ) {
4231                         while ( (name = attrNames[i++]) ) {
4232                                 propName = jQuery.propFix[ name ] || name;
4233
4234                                 // Boolean attributes get special treatment (#10870)
4235                                 if ( jQuery.expr.match.bool.test( name ) ) {
4236                                         // Set corresponding property to false
4237                                         elem[ propName ] = false;
4238                                 }
4239
4240                                 elem.removeAttribute( name );
4241                         }
4242                 }
4243         },
4244
4245         attrHooks: {
4246                 type: {
4247                         set: function( elem, value ) {
4248                                 if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
4249                                         // Setting the type on a radio button after the value resets the value in IE6-9
4250                                         // Reset value to default in case type is set after value during creation
4251                                         var val = elem.value;
4252                                         elem.setAttribute( "type", value );
4253                                         if ( val ) {
4254                                                 elem.value = val;
4255                                         }
4256                                         return value;
4257                                 }
4258                         }
4259                 }
4260         },
4261
4262         propFix: {
4263                 "for": "htmlFor",
4264                 "class": "className"
4265         },
4266
4267         prop: function( elem, name, value ) {
4268                 var ret, hooks, notxml,
4269                         nType = elem.nodeType;
4270
4271                 // don't get/set properties on text, comment and attribute nodes
4272                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
4273                         return;
4274                 }
4275
4276                 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
4277
4278                 if ( notxml ) {
4279                         // Fix name and attach hooks
4280                         name = jQuery.propFix[ name ] || name;
4281                         hooks = jQuery.propHooks[ name ];
4282                 }
4283
4284                 if ( value !== undefined ) {
4285                         return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
4286                                 ret :
4287                                 ( elem[ name ] = value );
4288
4289                 } else {
4290                         return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
4291                                 ret :
4292                                 elem[ name ];
4293                 }
4294         },
4295
4296         propHooks: {
4297                 tabIndex: {
4298                         get: function( elem ) {
4299                                 return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
4300                                         elem.tabIndex :
4301                                         -1;
4302                         }
4303                 }
4304         }
4305 });
4306
4307 // Hooks for boolean attributes
4308 boolHook = {
4309         set: function( elem, value, name ) {
4310                 if ( value === false ) {
4311                         // Remove boolean attributes when set to false
4312                         jQuery.removeAttr( elem, name );
4313                 } else {
4314                         elem.setAttribute( name, name );
4315                 }
4316                 return name;
4317         }
4318 };
4319 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
4320         var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
4321
4322         jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
4323                 var fn = jQuery.expr.attrHandle[ name ],
4324                         ret = isXML ?
4325                                 undefined :
4326                                 /* jshint eqeqeq: false */
4327                                 // Temporarily disable this handler to check existence
4328                                 (jQuery.expr.attrHandle[ name ] = undefined) !=
4329                                         getter( elem, name, isXML ) ?
4330
4331                                         name.toLowerCase() :
4332                                         null;
4333
4334                 // Restore handler
4335                 jQuery.expr.attrHandle[ name ] = fn;
4336
4337                 return ret;
4338         };
4339 });
4340
4341 // Support: IE9+
4342 // Selectedness for an option in an optgroup can be inaccurate
4343 if ( !jQuery.support.optSelected ) {
4344         jQuery.propHooks.selected = {
4345                 get: function( elem ) {
4346                         var parent = elem.parentNode;
4347                         if ( parent && parent.parentNode ) {
4348                                 parent.parentNode.selectedIndex;
4349                         }
4350                         return null;
4351                 }
4352         };
4353 }
4354
4355 jQuery.each([
4356         "tabIndex",
4357         "readOnly",
4358         "maxLength",
4359         "cellSpacing",
4360         "cellPadding",
4361         "rowSpan",
4362         "colSpan",
4363         "useMap",
4364         "frameBorder",
4365         "contentEditable"
4366 ], function() {
4367         jQuery.propFix[ this.toLowerCase() ] = this;
4368 });
4369
4370 // Radios and checkboxes getter/setter
4371 jQuery.each([ "radio", "checkbox" ], function() {
4372         jQuery.valHooks[ this ] = {
4373                 set: function( elem, value ) {
4374                         if ( jQuery.isArray( value ) ) {
4375                                 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
4376                         }
4377                 }
4378         };
4379         if ( !jQuery.support.checkOn ) {
4380                 jQuery.valHooks[ this ].get = function( elem ) {
4381                         // Support: Webkit
4382                         // "" is returned instead of "on" if a value isn't specified
4383                         return elem.getAttribute("value") === null ? "on" : elem.value;
4384                 };
4385         }
4386 });
4387 var rkeyEvent = /^key/,
4388         rmouseEvent = /^(?:mouse|contextmenu)|click/,
4389         rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4390         rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4391
4392 function returnTrue() {
4393         return true;
4394 }
4395
4396 function returnFalse() {
4397         return false;
4398 }
4399
4400 function safeActiveElement() {
4401         try {
4402                 return document.activeElement;
4403         } catch ( err ) { }
4404 }
4405
4406 /*
4407  * Helper functions for managing events -- not part of the public interface.
4408  * Props to Dean Edwards' addEvent library for many of the ideas.
4409  */
4410 jQuery.event = {
4411
4412         global: {},
4413
4414         add: function( elem, types, handler, data, selector ) {
4415
4416                 var handleObjIn, eventHandle, tmp,
4417                         events, t, handleObj,
4418                         special, handlers, type, namespaces, origType,
4419                         elemData = data_priv.get( elem );
4420
4421                 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4422                 if ( !elemData ) {
4423                         return;
4424                 }
4425
4426                 // Caller can pass in an object of custom data in lieu of the handler
4427                 if ( handler.handler ) {
4428                         handleObjIn = handler;
4429                         handler = handleObjIn.handler;
4430                         selector = handleObjIn.selector;
4431                 }
4432
4433                 // Make sure that the handler has a unique ID, used to find/remove it later
4434                 if ( !handler.guid ) {
4435                         handler.guid = jQuery.guid++;
4436                 }
4437
4438                 // Init the element's event structure and main handler, if this is the first
4439                 if ( !(events = elemData.events) ) {
4440                         events = elemData.events = {};
4441                 }
4442                 if ( !(eventHandle = elemData.handle) ) {
4443                         eventHandle = elemData.handle = function( e ) {
4444                                 // Discard the second event of a jQuery.event.trigger() and
4445                                 // when an event is called after a page has unloaded
4446                                 return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
4447                                         jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4448                                         undefined;
4449                         };
4450                         // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
4451                         eventHandle.elem = elem;
4452                 }
4453
4454                 // Handle multiple events separated by a space
4455                 types = ( types || "" ).match( core_rnotwhite ) || [""];
4456                 t = types.length;
4457                 while ( t-- ) {
4458                         tmp = rtypenamespace.exec( types[t] ) || [];
4459                         type = origType = tmp[1];
4460                         namespaces = ( tmp[2] || "" ).split( "." ).sort();
4461
4462                         // There *must* be a type, no attaching namespace-only handlers
4463                         if ( !type ) {
4464                                 continue;
4465                         }
4466
4467                         // If event changes its type, use the special event handlers for the changed type
4468                         special = jQuery.event.special[ type ] || {};
4469
4470                         // If selector defined, determine special event api type, otherwise given type
4471                         type = ( selector ? special.delegateType : special.bindType ) || type;
4472
4473                         // Update special based on newly reset type
4474                         special = jQuery.event.special[ type ] || {};
4475
4476                         // handleObj is passed to all event handlers
4477                         handleObj = jQuery.extend({
4478                                 type: type,
4479                                 origType: origType,
4480                                 data: data,
4481                                 handler: handler,
4482                                 guid: handler.guid,
4483                                 selector: selector,
4484                                 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4485                                 namespace: namespaces.join(".")
4486                         }, handleObjIn );
4487
4488                         // Init the event handler queue if we're the first
4489                         if ( !(handlers = events[ type ]) ) {
4490                                 handlers = events[ type ] = [];
4491                                 handlers.delegateCount = 0;
4492
4493                                 // Only use addEventListener if the special events handler returns false
4494                                 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4495                                         if ( elem.addEventListener ) {
4496                                                 elem.addEventListener( type, eventHandle, false );
4497                                         }
4498                                 }
4499                         }
4500
4501                         if ( special.add ) {
4502                                 special.add.call( elem, handleObj );
4503
4504                                 if ( !handleObj.handler.guid ) {
4505                                         handleObj.handler.guid = handler.guid;
4506                                 }
4507                         }
4508
4509                         // Add to the element's handler list, delegates in front
4510                         if ( selector ) {
4511                                 handlers.splice( handlers.delegateCount++, 0, handleObj );
4512                         } else {
4513                                 handlers.push( handleObj );
4514                         }
4515
4516                         // Keep track of which events have ever been used, for event optimization
4517                         jQuery.event.global[ type ] = true;
4518                 }
4519
4520                 // Nullify elem to prevent memory leaks in IE
4521                 elem = null;
4522         },
4523
4524         // Detach an event or set of events from an element
4525         remove: function( elem, types, handler, selector, mappedTypes ) {
4526
4527                 var j, origCount, tmp,
4528                         events, t, handleObj,
4529                         special, handlers, type, namespaces, origType,
4530                         elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4531
4532                 if ( !elemData || !(events = elemData.events) ) {
4533                         return;
4534                 }
4535
4536                 // Once for each type.namespace in types; type may be omitted
4537                 types = ( types || "" ).match( core_rnotwhite ) || [""];
4538                 t = types.length;
4539                 while ( t-- ) {
4540                         tmp = rtypenamespace.exec( types[t] ) || [];
4541                         type = origType = tmp[1];
4542                         namespaces = ( tmp[2] || "" ).split( "." ).sort();
4543
4544                         // Unbind all events (on this namespace, if provided) for the element
4545                         if ( !type ) {
4546                                 for ( type in events ) {
4547                                         jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4548                                 }
4549                                 continue;
4550                         }
4551
4552                         special = jQuery.event.special[ type ] || {};
4553                         type = ( selector ? special.delegateType : special.bindType ) || type;
4554                         handlers = events[ type ] || [];
4555                         tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4556
4557                         // Remove matching events
4558                         origCount = j = handlers.length;
4559                         while ( j-- ) {
4560                                 handleObj = handlers[ j ];
4561
4562                                 if ( ( mappedTypes || origType === handleObj.origType ) &&
4563                                         ( !handler || handler.guid === handleObj.guid ) &&
4564                                         ( !tmp || tmp.test( handleObj.namespace ) ) &&
4565                                         ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4566                                         handlers.splice( j, 1 );
4567
4568                                         if ( handleObj.selector ) {
4569                                                 handlers.delegateCount--;
4570                                         }
4571                                         if ( special.remove ) {
4572                                                 special.remove.call( elem, handleObj );
4573                                         }
4574                                 }
4575                         }
4576
4577                         // Remove generic event handler if we removed something and no more handlers exist
4578                         // (avoids potential for endless recursion during removal of special event handlers)
4579                         if ( origCount && !handlers.length ) {
4580                                 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4581                                         jQuery.removeEvent( elem, type, elemData.handle );
4582                                 }
4583
4584                                 delete events[ type ];
4585                         }
4586                 }
4587
4588                 // Remove the expando if it's no longer used
4589                 if ( jQuery.isEmptyObject( events ) ) {
4590                         delete elemData.handle;
4591                         data_priv.remove( elem, "events" );
4592                 }
4593         },
4594
4595         trigger: function( event, data, elem, onlyHandlers ) {
4596
4597                 var i, cur, tmp, bubbleType, ontype, handle, special,
4598                         eventPath = [ elem || document ],
4599                         type = core_hasOwn.call( event, "type" ) ? event.type : event,
4600                         namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4601
4602                 cur = tmp = elem = elem || document;
4603
4604                 // Don't do events on text and comment nodes
4605                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4606                         return;
4607                 }
4608
4609                 // focus/blur morphs to focusin/out; ensure we're not firing them right now
4610                 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4611                         return;
4612                 }
4613
4614                 if ( type.indexOf(".") >= 0 ) {
4615                         // Namespaced trigger; create a regexp to match event type in handle()
4616                         namespaces = type.split(".");
4617                         type = namespaces.shift();
4618                         namespaces.sort();
4619                 }
4620                 ontype = type.indexOf(":") < 0 && "on" + type;
4621
4622                 // Caller can pass in a jQuery.Event object, Object, or just an event type string
4623                 event = event[ jQuery.expando ] ?
4624                         event :
4625                         new jQuery.Event( type, typeof event === "object" && event );
4626
4627                 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4628                 event.isTrigger = onlyHandlers ? 2 : 3;
4629                 event.namespace = namespaces.join(".");
4630                 event.namespace_re = event.namespace ?
4631                         new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4632                         null;
4633
4634                 // Clean up the event in case it is being reused
4635                 event.result = undefined;
4636                 if ( !event.target ) {
4637                         event.target = elem;
4638                 }
4639
4640                 // Clone any incoming data and prepend the event, creating the handler arg list
4641                 data = data == null ?
4642                         [ event ] :
4643                         jQuery.makeArray( data, [ event ] );
4644
4645                 // Allow special events to draw outside the lines
4646                 special = jQuery.event.special[ type ] || {};
4647                 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4648                         return;
4649                 }
4650
4651                 // Determine event propagation path in advance, per W3C events spec (#9951)
4652                 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4653                 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4654
4655                         bubbleType = special.delegateType || type;
4656                         if ( !rfocusMorph.test( bubbleType + type ) ) {
4657                                 cur = cur.parentNode;
4658                         }
4659                         for ( ; cur; cur = cur.parentNode ) {
4660                                 eventPath.push( cur );
4661                                 tmp = cur;
4662                         }
4663
4664                         // Only add window if we got to document (e.g., not plain obj or detached DOM)
4665                         if ( tmp === (elem.ownerDocument || document) ) {
4666                                 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4667                         }
4668                 }
4669
4670                 // Fire handlers on the event path
4671                 i = 0;
4672                 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4673
4674                         event.type = i > 1 ?
4675                                 bubbleType :
4676                                 special.bindType || type;
4677
4678                         // jQuery handler
4679                         handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4680                         if ( handle ) {
4681                                 handle.apply( cur, data );
4682                         }
4683
4684                         // Native handler
4685                         handle = ontype && cur[ ontype ];
4686                         if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
4687                                 event.preventDefault();
4688                         }
4689                 }
4690                 event.type = type;
4691
4692                 // If nobody prevented the default action, do it now
4693                 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4694
4695                         if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4696                                 jQuery.acceptData( elem ) ) {
4697
4698                                 // Call a native DOM method on the target with the same name name as the event.
4699                                 // Don't do default actions on window, that's where global variables be (#6170)
4700                                 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4701
4702                                         // Don't re-trigger an onFOO event when we call its FOO() method
4703                                         tmp = elem[ ontype ];
4704
4705                                         if ( tmp ) {
4706                                                 elem[ ontype ] = null;
4707                                         }
4708
4709                                         // Prevent re-triggering of the same event, since we already bubbled it above
4710                                         jQuery.event.triggered = type;
4711                                         elem[ type ]();
4712                                         jQuery.event.triggered = undefined;
4713
4714                                         if ( tmp ) {
4715                                                 elem[ ontype ] = tmp;
4716                                         }
4717                                 }
4718                         }
4719                 }
4720
4721                 return event.result;
4722         },
4723
4724         dispatch: function( event ) {
4725
4726                 // Make a writable jQuery.Event from the native event object
4727                 event = jQuery.event.fix( event );
4728
4729                 var i, j, ret, matched, handleObj,
4730                         handlerQueue = [],
4731                         args = core_slice.call( arguments ),
4732                         handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4733                         special = jQuery.event.special[ event.type ] || {};
4734
4735                 // Use the fix-ed jQuery.Event rather than the (read-only) native event
4736                 args[0] = event;
4737                 event.delegateTarget = this;
4738
4739                 // Call the preDispatch hook for the mapped type, and let it bail if desired
4740                 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4741                         return;
4742                 }
4743
4744                 // Determine handlers
4745                 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4746
4747                 // Run delegates first; they may want to stop propagation beneath us
4748                 i = 0;
4749                 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4750                         event.currentTarget = matched.elem;
4751
4752                         j = 0;
4753                         while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4754
4755                                 // Triggered event must either 1) have no namespace, or
4756                                 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4757                                 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4758
4759                                         event.handleObj = handleObj;
4760                                         event.data = handleObj.data;
4761
4762                                         ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4763                                                         .apply( matched.elem, args );
4764
4765                                         if ( ret !== undefined ) {
4766                                                 if ( (event.result = ret) === false ) {
4767                                                         event.preventDefault();
4768                                                         event.stopPropagation();
4769                                                 }
4770                                         }
4771                                 }
4772                         }
4773                 }
4774
4775                 // Call the postDispatch hook for the mapped type
4776                 if ( special.postDispatch ) {
4777                         special.postDispatch.call( this, event );
4778                 }
4779
4780                 return event.result;
4781         },
4782
4783         handlers: function( event, handlers ) {
4784                 var i, matches, sel, handleObj,
4785                         handlerQueue = [],
4786                         delegateCount = handlers.delegateCount,
4787                         cur = event.target;
4788
4789                 // Find delegate handlers
4790                 // Black-hole SVG <use> instance trees (#13180)
4791                 // Avoid non-left-click bubbling in Firefox (#3861)
4792                 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4793
4794                         for ( ; cur !== this; cur = cur.parentNode || this ) {
4795
4796                                 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4797                                 if ( cur.disabled !== true || event.type !== "click" ) {
4798                                         matches = [];
4799                                         for ( i = 0; i < delegateCount; i++ ) {
4800                                                 handleObj = handlers[ i ];
4801
4802                                                 // Don't conflict with Object.prototype properties (#13203)
4803                                                 sel = handleObj.selector + " ";
4804
4805                                                 if ( matches[ sel ] === undefined ) {
4806                                                         matches[ sel ] = handleObj.needsContext ?
4807                                                                 jQuery( sel, this ).index( cur ) >= 0 :
4808                                                                 jQuery.find( sel, this, null, [ cur ] ).length;
4809                                                 }
4810                                                 if ( matches[ sel ] ) {
4811                                                         matches.push( handleObj );
4812                                                 }
4813                                         }
4814                                         if ( matches.length ) {
4815                                                 handlerQueue.push({ elem: cur, handlers: matches });
4816                                         }
4817                                 }
4818                         }
4819                 }
4820
4821                 // Add the remaining (directly-bound) handlers
4822                 if ( delegateCount < handlers.length ) {
4823                         handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4824                 }
4825
4826                 return handlerQueue;
4827         },
4828
4829         // Includes some event props shared by KeyEvent and MouseEvent
4830         props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4831
4832         fixHooks: {},
4833
4834         keyHooks: {
4835                 props: "char charCode key keyCode".split(" "),
4836                 filter: function( event, original ) {
4837
4838                         // Add which for key events
4839                         if ( event.which == null ) {
4840                                 event.which = original.charCode != null ? original.charCode : original.keyCode;
4841                         }
4842
4843                         return event;
4844                 }
4845         },
4846
4847         mouseHooks: {
4848                 props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4849                 filter: function( event, original ) {
4850                         var eventDoc, doc, body,
4851                                 button = original.button;
4852
4853                         // Calculate pageX/Y if missing and clientX/Y available
4854                         if ( event.pageX == null && original.clientX != null ) {
4855                                 eventDoc = event.target.ownerDocument || document;
4856                                 doc = eventDoc.documentElement;
4857                                 body = eventDoc.body;
4858
4859                                 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4860                                 event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
4861                         }
4862
4863                         // Add which for click: 1 === left; 2 === middle; 3 === right
4864                         // Note: button is not normalized, so don't use it
4865                         if ( !event.which && button !== undefined ) {
4866                                 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4867                         }
4868
4869                         return event;
4870                 }
4871         },
4872
4873         fix: function( event ) {
4874                 if ( event[ jQuery.expando ] ) {
4875                         return event;
4876                 }
4877
4878                 // Create a writable copy of the event object and normalize some properties
4879                 var i, prop, copy,
4880                         type = event.type,
4881                         originalEvent = event,
4882                         fixHook = this.fixHooks[ type ];
4883
4884                 if ( !fixHook ) {
4885                         this.fixHooks[ type ] = fixHook =
4886                                 rmouseEvent.test( type ) ? this.mouseHooks :
4887                                 rkeyEvent.test( type ) ? this.keyHooks :
4888                                 {};
4889                 }
4890                 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4891
4892                 event = new jQuery.Event( originalEvent );
4893
4894                 i = copy.length;
4895                 while ( i-- ) {
4896                         prop = copy[ i ];
4897                         event[ prop ] = originalEvent[ prop ];
4898                 }
4899
4900                 // Support: Cordova 2.5 (WebKit) (#13255)
4901                 // All events should have a target; Cordova deviceready doesn't
4902                 if ( !event.target ) {
4903                         event.target = document;
4904                 }
4905
4906                 // Support: Safari 6.0+, Chrome < 28
4907                 // Target should not be a text node (#504, #13143)
4908                 if ( event.target.nodeType === 3 ) {
4909                         event.target = event.target.parentNode;
4910                 }
4911
4912                 return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
4913         },
4914
4915         special: {
4916                 load: {
4917                         // Prevent triggered image.load events from bubbling to window.load
4918                         noBubble: true
4919                 },
4920                 focus: {
4921                         // Fire native event if possible so blur/focus sequence is correct
4922                         trigger: function() {
4923                                 if ( this !== safeActiveElement() && this.focus ) {
4924                                         this.focus();
4925                                         return false;
4926                                 }
4927                         },
4928                         delegateType: "focusin"
4929                 },
4930                 blur: {
4931                         trigger: function() {
4932                                 if ( this === safeActiveElement() && this.blur ) {
4933                                         this.blur();
4934                                         return false;
4935                                 }
4936                         },
4937                         delegateType: "focusout"
4938                 },
4939                 click: {
4940                         // For checkbox, fire native event so checked state will be right
4941                         trigger: function() {
4942                                 if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4943                                         this.click();
4944                                         return false;
4945                                 }
4946                         },
4947
4948                         // For cross-browser consistency, don't fire native .click() on links
4949                         _default: function( event ) {
4950                                 return jQuery.nodeName( event.target, "a" );
4951                         }
4952                 },
4953
4954                 beforeunload: {
4955                         postDispatch: function( event ) {
4956
4957                                 // Support: Firefox 20+
4958                                 // Firefox doesn't alert if the returnValue field is not set.
4959                                 if ( event.result !== undefined ) {
4960                                         event.originalEvent.returnValue = event.result;
4961                                 }
4962                         }
4963                 }
4964         },
4965
4966         simulate: function( type, elem, event, bubble ) {
4967                 // Piggyback on a donor event to simulate a different one.
4968                 // Fake originalEvent to avoid donor's stopPropagation, but if the
4969                 // simulated event prevents default then we do the same on the donor.
4970                 var e = jQuery.extend(
4971                         new jQuery.Event(),
4972                         event,
4973                         {
4974                                 type: type,
4975                                 isSimulated: true,
4976                                 originalEvent: {}
4977                         }
4978                 );
4979                 if ( bubble ) {
4980                         jQuery.event.trigger( e, null, elem );
4981                 } else {
4982                         jQuery.event.dispatch.call( elem, e );
4983                 }
4984                 if ( e.isDefaultPrevented() ) {
4985                         event.preventDefault();
4986                 }
4987         }
4988 };
4989
4990 jQuery.removeEvent = function( elem, type, handle ) {
4991         if ( elem.removeEventListener ) {
4992                 elem.removeEventListener( type, handle, false );
4993         }
4994 };
4995
4996 jQuery.Event = function( src, props ) {
4997         // Allow instantiation without the 'new' keyword
4998         if ( !(this instanceof jQuery.Event) ) {
4999                 return new jQuery.Event( src, props );
5000         }
5001
5002         // Event object
5003         if ( src && src.type ) {
5004                 this.originalEvent = src;
5005                 this.type = src.type;
5006
5007                 // Events bubbling up the document may have been marked as prevented
5008                 // by a handler lower down the tree; reflect the correct value.
5009                 this.isDefaultPrevented = ( src.defaultPrevented ||
5010                         src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
5011
5012         // Event type
5013         } else {
5014                 this.type = src;
5015         }
5016
5017         // Put explicitly provided properties onto the event object
5018         if ( props ) {
5019                 jQuery.extend( this, props );
5020         }
5021
5022         // Create a timestamp if incoming event doesn't have one
5023         this.timeStamp = src && src.timeStamp || jQuery.now();
5024
5025         // Mark it as fixed
5026         this[ jQuery.expando ] = true;
5027 };
5028
5029 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5030 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5031 jQuery.Event.prototype = {
5032         isDefaultPrevented: returnFalse,
5033         isPropagationStopped: returnFalse,
5034         isImmediatePropagationStopped: returnFalse,
5035
5036         preventDefault: function() {
5037                 var e = this.originalEvent;
5038
5039                 this.isDefaultPrevented = returnTrue;
5040
5041                 if ( e && e.preventDefault ) {
5042                         e.preventDefault();
5043                 }
5044         },
5045         stopPropagation: function() {
5046                 var e = this.originalEvent;
5047
5048                 this.isPropagationStopped = returnTrue;
5049
5050                 if ( e && e.stopPropagation ) {
5051                         e.stopPropagation();
5052                 }
5053         },
5054         stopImmediatePropagation: function() {
5055                 this.isImmediatePropagationStopped = returnTrue;
5056                 this.stopPropagation();
5057         }
5058 };
5059
5060 // Create mouseenter/leave events using mouseover/out and event-time checks
5061 // Support: Chrome 15+
5062 jQuery.each({
5063         mouseenter: "mouseover",
5064         mouseleave: "mouseout"
5065 }, function( orig, fix ) {
5066         jQuery.event.special[ orig ] = {
5067                 delegateType: fix,
5068                 bindType: fix,
5069
5070                 handle: function( event ) {
5071                         var ret,
5072                                 target = this,
5073                                 related = event.relatedTarget,
5074                                 handleObj = event.handleObj;
5075
5076                         // For mousenter/leave call the handler if related is outside the target.
5077                         // NB: No relatedTarget if the mouse left/entered the browser window
5078                         if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
5079                                 event.type = handleObj.origType;
5080                                 ret = handleObj.handler.apply( this, arguments );
5081                                 event.type = fix;
5082                         }
5083                         return ret;
5084                 }
5085         };
5086 });
5087
5088 // Create "bubbling" focus and blur events
5089 // Support: Firefox, Chrome, Safari
5090 if ( !jQuery.support.focusinBubbles ) {
5091         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5092
5093                 // Attach a single capturing handler while someone wants focusin/focusout
5094                 var attaches = 0,
5095                         handler = function( event ) {
5096                                 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
5097                         };
5098
5099                 jQuery.event.special[ fix ] = {
5100                         setup: function() {
5101                                 if ( attaches++ === 0 ) {
5102                                         document.addEventListener( orig, handler, true );
5103                                 }
5104                         },
5105                         teardown: function() {
5106                                 if ( --attaches === 0 ) {
5107                                         document.removeEventListener( orig, handler, true );
5108                                 }
5109                         }
5110                 };
5111         });
5112 }
5113
5114 jQuery.fn.extend({
5115
5116         on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
5117                 var origFn, type;
5118
5119                 // Types can be a map of types/handlers
5120                 if ( typeof types === "object" ) {
5121                         // ( types-Object, selector, data )
5122                         if ( typeof selector !== "string" ) {
5123                                 // ( types-Object, data )
5124                                 data = data || selector;
5125                                 selector = undefined;
5126                         }
5127                         for ( type in types ) {
5128                                 this.on( type, selector, data, types[ type ], one );
5129                         }
5130                         return this;
5131                 }
5132
5133                 if ( data == null && fn == null ) {
5134                         // ( types, fn )
5135                         fn = selector;
5136                         data = selector = undefined;
5137                 } else if ( fn == null ) {
5138                         if ( typeof selector === "string" ) {
5139                                 // ( types, selector, fn )
5140                                 fn = data;
5141                                 data = undefined;
5142                         } else {
5143                                 // ( types, data, fn )
5144                                 fn = data;
5145                                 data = selector;
5146                                 selector = undefined;
5147                         }
5148                 }
5149                 if ( fn === false ) {
5150                         fn = returnFalse;
5151                 } else if ( !fn ) {
5152                         return this;
5153                 }
5154
5155                 if ( one === 1 ) {
5156                         origFn = fn;
5157                         fn = function( event ) {
5158                                 // Can use an empty set, since event contains the info
5159                                 jQuery().off( event );
5160                                 return origFn.apply( this, arguments );
5161                         };
5162                         // Use same guid so caller can remove using origFn
5163                         fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5164                 }
5165                 return this.each( function() {
5166                         jQuery.event.add( this, types, fn, data, selector );
5167                 });
5168         },
5169         one: function( types, selector, data, fn ) {
5170                 return this.on( types, selector, data, fn, 1 );
5171         },
5172         off: function( types, selector, fn ) {
5173                 var handleObj, type;
5174                 if ( types && types.preventDefault && types.handleObj ) {
5175                         // ( event )  dispatched jQuery.Event
5176                         handleObj = types.handleObj;
5177                         jQuery( types.delegateTarget ).off(
5178                                 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
5179                                 handleObj.selector,
5180                                 handleObj.handler
5181                         );
5182                         return this;
5183                 }
5184                 if ( typeof types === "object" ) {
5185                         // ( types-object [, selector] )
5186                         for ( type in types ) {
5187                                 this.off( type, selector, types[ type ] );
5188                         }
5189                         return this;
5190                 }
5191                 if ( selector === false || typeof selector === "function" ) {
5192                         // ( types [, fn] )
5193                         fn = selector;
5194                         selector = undefined;
5195                 }
5196                 if ( fn === false ) {
5197                         fn = returnFalse;
5198                 }
5199                 return this.each(function() {
5200                         jQuery.event.remove( this, types, fn, selector );
5201                 });
5202         },
5203
5204         trigger: function( type, data ) {
5205                 return this.each(function() {
5206                         jQuery.event.trigger( type, data, this );
5207                 });
5208         },
5209         triggerHandler: function( type, data ) {
5210                 var elem = this[0];
5211                 if ( elem ) {
5212                         return jQuery.event.trigger( type, data, elem, true );
5213                 }
5214         }
5215 });
5216 var isSimple = /^.[^:#\[\.,]*$/,
5217         rparentsprev = /^(?:parents|prev(?:Until|All))/,
5218         rneedsContext = jQuery.expr.match.needsContext,
5219         // methods guaranteed to produce a unique set when starting from a unique set
5220         guaranteedUnique = {
5221                 children: true,
5222                 contents: true,
5223                 next: true,
5224                 prev: true
5225         };
5226
5227 jQuery.fn.extend({
5228         find: function( selector ) {
5229                 var i,
5230                         ret = [],
5231                         self = this,
5232                         len = self.length;
5233
5234                 if ( typeof selector !== "string" ) {
5235                         return this.pushStack( jQuery( selector ).filter(function() {
5236                                 for ( i = 0; i < len; i++ ) {
5237                                         if ( jQuery.contains( self[ i ], this ) ) {
5238                                                 return true;
5239                                         }
5240                                 }
5241                         }) );
5242                 }
5243
5244                 for ( i = 0; i < len; i++ ) {
5245                         jQuery.find( selector, self[ i ], ret );
5246                 }
5247
5248                 // Needed because $( selector, context ) becomes $( context ).find( selector )
5249                 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
5250                 ret.selector = this.selector ? this.selector + " " + selector : selector;
5251                 return ret;
5252         },
5253
5254         has: function( target ) {
5255                 var targets = jQuery( target, this ),
5256                         l = targets.length;
5257
5258                 return this.filter(function() {
5259                         var i = 0;
5260                         for ( ; i < l; i++ ) {
5261                                 if ( jQuery.contains( this, targets[i] ) ) {
5262                                         return true;
5263                                 }
5264                         }
5265                 });
5266         },
5267
5268         not: function( selector ) {
5269                 return this.pushStack( winnow(this, selector || [], true) );
5270         },
5271
5272         filter: function( selector ) {
5273                 return this.pushStack( winnow(this, selector || [], false) );
5274         },
5275
5276         is: function( selector ) {
5277                 return !!winnow(
5278                         this,
5279
5280                         // If this is a positional/relative selector, check membership in the returned set
5281                         // so $("p:first").is("p:last") won't return true for a doc with two "p".
5282                         typeof selector === "string" && rneedsContext.test( selector ) ?
5283                                 jQuery( selector ) :
5284                                 selector || [],
5285                         false
5286                 ).length;
5287         },
5288
5289         closest: function( selectors, context ) {
5290                 var cur,
5291                         i = 0,
5292                         l = this.length,
5293                         matched = [],
5294                         pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
5295                                 jQuery( selectors, context || this.context ) :
5296                                 0;
5297
5298                 for ( ; i < l; i++ ) {
5299                         for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
5300                                 // Always skip document fragments
5301                                 if ( cur.nodeType < 11 && (pos ?
5302                                         pos.index(cur) > -1 :
5303
5304                                         // Don't pass non-elements to Sizzle
5305                                         cur.nodeType === 1 &&
5306                                                 jQuery.find.matchesSelector(cur, selectors)) ) {
5307
5308                                         cur = matched.push( cur );
5309                                         break;
5310                                 }
5311                         }
5312                 }
5313
5314                 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
5315         },
5316
5317         // Determine the position of an element within
5318         // the matched set of elements
5319         index: function( elem ) {
5320
5321                 // No argument, return index in parent
5322                 if ( !elem ) {
5323                         return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
5324                 }
5325
5326                 // index in selector
5327                 if ( typeof elem === "string" ) {
5328                         return core_indexOf.call( jQuery( elem ), this[ 0 ] );
5329                 }
5330
5331                 // Locate the position of the desired element
5332                 return core_indexOf.call( this,
5333
5334                         // If it receives a jQuery object, the first element is used
5335                         elem.jquery ? elem[ 0 ] : elem
5336                 );
5337         },
5338
5339         add: function( selector, context ) {
5340                 var set = typeof selector === "string" ?
5341                                 jQuery( selector, context ) :
5342                                 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5343                         all = jQuery.merge( this.get(), set );
5344
5345                 return this.pushStack( jQuery.unique(all) );
5346         },
5347
5348         addBack: function( selector ) {
5349                 return this.add( selector == null ?
5350                         this.prevObject : this.prevObject.filter(selector)
5351                 );
5352         }
5353 });
5354
5355 function sibling( cur, dir ) {
5356         while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
5357
5358         return cur;
5359 }
5360
5361 jQuery.each({
5362         parent: function( elem ) {
5363                 var parent = elem.parentNode;
5364                 return parent && parent.nodeType !== 11 ? parent : null;
5365         },
5366         parents: function( elem ) {
5367                 return jQuery.dir( elem, "parentNode" );
5368         },
5369         parentsUntil: function( elem, i, until ) {
5370                 return jQuery.dir( elem, "parentNode", until );
5371         },
5372         next: function( elem ) {
5373                 return sibling( elem, "nextSibling" );
5374         },
5375         prev: function( elem ) {
5376                 return sibling( elem, "previousSibling" );
5377         },
5378         nextAll: function( elem ) {
5379                 return jQuery.dir( elem, "nextSibling" );
5380         },
5381         prevAll: function( elem ) {
5382                 return jQuery.dir( elem, "previousSibling" );
5383         },
5384         nextUntil: function( elem, i, until ) {
5385                 return jQuery.dir( elem, "nextSibling", until );
5386         },
5387         prevUntil: function( elem, i, until ) {
5388                 return jQuery.dir( elem, "previousSibling", until );
5389         },
5390         siblings: function( elem ) {
5391                 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5392         },
5393         children: function( elem ) {
5394                 return jQuery.sibling( elem.firstChild );
5395         },
5396         contents: function( elem ) {
5397                 return elem.contentDocument || jQuery.merge( [], elem.childNodes );
5398         }
5399 }, function( name, fn ) {
5400         jQuery.fn[ name ] = function( until, selector ) {
5401                 var matched = jQuery.map( this, fn, until );
5402
5403                 if ( name.slice( -5 ) !== "Until" ) {
5404                         selector = until;
5405                 }
5406
5407                 if ( selector && typeof selector === "string" ) {
5408                         matched = jQuery.filter( selector, matched );
5409                 }
5410
5411                 if ( this.length > 1 ) {
5412                         // Remove duplicates
5413                         if ( !guaranteedUnique[ name ] ) {
5414                                 jQuery.unique( matched );
5415                         }
5416
5417                         // Reverse order for parents* and prev-derivatives
5418                         if ( rparentsprev.test( name ) ) {
5419                                 matched.reverse();
5420                         }
5421                 }
5422
5423                 return this.pushStack( matched );
5424         };
5425 });
5426
5427 jQuery.extend({
5428         filter: function( expr, elems, not ) {
5429                 var elem = elems[ 0 ];
5430
5431                 if ( not ) {
5432                         expr = ":not(" + expr + ")";
5433                 }
5434
5435                 return elems.length === 1 && elem.nodeType === 1 ?
5436                         jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
5437                         jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
5438                                 return elem.nodeType === 1;
5439                         }));
5440         },
5441
5442         dir: function( elem, dir, until ) {
5443                 var matched = [],
5444                         truncate = until !== undefined;
5445
5446                 while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
5447                         if ( elem.nodeType === 1 ) {
5448                                 if ( truncate && jQuery( elem ).is( until ) ) {
5449                                         break;
5450                                 }
5451                                 matched.push( elem );
5452                         }
5453                 }
5454                 return matched;
5455         },
5456
5457         sibling: function( n, elem ) {
5458                 var matched = [];
5459
5460                 for ( ; n; n = n.nextSibling ) {
5461                         if ( n.nodeType === 1 && n !== elem ) {
5462                                 matched.push( n );
5463                         }
5464                 }
5465
5466                 return matched;
5467         }
5468 });
5469
5470 // Implement the identical functionality for filter and not
5471 function winnow( elements, qualifier, not ) {
5472         if ( jQuery.isFunction( qualifier ) ) {
5473                 return jQuery.grep( elements, function( elem, i ) {
5474                         /* jshint -W018 */
5475                         return !!qualifier.call( elem, i, elem ) !== not;
5476                 });
5477
5478         }
5479
5480         if ( qualifier.nodeType ) {
5481                 return jQuery.grep( elements, function( elem ) {
5482                         return ( elem === qualifier ) !== not;
5483                 });
5484
5485         }
5486
5487         if ( typeof qualifier === "string" ) {
5488                 if ( isSimple.test( qualifier ) ) {
5489                         return jQuery.filter( qualifier, elements, not );
5490                 }
5491
5492                 qualifier = jQuery.filter( qualifier, elements );
5493         }
5494
5495         return jQuery.grep( elements, function( elem ) {
5496                 return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not;
5497         });
5498 }
5499 var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5500         rtagName = /<([\w:]+)/,
5501         rhtml = /<|&#?\w+;/,
5502         rnoInnerhtml = /<(?:script|style|link)/i,
5503         manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
5504         // checked="checked" or checked
5505         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5506         rscriptType = /^$|\/(?:java|ecma)script/i,
5507         rscriptTypeMasked = /^true\/(.*)/,
5508         rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5509
5510         // We have to close these tags to support XHTML (#13200)
5511         wrapMap = {
5512
5513                 // Support: IE 9
5514                 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5515
5516                 thead: [ 1, "<table>", "</table>" ],
5517                 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
5518                 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5519                 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5520
5521                 _default: [ 0, "", "" ]
5522         };
5523
5524 // Support: IE 9
5525 wrapMap.optgroup = wrapMap.option;
5526
5527 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5528 wrapMap.th = wrapMap.td;
5529
5530 jQuery.fn.extend({
5531         text: function( value ) {
5532                 return jQuery.access( this, function( value ) {
5533                         return value === undefined ?
5534                                 jQuery.text( this ) :
5535                                 this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
5536                 }, null, value, arguments.length );
5537         },
5538
5539         append: function() {
5540                 return this.domManip( arguments, function( elem ) {
5541                         if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5542                                 var target = manipulationTarget( this, elem );
5543                                 target.appendChild( elem );
5544                         }
5545                 });
5546         },
5547
5548         prepend: function() {
5549                 return this.domManip( arguments, function( elem ) {
5550                         if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5551                                 var target = manipulationTarget( this, elem );
5552                                 target.insertBefore( elem, target.firstChild );
5553                         }
5554                 });
5555         },
5556
5557         before: function() {
5558                 return this.domManip( arguments, function( elem ) {
5559                         if ( this.parentNode ) {
5560                                 this.parentNode.insertBefore( elem, this );
5561                         }
5562                 });
5563         },
5564
5565         after: function() {
5566                 return this.domManip( arguments, function( elem ) {
5567                         if ( this.parentNode ) {
5568                                 this.parentNode.insertBefore( elem, this.nextSibling );
5569                         }
5570                 });
5571         },
5572
5573         // keepData is for internal use only--do not document
5574         remove: function( selector, keepData ) {
5575                 var elem,
5576                         elems = selector ? jQuery.filter( selector, this ) : this,
5577                         i = 0;
5578
5579                 for ( ; (elem = elems[i]) != null; i++ ) {
5580                         if ( !keepData && elem.nodeType === 1 ) {
5581                                 jQuery.cleanData( getAll( elem ) );
5582                         }
5583
5584                         if ( elem.parentNode ) {
5585                                 if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5586                                         setGlobalEval( getAll( elem, "script" ) );
5587                                 }
5588                                 elem.parentNode.removeChild( elem );
5589                         }
5590                 }
5591
5592                 return this;
5593         },
5594
5595         empty: function() {
5596                 var elem,
5597                         i = 0;
5598
5599                 for ( ; (elem = this[i]) != null; i++ ) {
5600                         if ( elem.nodeType === 1 ) {
5601
5602                                 // Prevent memory leaks
5603                                 jQuery.cleanData( getAll( elem, false ) );
5604
5605                                 // Remove any remaining nodes
5606                                 elem.textContent = "";
5607                         }
5608                 }
5609
5610                 return this;
5611         },
5612
5613         clone: function( dataAndEvents, deepDataAndEvents ) {
5614                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5615                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5616
5617                 return this.map( function () {
5618                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5619                 });
5620         },
5621
5622         html: function( value ) {
5623                 return jQuery.access( this, function( value ) {
5624                         var elem = this[ 0 ] || {},
5625                                 i = 0,
5626                                 l = this.length;
5627
5628                         if ( value === undefined && elem.nodeType === 1 ) {
5629                                 return elem.innerHTML;
5630                         }
5631
5632                         // See if we can take a shortcut and just use innerHTML
5633                         if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5634                                 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5635
5636                                 value = value.replace( rxhtmlTag, "<$1></$2>" );
5637
5638                                 try {
5639                                         for ( ; i < l; i++ ) {
5640                                                 elem = this[ i ] || {};
5641
5642                                                 // Remove element nodes and prevent memory leaks
5643                                                 if ( elem.nodeType === 1 ) {
5644                                                         jQuery.cleanData( getAll( elem, false ) );
5645                                                         elem.innerHTML = value;
5646                                                 }
5647                                         }
5648
5649                                         elem = 0;
5650
5651                                 // If using innerHTML throws an exception, use the fallback method
5652                                 } catch( e ) {}
5653                         }
5654
5655                         if ( elem ) {
5656                                 this.empty().append( value );
5657                         }
5658                 }, null, value, arguments.length );
5659         },
5660
5661         replaceWith: function() {
5662                 var
5663                         // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
5664                         args = jQuery.map( this, function( elem ) {
5665                                 return [ elem.nextSibling, elem.parentNode ];
5666                         }),
5667                         i = 0;
5668
5669                 // Make the changes, replacing each context element with the new content
5670                 this.domManip( arguments, function( elem ) {
5671                         var next = args[ i++ ],
5672                                 parent = args[ i++ ];
5673
5674                         if ( parent ) {
5675                                 // Don't use the snapshot next if it has moved (#13810)
5676                                 if ( next && next.parentNode !== parent ) {
5677                                         next = this.nextSibling;
5678                                 }
5679                                 jQuery( this ).remove();
5680                                 parent.insertBefore( elem, next );
5681                         }
5682                 // Allow new content to include elements from the context set
5683                 }, true );
5684
5685                 // Force removal if there was no new content (e.g., from empty arguments)
5686                 return i ? this : this.remove();
5687         },
5688
5689         detach: function( selector ) {
5690                 return this.remove( selector, true );
5691         },
5692
5693         domManip: function( args, callback, allowIntersection ) {
5694
5695                 // Flatten any nested arrays
5696                 args = core_concat.apply( [], args );
5697
5698                 var fragment, first, scripts, hasScripts, node, doc,
5699                         i = 0,
5700                         l = this.length,
5701                         set = this,
5702                         iNoClone = l - 1,
5703                         value = args[ 0 ],
5704                         isFunction = jQuery.isFunction( value );
5705
5706                 // We can't cloneNode fragments that contain checked, in WebKit
5707                 if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
5708                         return this.each(function( index ) {
5709                                 var self = set.eq( index );
5710                                 if ( isFunction ) {
5711                                         args[ 0 ] = value.call( this, index, self.html() );
5712                                 }
5713                                 self.domManip( args, callback, allowIntersection );
5714                         });
5715                 }
5716
5717                 if ( l ) {
5718                         fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
5719                         first = fragment.firstChild;
5720
5721                         if ( fragment.childNodes.length === 1 ) {
5722                                 fragment = first;
5723                         }
5724
5725                         if ( first ) {
5726                                 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5727                                 hasScripts = scripts.length;
5728
5729                                 // Use the original fragment for the last item instead of the first because it can end up
5730                                 // being emptied incorrectly in certain situations (#8070).
5731                                 for ( ; i < l; i++ ) {
5732                                         node = fragment;
5733
5734                                         if ( i !== iNoClone ) {
5735                                                 node = jQuery.clone( node, true, true );
5736
5737                                                 // Keep references to cloned scripts for later restoration
5738                                                 if ( hasScripts ) {
5739                                                         // Support: QtWebKit
5740                                                         // jQuery.merge because core_push.apply(_, arraylike) throws
5741                                                         jQuery.merge( scripts, getAll( node, "script" ) );
5742                                                 }
5743                                         }
5744
5745                                         callback.call( this[ i ], node, i );
5746                                 }
5747
5748                                 if ( hasScripts ) {
5749                                         doc = scripts[ scripts.length - 1 ].ownerDocument;
5750
5751                                         // Reenable scripts
5752                                         jQuery.map( scripts, restoreScript );
5753
5754                                         // Evaluate executable scripts on first document insertion
5755                                         for ( i = 0; i < hasScripts; i++ ) {
5756                                                 node = scripts[ i ];
5757                                                 if ( rscriptType.test( node.type || "" ) &&
5758                                                         !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5759
5760                                                         if ( node.src ) {
5761                                                                 // Hope ajax is available...
5762                                                                 jQuery._evalUrl( node.src );
5763                                                         } else {
5764                                                                 jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5765                                                         }
5766                                                 }
5767                                         }
5768                                 }
5769                         }
5770                 }
5771
5772                 return this;
5773         }
5774 });
5775
5776 jQuery.each({
5777         appendTo: "append",
5778         prependTo: "prepend",
5779         insertBefore: "before",
5780         insertAfter: "after",
5781         replaceAll: "replaceWith"
5782 }, function( name, original ) {
5783         jQuery.fn[ name ] = function( selector ) {
5784                 var elems,
5785                         ret = [],
5786                         insert = jQuery( selector ),
5787                         last = insert.length - 1,
5788                         i = 0;
5789
5790                 for ( ; i <= last; i++ ) {
5791                         elems = i === last ? this : this.clone( true );
5792                         jQuery( insert[ i ] )[ original ]( elems );
5793
5794                         // Support: QtWebKit
5795                         // .get() because core_push.apply(_, arraylike) throws
5796                         core_push.apply( ret, elems.get() );
5797                 }
5798
5799                 return this.pushStack( ret );
5800         };
5801 });
5802
5803 jQuery.extend({
5804         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5805                 var i, l, srcElements, destElements,
5806                         clone = elem.cloneNode( true ),
5807                         inPage = jQuery.contains( elem.ownerDocument, elem );
5808
5809                 // Support: IE >= 9
5810                 // Fix Cloning issues
5811                 if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
5812
5813                         // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5814                         destElements = getAll( clone );
5815                         srcElements = getAll( elem );
5816
5817                         for ( i = 0, l = srcElements.length; i < l; i++ ) {
5818                                 fixInput( srcElements[ i ], destElements[ i ] );
5819                         }
5820                 }
5821
5822                 // Copy the events from the original to the clone
5823                 if ( dataAndEvents ) {
5824                         if ( deepDataAndEvents ) {
5825                                 srcElements = srcElements || getAll( elem );
5826                                 destElements = destElements || getAll( clone );
5827
5828                                 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5829                                         cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5830                                 }
5831                         } else {
5832                                 cloneCopyEvent( elem, clone );
5833                         }
5834                 }
5835
5836                 // Preserve script evaluation history
5837                 destElements = getAll( clone, "script" );
5838                 if ( destElements.length > 0 ) {
5839                         setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5840                 }
5841
5842                 // Return the cloned set
5843                 return clone;
5844         },
5845
5846         buildFragment: function( elems, context, scripts, selection ) {
5847                 var elem, tmp, tag, wrap, contains, j,
5848                         i = 0,
5849                         l = elems.length,
5850                         fragment = context.createDocumentFragment(),
5851                         nodes = [];
5852
5853                 for ( ; i < l; i++ ) {
5854                         elem = elems[ i ];
5855
5856                         if ( elem || elem === 0 ) {
5857
5858                                 // Add nodes directly
5859                                 if ( jQuery.type( elem ) === "object" ) {
5860                                         // Support: QtWebKit
5861                                         // jQuery.merge because core_push.apply(_, arraylike) throws
5862                                         jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5863
5864                                 // Convert non-html into a text node
5865                                 } else if ( !rhtml.test( elem ) ) {
5866                                         nodes.push( context.createTextNode( elem ) );
5867
5868                                 // Convert html into DOM nodes
5869                                 } else {
5870                                         tmp = tmp || fragment.appendChild( context.createElement("div") );
5871
5872                                         // Deserialize a standard representation
5873                                         tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase();
5874                                         wrap = wrapMap[ tag ] || wrapMap._default;
5875                                         tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5876
5877                                         // Descend through wrappers to the right content
5878                                         j = wrap[ 0 ];
5879                                         while ( j-- ) {
5880                                                 tmp = tmp.lastChild;
5881                                         }
5882
5883                                         // Support: QtWebKit
5884                                         // jQuery.merge because core_push.apply(_, arraylike) throws
5885                                         jQuery.merge( nodes, tmp.childNodes );
5886
5887                                         // Remember the top-level container
5888                                         tmp = fragment.firstChild;
5889
5890                                         // Fixes #12346
5891                                         // Support: Webkit, IE
5892                                         tmp.textContent = "";
5893                                 }
5894                         }
5895                 }
5896
5897                 // Remove wrapper from fragment
5898                 fragment.textContent = "";
5899
5900                 i = 0;
5901                 while ( (elem = nodes[ i++ ]) ) {
5902
5903                         // #4087 - If origin and destination elements are the same, and this is
5904                         // that element, do not do anything
5905                         if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5906                                 continue;
5907                         }
5908
5909                         contains = jQuery.contains( elem.ownerDocument, elem );
5910
5911                         // Append to fragment
5912                         tmp = getAll( fragment.appendChild( elem ), "script" );
5913
5914                         // Preserve script evaluation history
5915                         if ( contains ) {
5916                                 setGlobalEval( tmp );
5917                         }
5918
5919                         // Capture executables
5920                         if ( scripts ) {
5921                                 j = 0;
5922                                 while ( (elem = tmp[ j++ ]) ) {
5923                                         if ( rscriptType.test( elem.type || "" ) ) {
5924                                                 scripts.push( elem );
5925                                         }
5926                                 }
5927                         }
5928                 }
5929
5930                 return fragment;
5931         },
5932
5933         cleanData: function( elems ) {
5934                 var data, elem, events, type, key, j,
5935                         special = jQuery.event.special,
5936                         i = 0;
5937
5938                 for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5939                         if ( Data.accepts( elem ) ) {
5940                                 key = elem[ data_priv.expando ];
5941
5942                                 if ( key && (data = data_priv.cache[ key ]) ) {
5943                                         events = Object.keys( data.events || {} );
5944                                         if ( events.length ) {
5945                                                 for ( j = 0; (type = events[j]) !== undefined; j++ ) {
5946                                                         if ( special[ type ] ) {
5947                                                                 jQuery.event.remove( elem, type );
5948
5949                                                         // This is a shortcut to avoid jQuery.event.remove's overhead
5950                                                         } else {
5951                                                                 jQuery.removeEvent( elem, type, data.handle );
5952                                                         }
5953                                                 }
5954                                         }
5955                                         if ( data_priv.cache[ key ] ) {
5956                                                 // Discard any remaining `private` data
5957                                                 delete data_priv.cache[ key ];
5958                                         }
5959                                 }
5960                         }
5961                         // Discard any remaining `user` data
5962                         delete data_user.cache[ elem[ data_user.expando ] ];
5963                 }
5964         },
5965
5966         _evalUrl: function( url ) {
5967                 return jQuery.ajax({
5968                         url: url,
5969                         type: "GET",
5970                         dataType: "script",
5971                         async: false,
5972                         global: false,
5973                         "throws": true
5974                 });
5975         }
5976 });
5977
5978 // Support: 1.x compatibility
5979 // Manipulating tables requires a tbody
5980 function manipulationTarget( elem, content ) {
5981         return jQuery.nodeName( elem, "table" ) &&
5982                 jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
5983
5984                 elem.getElementsByTagName("tbody")[0] ||
5985                         elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
5986                 elem;
5987 }
5988
5989 // Replace/restore the type attribute of script elements for safe DOM manipulation
5990 function disableScript( elem ) {
5991         elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
5992         return elem;
5993 }
5994 function restoreScript( elem ) {
5995         var match = rscriptTypeMasked.exec( elem.type );
5996
5997         if ( match ) {
5998                 elem.type = match[ 1 ];
5999         } else {
6000                 elem.removeAttribute("type");
6001         }
6002
6003         return elem;
6004 }
6005
6006 // Mark scripts as having already been evaluated
6007 function setGlobalEval( elems, refElements ) {
6008         var l = elems.length,
6009                 i = 0;
6010
6011         for ( ; i < l; i++ ) {
6012                 data_priv.set(
6013                         elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
6014                 );
6015         }
6016 }
6017
6018 function cloneCopyEvent( src, dest ) {
6019         var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
6020
6021         if ( dest.nodeType !== 1 ) {
6022                 return;
6023         }
6024
6025         // 1. Copy private data: events, handlers, etc.
6026         if ( data_priv.hasData( src ) ) {
6027                 pdataOld = data_priv.access( src );
6028                 pdataCur = data_priv.set( dest, pdataOld );
6029                 events = pdataOld.events;
6030
6031                 if ( events ) {
6032                         delete pdataCur.handle;
6033                         pdataCur.events = {};
6034
6035                         for ( type in events ) {
6036                                 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6037                                         jQuery.event.add( dest, type, events[ type ][ i ] );
6038                                 }
6039                         }
6040                 }
6041         }
6042
6043         // 2. Copy user data
6044         if ( data_user.hasData( src ) ) {
6045                 udataOld = data_user.access( src );
6046                 udataCur = jQuery.extend( {}, udataOld );
6047
6048                 data_user.set( dest, udataCur );
6049         }
6050 }
6051
6052
6053 function getAll( context, tag ) {
6054         var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
6055                         context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
6056                         [];
6057
6058         return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
6059                 jQuery.merge( [ context ], ret ) :
6060                 ret;
6061 }
6062
6063 // Support: IE >= 9
6064 function fixInput( src, dest ) {
6065         var nodeName = dest.nodeName.toLowerCase();
6066
6067         // Fails to persist the checked state of a cloned checkbox or radio button.
6068         if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
6069                 dest.checked = src.checked;
6070
6071         // Fails to return the selected option to the default selected state when cloning options
6072         } else if ( nodeName === "input" || nodeName === "textarea" ) {
6073                 dest.defaultValue = src.defaultValue;
6074         }
6075 }
6076 jQuery.fn.extend({
6077         wrapAll: function( html ) {
6078                 var wrap;
6079
6080                 if ( jQuery.isFunction( html ) ) {
6081                         return this.each(function( i ) {
6082                                 jQuery( this ).wrapAll( html.call(this, i) );
6083                         });
6084                 }
6085
6086                 if ( this[ 0 ] ) {
6087
6088                         // The elements to wrap the target around
6089                         wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
6090
6091                         if ( this[ 0 ].parentNode ) {
6092                                 wrap.insertBefore( this[ 0 ] );
6093                         }
6094
6095                         wrap.map(function() {
6096                                 var elem = this;
6097
6098                                 while ( elem.firstElementChild ) {
6099                                         elem = elem.firstElementChild;
6100                                 }
6101
6102                                 return elem;
6103                         }).append( this );
6104                 }
6105
6106                 return this;
6107         },
6108
6109         wrapInner: function( html ) {
6110                 if ( jQuery.isFunction( html ) ) {
6111                         return this.each(function( i ) {
6112                                 jQuery( this ).wrapInner( html.call(this, i) );
6113                         });
6114                 }
6115
6116                 return this.each(function() {
6117                         var self = jQuery( this ),
6118                                 contents = self.contents();
6119
6120                         if ( contents.length ) {
6121                                 contents.wrapAll( html );
6122
6123                         } else {
6124                                 self.append( html );
6125                         }
6126                 });
6127         },
6128
6129         wrap: function( html ) {
6130                 var isFunction = jQuery.isFunction( html );
6131
6132                 return this.each(function( i ) {
6133                         jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
6134                 });
6135         },
6136
6137         unwrap: function() {
6138                 return this.parent().each(function() {
6139                         if ( !jQuery.nodeName( this, "body" ) ) {
6140                                 jQuery( this ).replaceWith( this.childNodes );
6141                         }
6142                 }).end();
6143         }
6144 });
6145 var curCSS, iframe,
6146         // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6147         // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6148         rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6149         rmargin = /^margin/,
6150         rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6151         rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6152         rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
6153         elemdisplay = { BODY: "block" },
6154
6155         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6156         cssNormalTransform = {
6157                 letterSpacing: 0,
6158                 fontWeight: 400
6159         },
6160
6161         cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6162         cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
6163
6164 // return a css property mapped to a potentially vendor prefixed property
6165 function vendorPropName( style, name ) {
6166
6167         // shortcut for names that are not vendor prefixed
6168         if ( name in style ) {
6169                 return name;
6170         }
6171
6172         // check for vendor prefixed names
6173         var capName = name.charAt(0).toUpperCase() + name.slice(1),
6174                 origName = name,
6175                 i = cssPrefixes.length;
6176
6177         while ( i-- ) {
6178                 name = cssPrefixes[ i ] + capName;
6179                 if ( name in style ) {
6180                         return name;
6181                 }
6182         }
6183
6184         return origName;
6185 }
6186
6187 function isHidden( elem, el ) {
6188         // isHidden might be called from jQuery#filter function;
6189         // in that case, element will be second argument
6190         elem = el || elem;
6191         return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6192 }
6193
6194 // NOTE: we've included the "window" in window.getComputedStyle
6195 // because jsdom on node.js will break without it.
6196 function getStyles( elem ) {
6197         return window.getComputedStyle( elem, null );
6198 }
6199
6200 function showHide( elements, show ) {
6201         var display, elem, hidden,
6202                 values = [],
6203                 index = 0,
6204                 length = elements.length;
6205
6206         for ( ; index < length; index++ ) {
6207                 elem = elements[ index ];
6208                 if ( !elem.style ) {
6209                         continue;
6210                 }
6211
6212                 values[ index ] = data_priv.get( elem, "olddisplay" );
6213                 display = elem.style.display;
6214                 if ( show ) {
6215                         // Reset the inline display of this element to learn if it is
6216                         // being hidden by cascaded rules or not
6217                         if ( !values[ index ] && display === "none" ) {
6218                                 elem.style.display = "";
6219                         }
6220
6221                         // Set elements which have been overridden with display: none
6222                         // in a stylesheet to whatever the default browser style is
6223                         // for such an element
6224                         if ( elem.style.display === "" && isHidden( elem ) ) {
6225                                 values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6226                         }
6227                 } else {
6228
6229                         if ( !values[ index ] ) {
6230                                 hidden = isHidden( elem );
6231
6232                                 if ( display && display !== "none" || !hidden ) {
6233                                         data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") );
6234                                 }
6235                         }
6236                 }
6237         }
6238
6239         // Set the display of most of the elements in a second loop
6240         // to avoid the constant reflow
6241         for ( index = 0; index < length; index++ ) {
6242                 elem = elements[ index ];
6243                 if ( !elem.style ) {
6244                         continue;
6245                 }
6246                 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6247                         elem.style.display = show ? values[ index ] || "" : "none";
6248                 }
6249         }
6250
6251         return elements;
6252 }
6253
6254 jQuery.fn.extend({
6255         css: function( name, value ) {
6256                 return jQuery.access( this, function( elem, name, value ) {
6257                         var styles, len,
6258                                 map = {},
6259                                 i = 0;
6260
6261                         if ( jQuery.isArray( name ) ) {
6262                                 styles = getStyles( elem );
6263                                 len = name.length;
6264
6265                                 for ( ; i < len; i++ ) {
6266                                         map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6267                                 }
6268
6269                                 return map;
6270                         }
6271
6272                         return value !== undefined ?
6273                                 jQuery.style( elem, name, value ) :
6274                                 jQuery.css( elem, name );
6275                 }, name, value, arguments.length > 1 );
6276         },
6277         show: function() {
6278                 return showHide( this, true );
6279         },
6280         hide: function() {
6281                 return showHide( this );
6282         },
6283         toggle: function( state ) {
6284                 if ( typeof state === "boolean" ) {
6285                         return state ? this.show() : this.hide();
6286                 }
6287
6288                 return this.each(function() {
6289                         if ( isHidden( this ) ) {
6290                                 jQuery( this ).show();
6291                         } else {
6292                                 jQuery( this ).hide();
6293                         }
6294                 });
6295         }
6296 });
6297
6298 jQuery.extend({
6299         // Add in style property hooks for overriding the default
6300         // behavior of getting and setting a style property
6301         cssHooks: {
6302                 opacity: {
6303                         get: function( elem, computed ) {
6304                                 if ( computed ) {
6305                                         // We should always get a number back from opacity
6306                                         var ret = curCSS( elem, "opacity" );
6307                                         return ret === "" ? "1" : ret;
6308                                 }
6309                         }
6310                 }
6311         },
6312
6313         // Don't automatically add "px" to these possibly-unitless properties
6314         cssNumber: {
6315                 "columnCount": true,
6316                 "fillOpacity": true,
6317                 "fontWeight": true,
6318                 "lineHeight": true,
6319                 "opacity": true,
6320                 "order": true,
6321                 "orphans": true,
6322                 "widows": true,
6323                 "zIndex": true,
6324                 "zoom": true
6325         },
6326
6327         // Add in properties whose names you wish to fix before
6328         // setting or getting the value
6329         cssProps: {
6330                 // normalize float css property
6331                 "float": "cssFloat"
6332         },
6333
6334         // Get and set the style property on a DOM Node
6335         style: function( elem, name, value, extra ) {
6336                 // Don't set styles on text and comment nodes
6337                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6338                         return;
6339                 }
6340
6341                 // Make sure that we're working with the right name
6342                 var ret, type, hooks,
6343                         origName = jQuery.camelCase( name ),
6344                         style = elem.style;
6345
6346                 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6347
6348                 // gets hook for the prefixed version
6349                 // followed by the unprefixed version
6350                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6351
6352                 // Check if we're setting a value
6353                 if ( value !== undefined ) {
6354                         type = typeof value;
6355
6356                         // convert relative number strings (+= or -=) to relative numbers. #7345
6357                         if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6358                                 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6359                                 // Fixes bug #9237
6360                                 type = "number";
6361                         }
6362
6363                         // Make sure that NaN and null values aren't set. See: #7116
6364                         if ( value == null || type === "number" && isNaN( value ) ) {
6365                                 return;
6366                         }
6367
6368                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
6369                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6370                                 value += "px";
6371                         }
6372
6373                         // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
6374                         // but it would mean to define eight (for every problematic property) identical functions
6375                         if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
6376                                 style[ name ] = "inherit";
6377                         }
6378
6379                         // If a hook was provided, use that value, otherwise just set the specified value
6380                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6381                                 style[ name ] = value;
6382                         }
6383
6384                 } else {
6385                         // If a hook was provided get the non-computed value from there
6386                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6387                                 return ret;
6388                         }
6389
6390                         // Otherwise just get the value from the style object
6391                         return style[ name ];
6392                 }
6393         },
6394
6395         css: function( elem, name, extra, styles ) {
6396                 var val, num, hooks,
6397                         origName = jQuery.camelCase( name );
6398
6399                 // Make sure that we're working with the right name
6400                 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6401
6402                 // gets hook for the prefixed version
6403                 // followed by the unprefixed version
6404                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6405
6406                 // If a hook was provided get the computed value from there
6407                 if ( hooks && "get" in hooks ) {
6408                         val = hooks.get( elem, true, extra );
6409                 }
6410
6411                 // Otherwise, if a way to get the computed value exists, use that
6412                 if ( val === undefined ) {
6413                         val = curCSS( elem, name, styles );
6414                 }
6415
6416                 //convert "normal" to computed value
6417                 if ( val === "normal" && name in cssNormalTransform ) {
6418                         val = cssNormalTransform[ name ];
6419                 }
6420
6421                 // Return, converting to number if forced or a qualifier was provided and val looks numeric
6422                 if ( extra === "" || extra ) {
6423                         num = parseFloat( val );
6424                         return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6425                 }
6426                 return val;
6427         }
6428 });
6429
6430 curCSS = function( elem, name, _computed ) {
6431         var width, minWidth, maxWidth,
6432                 computed = _computed || getStyles( elem ),
6433
6434                 // Support: IE9
6435                 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6436                 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
6437                 style = elem.style;
6438
6439         if ( computed ) {
6440
6441                 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6442                         ret = jQuery.style( elem, name );
6443                 }
6444
6445                 // Support: Safari 5.1
6446                 // A tribute to the "awesome hack by Dean Edwards"
6447                 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6448                 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6449                 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6450
6451                         // Remember the original values
6452                         width = style.width;
6453                         minWidth = style.minWidth;
6454                         maxWidth = style.maxWidth;
6455
6456                         // Put in the new values to get a computed value out
6457                         style.minWidth = style.maxWidth = style.width = ret;
6458                         ret = computed.width;
6459
6460                         // Revert the changed values
6461                         style.width = width;
6462                         style.minWidth = minWidth;
6463                         style.maxWidth = maxWidth;
6464                 }
6465         }
6466
6467         return ret;
6468 };
6469
6470
6471 function setPositiveNumber( elem, value, subtract ) {
6472         var matches = rnumsplit.exec( value );
6473         return matches ?
6474                 // Guard against undefined "subtract", e.g., when used as in cssHooks
6475                 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6476                 value;
6477 }
6478
6479 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6480         var i = extra === ( isBorderBox ? "border" : "content" ) ?
6481                 // If we already have the right measurement, avoid augmentation
6482                 4 :
6483                 // Otherwise initialize for horizontal or vertical properties
6484                 name === "width" ? 1 : 0,
6485
6486                 val = 0;
6487
6488         for ( ; i < 4; i += 2 ) {
6489                 // both box models exclude margin, so add it if we want it
6490                 if ( extra === "margin" ) {
6491                         val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6492                 }
6493
6494                 if ( isBorderBox ) {
6495                         // border-box includes padding, so remove it if we want content
6496                         if ( extra === "content" ) {
6497                                 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6498                         }
6499
6500                         // at this point, extra isn't border nor margin, so remove border
6501                         if ( extra !== "margin" ) {
6502                                 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6503                         }
6504                 } else {
6505                         // at this point, extra isn't content, so add padding
6506                         val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6507
6508                         // at this point, extra isn't content nor padding, so add border
6509                         if ( extra !== "padding" ) {
6510                                 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6511                         }
6512                 }
6513         }
6514
6515         return val;
6516 }
6517
6518 function getWidthOrHeight( elem, name, extra ) {
6519
6520         // Start with offset property, which is equivalent to the border-box value
6521         var valueIsBorderBox = true,
6522                 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6523                 styles = getStyles( elem ),
6524                 isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6525
6526         // some non-html elements return undefined for offsetWidth, so check for null/undefined
6527         // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6528         // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6529         if ( val <= 0 || val == null ) {
6530                 // Fall back to computed then uncomputed css if necessary
6531                 val = curCSS( elem, name, styles );
6532                 if ( val < 0 || val == null ) {
6533                         val = elem.style[ name ];
6534                 }
6535
6536                 // Computed unit is not pixels. Stop here and return.
6537                 if ( rnumnonpx.test(val) ) {
6538                         return val;
6539                 }
6540
6541                 // we need the check for style in case a browser which returns unreliable values
6542                 // for getComputedStyle silently falls back to the reliable elem.style
6543                 valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6544
6545                 // Normalize "", auto, and prepare for extra
6546                 val = parseFloat( val ) || 0;
6547         }
6548
6549         // use the active box-sizing model to add/subtract irrelevant styles
6550         return ( val +
6551                 augmentWidthOrHeight(
6552                         elem,
6553                         name,
6554                         extra || ( isBorderBox ? "border" : "content" ),
6555                         valueIsBorderBox,
6556                         styles
6557                 )
6558         ) + "px";
6559 }
6560
6561 // Try to determine the default display value of an element
6562 function css_defaultDisplay( nodeName ) {
6563         var doc = document,
6564                 display = elemdisplay[ nodeName ];
6565
6566         if ( !display ) {
6567                 display = actualDisplay( nodeName, doc );
6568
6569                 // If the simple way fails, read from inside an iframe
6570                 if ( display === "none" || !display ) {
6571                         // Use the already-created iframe if possible
6572                         iframe = ( iframe ||
6573                                 jQuery("<iframe frameborder='0' width='0' height='0'/>")
6574                                 .css( "cssText", "display:block !important" )
6575                         ).appendTo( doc.documentElement );
6576
6577                         // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6578                         doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
6579                         doc.write("<!doctype html><html><body>");
6580                         doc.close();
6581
6582                         display = actualDisplay( nodeName, doc );
6583                         iframe.detach();
6584                 }
6585
6586                 // Store the correct default display
6587                 elemdisplay[ nodeName ] = display;
6588         }
6589
6590         return display;
6591 }
6592
6593 // Called ONLY from within css_defaultDisplay
6594 function actualDisplay( name, doc ) {
6595         var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6596                 display = jQuery.css( elem[0], "display" );
6597         elem.remove();
6598         return display;
6599 }
6600
6601 jQuery.each([ "height", "width" ], function( i, name ) {
6602         jQuery.cssHooks[ name ] = {
6603                 get: function( elem, computed, extra ) {
6604                         if ( computed ) {
6605                                 // certain elements can have dimension info if we invisibly show them
6606                                 // however, it must have a current display style that would benefit from this
6607                                 return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
6608                                         jQuery.swap( elem, cssShow, function() {
6609                                                 return getWidthOrHeight( elem, name, extra );
6610                                         }) :
6611                                         getWidthOrHeight( elem, name, extra );
6612                         }
6613                 },
6614
6615                 set: function( elem, value, extra ) {
6616                         var styles = extra && getStyles( elem );
6617                         return setPositiveNumber( elem, value, extra ?
6618                                 augmentWidthOrHeight(
6619                                         elem,
6620                                         name,
6621                                         extra,
6622                                         jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6623                                         styles
6624                                 ) : 0
6625                         );
6626                 }
6627         };
6628 });
6629
6630 // These hooks cannot be added until DOM ready because the support test
6631 // for it is not run until after DOM ready
6632 jQuery(function() {
6633         // Support: Android 2.3
6634         if ( !jQuery.support.reliableMarginRight ) {
6635                 jQuery.cssHooks.marginRight = {
6636                         get: function( elem, computed ) {
6637                                 if ( computed ) {
6638                                         // Support: Android 2.3
6639                                         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6640                                         // Work around by temporarily setting element display to inline-block
6641                                         return jQuery.swap( elem, { "display": "inline-block" },
6642                                                 curCSS, [ elem, "marginRight" ] );
6643                                 }
6644                         }
6645                 };
6646         }
6647
6648         // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
6649         // getComputedStyle returns percent when specified for top/left/bottom/right
6650         // rather than make the css module depend on the offset module, we just check for it here
6651         if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
6652                 jQuery.each( [ "top", "left" ], function( i, prop ) {
6653                         jQuery.cssHooks[ prop ] = {
6654                                 get: function( elem, computed ) {
6655                                         if ( computed ) {
6656                                                 computed = curCSS( elem, prop );
6657                                                 // if curCSS returns percentage, fallback to offset
6658                                                 return rnumnonpx.test( computed ) ?
6659                                                         jQuery( elem ).position()[ prop ] + "px" :
6660                                                         computed;
6661                                         }
6662                                 }
6663                         };
6664                 });
6665         }
6666
6667 });
6668
6669 if ( jQuery.expr && jQuery.expr.filters ) {
6670         jQuery.expr.filters.hidden = function( elem ) {
6671                 // Support: Opera <= 12.12
6672                 // Opera reports offsetWidths and offsetHeights less than zero on some elements
6673                 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
6674         };
6675
6676         jQuery.expr.filters.visible = function( elem ) {
6677                 return !jQuery.expr.filters.hidden( elem );
6678         };
6679 }
6680
6681 // These hooks are used by animate to expand properties
6682 jQuery.each({
6683         margin: "",
6684         padding: "",
6685         border: "Width"
6686 }, function( prefix, suffix ) {
6687         jQuery.cssHooks[ prefix + suffix ] = {
6688                 expand: function( value ) {
6689                         var i = 0,
6690                                 expanded = {},
6691
6692                                 // assumes a single number if not a string
6693                                 parts = typeof value === "string" ? value.split(" ") : [ value ];
6694
6695                         for ( ; i < 4; i++ ) {
6696                                 expanded[ prefix + cssExpand[ i ] + suffix ] =
6697                                         parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6698                         }
6699
6700                         return expanded;
6701                 }
6702         };
6703
6704         if ( !rmargin.test( prefix ) ) {
6705                 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6706         }
6707 });
6708 var r20 = /%20/g,
6709         rbracket = /\[\]$/,
6710         rCRLF = /\r?\n/g,
6711         rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
6712         rsubmittable = /^(?:input|select|textarea|keygen)/i;
6713
6714 jQuery.fn.extend({
6715         serialize: function() {
6716                 return jQuery.param( this.serializeArray() );
6717         },
6718         serializeArray: function() {
6719                 return this.map(function(){
6720                         // Can add propHook for "elements" to filter or add form elements
6721                         var elements = jQuery.prop( this, "elements" );
6722                         return elements ? jQuery.makeArray( elements ) : this;
6723                 })
6724                 .filter(function(){
6725                         var type = this.type;
6726                         // Use .is(":disabled") so that fieldset[disabled] works
6727                         return this.name && !jQuery( this ).is( ":disabled" ) &&
6728                                 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
6729                                 ( this.checked || !manipulation_rcheckableType.test( type ) );
6730                 })
6731                 .map(function( i, elem ){
6732                         var val = jQuery( this ).val();
6733
6734                         return val == null ?
6735                                 null :
6736                                 jQuery.isArray( val ) ?
6737                                         jQuery.map( val, function( val ){
6738                                                 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6739                                         }) :
6740                                         { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6741                 }).get();
6742         }
6743 });
6744
6745 //Serialize an array of form elements or a set of
6746 //key/values into a query string
6747 jQuery.param = function( a, traditional ) {
6748         var prefix,
6749                 s = [],
6750                 add = function( key, value ) {
6751                         // If value is a function, invoke it and return its value
6752                         value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
6753                         s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
6754                 };
6755
6756         // Set traditional to true for jQuery <= 1.3.2 behavior.
6757         if ( traditional === undefined ) {
6758                 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
6759         }
6760
6761         // If an array was passed in, assume that it is an array of form elements.
6762         if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
6763                 // Serialize the form elements
6764                 jQuery.each( a, function() {
6765                         add( this.name, this.value );
6766                 });
6767
6768         } else {
6769                 // If traditional, encode the "old" way (the way 1.3.2 or older
6770                 // did it), otherwise encode params recursively.
6771                 for ( prefix in a ) {
6772                         buildParams( prefix, a[ prefix ], traditional, add );
6773                 }
6774         }
6775
6776         // Return the resulting serialization
6777         return s.join( "&" ).replace( r20, "+" );
6778 };
6779
6780 function buildParams( prefix, obj, traditional, add ) {
6781         var name;
6782
6783         if ( jQuery.isArray( obj ) ) {
6784                 // Serialize array item.
6785                 jQuery.each( obj, function( i, v ) {
6786                         if ( traditional || rbracket.test( prefix ) ) {
6787                                 // Treat each array item as a scalar.
6788                                 add( prefix, v );
6789
6790                         } else {
6791                                 // Item is non-scalar (array or object), encode its numeric index.
6792                                 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
6793                         }
6794                 });
6795
6796         } else if ( !traditional && jQuery.type( obj ) === "object" ) {
6797                 // Serialize object item.
6798                 for ( name in obj ) {
6799                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
6800                 }
6801
6802         } else {
6803                 // Serialize scalar item.
6804                 add( prefix, obj );
6805         }
6806 }
6807 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
6808         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
6809         "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
6810
6811         // Handle event binding
6812         jQuery.fn[ name ] = function( data, fn ) {
6813                 return arguments.length > 0 ?
6814                         this.on( name, null, data, fn ) :
6815                         this.trigger( name );
6816         };
6817 });
6818
6819 jQuery.fn.extend({
6820         hover: function( fnOver, fnOut ) {
6821                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
6822         },
6823
6824         bind: function( types, data, fn ) {
6825                 return this.on( types, null, data, fn );
6826         },
6827         unbind: function( types, fn ) {
6828                 return this.off( types, null, fn );
6829         },
6830
6831         delegate: function( selector, types, data, fn ) {
6832                 return this.on( types, selector, data, fn );
6833         },
6834         undelegate: function( selector, types, fn ) {
6835                 // ( namespace ) or ( selector, types [, fn] )
6836                 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
6837         }
6838 });
6839 var
6840         // Document location
6841         ajaxLocParts,
6842         ajaxLocation,
6843
6844         ajax_nonce = jQuery.now(),
6845
6846         ajax_rquery = /\?/,
6847         rhash = /#.*$/,
6848         rts = /([?&])_=[^&]*/,
6849         rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
6850         // #7653, #8125, #8152: local protocol detection
6851         rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
6852         rnoContent = /^(?:GET|HEAD)$/,
6853         rprotocol = /^\/\//,
6854         rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
6855
6856         // Keep a copy of the old load method
6857         _load = jQuery.fn.load,
6858
6859         /* Prefilters
6860          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6861          * 2) These are called:
6862          *    - BEFORE asking for a transport
6863          *    - AFTER param serialization (s.data is a string if s.processData is true)
6864          * 3) key is the dataType
6865          * 4) the catchall symbol "*" can be used
6866          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6867          */
6868         prefilters = {},
6869
6870         /* Transports bindings
6871          * 1) key is the dataType
6872          * 2) the catchall symbol "*" can be used
6873          * 3) selection will start with transport dataType and THEN go to "*" if needed
6874          */
6875         transports = {},
6876
6877         // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6878         allTypes = "*/".concat("*");
6879
6880 // #8138, IE may throw an exception when accessing
6881 // a field from window.location if document.domain has been set
6882 try {
6883         ajaxLocation = location.href;
6884 } catch( e ) {
6885         // Use the href attribute of an A element
6886         // since IE will modify it given document.location
6887         ajaxLocation = document.createElement( "a" );
6888         ajaxLocation.href = "";
6889         ajaxLocation = ajaxLocation.href;
6890 }
6891
6892 // Segment location into parts
6893 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6894
6895 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6896 function addToPrefiltersOrTransports( structure ) {
6897
6898         // dataTypeExpression is optional and defaults to "*"
6899         return function( dataTypeExpression, func ) {
6900
6901                 if ( typeof dataTypeExpression !== "string" ) {
6902                         func = dataTypeExpression;
6903                         dataTypeExpression = "*";
6904                 }
6905
6906                 var dataType,
6907                         i = 0,
6908                         dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
6909
6910                 if ( jQuery.isFunction( func ) ) {
6911                         // For each dataType in the dataTypeExpression
6912                         while ( (dataType = dataTypes[i++]) ) {
6913                                 // Prepend if requested
6914                                 if ( dataType[0] === "+" ) {
6915                                         dataType = dataType.slice( 1 ) || "*";
6916                                         (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
6917
6918                                 // Otherwise append
6919                                 } else {
6920                                         (structure[ dataType ] = structure[ dataType ] || []).push( func );
6921                                 }
6922                         }
6923                 }
6924         };
6925 }
6926
6927 // Base inspection function for prefilters and transports
6928 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
6929
6930         var inspected = {},
6931                 seekingTransport = ( structure === transports );
6932
6933         function inspect( dataType ) {
6934                 var selected;
6935                 inspected[ dataType ] = true;
6936                 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
6937                         var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
6938                         if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
6939                                 options.dataTypes.unshift( dataTypeOrTransport );
6940                                 inspect( dataTypeOrTransport );
6941                                 return false;
6942                         } else if ( seekingTransport ) {
6943                                 return !( selected = dataTypeOrTransport );
6944                         }
6945                 });
6946                 return selected;
6947         }
6948
6949         return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
6950 }
6951
6952 // A special extend for ajax options
6953 // that takes "flat" options (not to be deep extended)
6954 // Fixes #9887
6955 function ajaxExtend( target, src ) {
6956         var key, deep,
6957                 flatOptions = jQuery.ajaxSettings.flatOptions || {};
6958
6959         for ( key in src ) {
6960                 if ( src[ key ] !== undefined ) {
6961                         ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
6962                 }
6963         }
6964         if ( deep ) {
6965                 jQuery.extend( true, target, deep );
6966         }
6967
6968         return target;
6969 }
6970
6971 jQuery.fn.load = function( url, params, callback ) {
6972         if ( typeof url !== "string" && _load ) {
6973                 return _load.apply( this, arguments );
6974         }
6975
6976         var selector, type, response,
6977                 self = this,
6978                 off = url.indexOf(" ");
6979
6980         if ( off >= 0 ) {
6981                 selector = url.slice( off );
6982                 url = url.slice( 0, off );
6983         }
6984
6985         // If it's a function
6986         if ( jQuery.isFunction( params ) ) {
6987
6988                 // We assume that it's the callback
6989                 callback = params;
6990                 params = undefined;
6991
6992         // Otherwise, build a param string
6993         } else if ( params && typeof params === "object" ) {
6994                 type = "POST";
6995         }
6996
6997         // If we have elements to modify, make the request
6998         if ( self.length > 0 ) {
6999                 jQuery.ajax({
7000                         url: url,
7001
7002                         // if "type" variable is undefined, then "GET" method will be used
7003                         type: type,
7004                         dataType: "html",
7005                         data: params
7006                 }).done(function( responseText ) {
7007
7008                         // Save response for use in complete callback
7009                         response = arguments;
7010
7011                         self.html( selector ?
7012
7013                                 // If a selector was specified, locate the right elements in a dummy div
7014                                 // Exclude scripts to avoid IE 'Permission Denied' errors
7015                                 jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
7016
7017                                 // Otherwise use the full result
7018                                 responseText );
7019
7020                 }).complete( callback && function( jqXHR, status ) {
7021                         self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7022                 });
7023         }
7024
7025         return this;
7026 };
7027
7028 // Attach a bunch of functions for handling common AJAX events
7029 jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
7030         jQuery.fn[ type ] = function( fn ){
7031                 return this.on( type, fn );
7032         };
7033 });
7034
7035 jQuery.extend({
7036
7037         // Counter for holding the number of active queries
7038         active: 0,
7039
7040         // Last-Modified header cache for next request
7041         lastModified: {},
7042         etag: {},
7043
7044         ajaxSettings: {
7045                 url: ajaxLocation,
7046                 type: "GET",
7047                 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7048                 global: true,
7049                 processData: true,
7050                 async: true,
7051                 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7052                 /*
7053                 timeout: 0,
7054                 data: null,
7055                 dataType: null,
7056                 username: null,
7057                 password: null,
7058                 cache: null,
7059                 throws: false,
7060                 traditional: false,
7061                 headers: {},
7062                 */
7063
7064                 accepts: {
7065                         "*": allTypes,
7066                         text: "text/plain",
7067                         html: "text/html",
7068                         xml: "application/xml, text/xml",
7069                         json: "application/json, text/javascript"
7070                 },
7071
7072                 contents: {
7073                         xml: /xml/,
7074                         html: /html/,
7075                         json: /json/
7076                 },
7077
7078                 responseFields: {
7079                         xml: "responseXML",
7080                         text: "responseText",
7081                         json: "responseJSON"
7082                 },
7083
7084                 // Data converters
7085                 // Keys separate source (or catchall "*") and destination types with a single space
7086                 converters: {
7087
7088                         // Convert anything to text
7089                         "* text": String,
7090
7091                         // Text to html (true = no transformation)
7092                         "text html": true,
7093
7094                         // Evaluate text as a json expression
7095                         "text json": jQuery.parseJSON,
7096
7097                         // Parse text as xml
7098                         "text xml": jQuery.parseXML
7099                 },
7100
7101                 // For options that shouldn't be deep extended:
7102                 // you can add your own custom options here if
7103                 // and when you create one that shouldn't be
7104                 // deep extended (see ajaxExtend)
7105                 flatOptions: {
7106                         url: true,
7107                         context: true
7108                 }
7109         },
7110
7111         // Creates a full fledged settings object into target
7112         // with both ajaxSettings and settings fields.
7113         // If target is omitted, writes into ajaxSettings.
7114         ajaxSetup: function( target, settings ) {
7115                 return settings ?
7116
7117                         // Building a settings object
7118                         ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7119
7120                         // Extending ajaxSettings
7121                         ajaxExtend( jQuery.ajaxSettings, target );
7122         },
7123
7124         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7125         ajaxTransport: addToPrefiltersOrTransports( transports ),
7126
7127         // Main method
7128         ajax: function( url, options ) {
7129
7130                 // If url is an object, simulate pre-1.5 signature
7131                 if ( typeof url === "object" ) {
7132                         options = url;
7133                         url = undefined;
7134                 }
7135
7136                 // Force options to be an object
7137                 options = options || {};
7138
7139                 var transport,
7140                         // URL without anti-cache param
7141                         cacheURL,
7142                         // Response headers
7143                         responseHeadersString,
7144                         responseHeaders,
7145                         // timeout handle
7146                         timeoutTimer,
7147                         // Cross-domain detection vars
7148                         parts,
7149                         // To know if global events are to be dispatched
7150                         fireGlobals,
7151                         // Loop variable
7152                         i,
7153                         // Create the final options object
7154                         s = jQuery.ajaxSetup( {}, options ),
7155                         // Callbacks context
7156                         callbackContext = s.context || s,
7157                         // Context for global events is callbackContext if it is a DOM node or jQuery collection
7158                         globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7159                                 jQuery( callbackContext ) :
7160                                 jQuery.event,
7161                         // Deferreds
7162                         deferred = jQuery.Deferred(),
7163                         completeDeferred = jQuery.Callbacks("once memory"),
7164                         // Status-dependent callbacks
7165                         statusCode = s.statusCode || {},
7166                         // Headers (they are sent all at once)
7167                         requestHeaders = {},
7168                         requestHeadersNames = {},
7169                         // The jqXHR state
7170                         state = 0,
7171                         // Default abort message
7172                         strAbort = "canceled",
7173                         // Fake xhr
7174                         jqXHR = {
7175                                 readyState: 0,
7176
7177                                 // Builds headers hashtable if needed
7178                                 getResponseHeader: function( key ) {
7179                                         var match;
7180                                         if ( state === 2 ) {
7181                                                 if ( !responseHeaders ) {
7182                                                         responseHeaders = {};
7183                                                         while ( (match = rheaders.exec( responseHeadersString )) ) {
7184                                                                 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7185                                                         }
7186                                                 }
7187                                                 match = responseHeaders[ key.toLowerCase() ];
7188                                         }
7189                                         return match == null ? null : match;
7190                                 },
7191
7192                                 // Raw string
7193                                 getAllResponseHeaders: function() {
7194                                         return state === 2 ? responseHeadersString : null;
7195                                 },
7196
7197                                 // Caches the header
7198                                 setRequestHeader: function( name, value ) {
7199                                         var lname = name.toLowerCase();
7200                                         if ( !state ) {
7201                                                 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7202                                                 requestHeaders[ name ] = value;
7203                                         }
7204                                         return this;
7205                                 },
7206
7207                                 // Overrides response content-type header
7208                                 overrideMimeType: function( type ) {
7209                                         if ( !state ) {
7210                                                 s.mimeType = type;
7211                                         }
7212                                         return this;
7213                                 },
7214
7215                                 // Status-dependent callbacks
7216                                 statusCode: function( map ) {
7217                                         var code;
7218                                         if ( map ) {
7219                                                 if ( state < 2 ) {
7220                                                         for ( code in map ) {
7221                                                                 // Lazy-add the new callback in a way that preserves old ones
7222                                                                 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
7223                                                         }
7224                                                 } else {
7225                                                         // Execute the appropriate callbacks
7226                                                         jqXHR.always( map[ jqXHR.status ] );
7227                                                 }
7228                                         }
7229                                         return this;
7230                                 },
7231
7232                                 // Cancel the request
7233                                 abort: function( statusText ) {
7234                                         var finalText = statusText || strAbort;
7235                                         if ( transport ) {
7236                                                 transport.abort( finalText );
7237                                         }
7238                                         done( 0, finalText );
7239                                         return this;
7240                                 }
7241                         };
7242
7243                 // Attach deferreds
7244                 deferred.promise( jqXHR ).complete = completeDeferred.add;
7245                 jqXHR.success = jqXHR.done;
7246                 jqXHR.error = jqXHR.fail;
7247
7248                 // Remove hash character (#7531: and string promotion)
7249                 // Add protocol if not provided (prefilters might expect it)
7250                 // Handle falsy url in the settings object (#10093: consistency with old signature)
7251                 // We also use the url parameter if available
7252                 s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
7253                         .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7254
7255                 // Alias method option to type as per ticket #12004
7256                 s.type = options.method || options.type || s.method || s.type;
7257
7258                 // Extract dataTypes list
7259                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
7260
7261                 // A cross-domain request is in order when we have a protocol:host:port mismatch
7262                 if ( s.crossDomain == null ) {
7263                         parts = rurl.exec( s.url.toLowerCase() );
7264                         s.crossDomain = !!( parts &&
7265                                 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
7266                                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
7267                                                 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
7268                         );
7269                 }
7270
7271                 // Convert data if not already a string
7272                 if ( s.data && s.processData && typeof s.data !== "string" ) {
7273                         s.data = jQuery.param( s.data, s.traditional );
7274                 }
7275
7276                 // Apply prefilters
7277                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7278
7279                 // If request was aborted inside a prefilter, stop there
7280                 if ( state === 2 ) {
7281                         return jqXHR;
7282                 }
7283
7284                 // We can fire global events as of now if asked to
7285                 fireGlobals = s.global;
7286
7287                 // Watch for a new set of requests
7288                 if ( fireGlobals && jQuery.active++ === 0 ) {
7289                         jQuery.event.trigger("ajaxStart");
7290                 }
7291
7292                 // Uppercase the type
7293                 s.type = s.type.toUpperCase();
7294
7295                 // Determine if request has content
7296                 s.hasContent = !rnoContent.test( s.type );
7297
7298                 // Save the URL in case we're toying with the If-Modified-Since
7299                 // and/or If-None-Match header later on
7300                 cacheURL = s.url;
7301
7302                 // More options handling for requests with no content
7303                 if ( !s.hasContent ) {
7304
7305                         // If data is available, append data to url
7306                         if ( s.data ) {
7307                                 cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
7308                                 // #9682: remove data so that it's not used in an eventual retry
7309                                 delete s.data;
7310                         }
7311
7312                         // Add anti-cache in url if needed
7313                         if ( s.cache === false ) {
7314                                 s.url = rts.test( cacheURL ) ?
7315
7316                                         // If there is already a '_' parameter, set its value
7317                                         cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
7318
7319                                         // Otherwise add one to the end
7320                                         cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
7321                         }
7322                 }
7323
7324                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7325                 if ( s.ifModified ) {
7326                         if ( jQuery.lastModified[ cacheURL ] ) {
7327                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
7328                         }
7329                         if ( jQuery.etag[ cacheURL ] ) {
7330                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
7331                         }
7332                 }
7333
7334                 // Set the correct header, if data is being sent
7335                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7336                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
7337                 }
7338
7339                 // Set the Accepts header for the server, depending on the dataType
7340                 jqXHR.setRequestHeader(
7341                         "Accept",
7342                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7343                                 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7344                                 s.accepts[ "*" ]
7345                 );
7346
7347                 // Check for headers option
7348                 for ( i in s.headers ) {
7349                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7350                 }
7351
7352                 // Allow custom headers/mimetypes and early abort
7353                 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7354                         // Abort if not done already and return
7355                         return jqXHR.abort();
7356                 }
7357
7358                 // aborting is no longer a cancellation
7359                 strAbort = "abort";
7360
7361                 // Install callbacks on deferreds
7362                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7363                         jqXHR[ i ]( s[ i ] );
7364                 }
7365
7366                 // Get transport
7367                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7368
7369                 // If no transport, we auto-abort
7370                 if ( !transport ) {
7371                         done( -1, "No Transport" );
7372                 } else {
7373                         jqXHR.readyState = 1;
7374
7375                         // Send global event
7376                         if ( fireGlobals ) {
7377                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7378                         }
7379                         // Timeout
7380                         if ( s.async && s.timeout > 0 ) {
7381                                 timeoutTimer = setTimeout(function() {
7382                                         jqXHR.abort("timeout");
7383                                 }, s.timeout );
7384                         }
7385
7386                         try {
7387                                 state = 1;
7388                                 transport.send( requestHeaders, done );
7389                         } catch ( e ) {
7390                                 // Propagate exception as error if not done
7391                                 if ( state < 2 ) {
7392                                         done( -1, e );
7393                                 // Simply rethrow otherwise
7394                                 } else {
7395                                         throw e;
7396                                 }
7397                         }
7398                 }
7399
7400                 // Callback for when everything is done
7401                 function done( status, nativeStatusText, responses, headers ) {
7402                         var isSuccess, success, error, response, modified,
7403                                 statusText = nativeStatusText;
7404
7405                         // Called once
7406                         if ( state === 2 ) {
7407                                 return;
7408                         }
7409
7410                         // State is "done" now
7411                         state = 2;
7412
7413                         // Clear timeout if it exists
7414                         if ( timeoutTimer ) {
7415                                 clearTimeout( timeoutTimer );
7416                         }
7417
7418                         // Dereference transport for early garbage collection
7419                         // (no matter how long the jqXHR object will be used)
7420                         transport = undefined;
7421
7422                         // Cache response headers
7423                         responseHeadersString = headers || "";
7424
7425                         // Set readyState
7426                         jqXHR.readyState = status > 0 ? 4 : 0;
7427
7428                         // Determine if successful
7429                         isSuccess = status >= 200 && status < 300 || status === 304;
7430
7431                         // Get response data
7432                         if ( responses ) {
7433                                 response = ajaxHandleResponses( s, jqXHR, responses );
7434                         }
7435
7436                         // Convert no matter what (that way responseXXX fields are always set)
7437                         response = ajaxConvert( s, response, jqXHR, isSuccess );
7438
7439                         // If successful, handle type chaining
7440                         if ( isSuccess ) {
7441
7442                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7443                                 if ( s.ifModified ) {
7444                                         modified = jqXHR.getResponseHeader("Last-Modified");
7445                                         if ( modified ) {
7446                                                 jQuery.lastModified[ cacheURL ] = modified;
7447                                         }
7448                                         modified = jqXHR.getResponseHeader("etag");
7449                                         if ( modified ) {
7450                                                 jQuery.etag[ cacheURL ] = modified;
7451                                         }
7452                                 }
7453
7454                                 // if no content
7455                                 if ( status === 204 || s.type === "HEAD" ) {
7456                                         statusText = "nocontent";
7457
7458                                 // if not modified
7459                                 } else if ( status === 304 ) {
7460                                         statusText = "notmodified";
7461
7462                                 // If we have data, let's convert it
7463                                 } else {
7464                                         statusText = response.state;
7465                                         success = response.data;
7466                                         error = response.error;
7467                                         isSuccess = !error;
7468                                 }
7469                         } else {
7470                                 // We extract error from statusText
7471                                 // then normalize statusText and status for non-aborts
7472                                 error = statusText;
7473                                 if ( status || !statusText ) {
7474                                         statusText = "error";
7475                                         if ( status < 0 ) {
7476                                                 status = 0;
7477                                         }
7478                                 }
7479                         }
7480
7481                         // Set data for the fake xhr object
7482                         jqXHR.status = status;
7483                         jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7484
7485                         // Success/Error
7486                         if ( isSuccess ) {
7487                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7488                         } else {
7489                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7490                         }
7491
7492                         // Status-dependent callbacks
7493                         jqXHR.statusCode( statusCode );
7494                         statusCode = undefined;
7495
7496                         if ( fireGlobals ) {
7497                                 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
7498                                         [ jqXHR, s, isSuccess ? success : error ] );
7499                         }
7500
7501                         // Complete
7502                         completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7503
7504                         if ( fireGlobals ) {
7505                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7506                                 // Handle the global AJAX counter
7507                                 if ( !( --jQuery.active ) ) {
7508                                         jQuery.event.trigger("ajaxStop");
7509                                 }
7510                         }
7511                 }
7512
7513                 return jqXHR;
7514         },
7515
7516         getJSON: function( url, data, callback ) {
7517                 return jQuery.get( url, data, callback, "json" );
7518         },
7519
7520         getScript: function( url, callback ) {
7521                 return jQuery.get( url, undefined, callback, "script" );
7522         }
7523 });
7524
7525 jQuery.each( [ "get", "post" ], function( i, method ) {
7526         jQuery[ method ] = function( url, data, callback, type ) {
7527                 // shift arguments if data argument was omitted
7528                 if ( jQuery.isFunction( data ) ) {
7529                         type = type || callback;
7530                         callback = data;
7531                         data = undefined;
7532                 }
7533
7534                 return jQuery.ajax({
7535                         url: url,
7536                         type: method,
7537                         dataType: type,
7538                         data: data,
7539                         success: callback
7540                 });
7541         };
7542 });
7543
7544 /* Handles responses to an ajax request:
7545  * - finds the right dataType (mediates between content-type and expected dataType)
7546  * - returns the corresponding response
7547  */
7548 function ajaxHandleResponses( s, jqXHR, responses ) {
7549
7550         var ct, type, finalDataType, firstDataType,
7551                 contents = s.contents,
7552                 dataTypes = s.dataTypes;
7553
7554         // Remove auto dataType and get content-type in the process
7555         while( dataTypes[ 0 ] === "*" ) {
7556                 dataTypes.shift();
7557                 if ( ct === undefined ) {
7558                         ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7559                 }
7560         }
7561
7562         // Check if we're dealing with a known content-type
7563         if ( ct ) {
7564                 for ( type in contents ) {
7565                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
7566                                 dataTypes.unshift( type );
7567                                 break;
7568                         }
7569                 }
7570         }
7571
7572         // Check to see if we have a response for the expected dataType
7573         if ( dataTypes[ 0 ] in responses ) {
7574                 finalDataType = dataTypes[ 0 ];
7575         } else {
7576                 // Try convertible dataTypes
7577                 for ( type in responses ) {
7578                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7579                                 finalDataType = type;
7580                                 break;
7581                         }
7582                         if ( !firstDataType ) {
7583                                 firstDataType = type;
7584                         }
7585                 }
7586                 // Or just use first one
7587                 finalDataType = finalDataType || firstDataType;
7588         }
7589
7590         // If we found a dataType
7591         // We add the dataType to the list if needed
7592         // and return the corresponding response
7593         if ( finalDataType ) {
7594                 if ( finalDataType !== dataTypes[ 0 ] ) {
7595                         dataTypes.unshift( finalDataType );
7596                 }
7597                 return responses[ finalDataType ];
7598         }
7599 }
7600
7601 /* Chain conversions given the request and the original response
7602  * Also sets the responseXXX fields on the jqXHR instance
7603  */
7604 function ajaxConvert( s, response, jqXHR, isSuccess ) {
7605         var conv2, current, conv, tmp, prev,
7606                 converters = {},
7607                 // Work with a copy of dataTypes in case we need to modify it for conversion
7608                 dataTypes = s.dataTypes.slice();
7609
7610         // Create converters map with lowercased keys
7611         if ( dataTypes[ 1 ] ) {
7612                 for ( conv in s.converters ) {
7613                         converters[ conv.toLowerCase() ] = s.converters[ conv ];
7614                 }
7615         }
7616
7617         current = dataTypes.shift();
7618
7619         // Convert to each sequential dataType
7620         while ( current ) {
7621
7622                 if ( s.responseFields[ current ] ) {
7623                         jqXHR[ s.responseFields[ current ] ] = response;
7624                 }
7625
7626                 // Apply the dataFilter if provided
7627                 if ( !prev && isSuccess && s.dataFilter ) {
7628                         response = s.dataFilter( response, s.dataType );
7629                 }
7630
7631                 prev = current;
7632                 current = dataTypes.shift();
7633
7634                 if ( current ) {
7635
7636                 // There's only work to do if current dataType is non-auto
7637                         if ( current === "*" ) {
7638
7639                                 current = prev;
7640
7641                         // Convert response if prev dataType is non-auto and differs from current
7642                         } else if ( prev !== "*" && prev !== current ) {
7643
7644                                 // Seek a direct converter
7645                                 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7646
7647                                 // If none found, seek a pair
7648                                 if ( !conv ) {
7649                                         for ( conv2 in converters ) {
7650
7651                                                 // If conv2 outputs current
7652                                                 tmp = conv2.split( " " );
7653                                                 if ( tmp[ 1 ] === current ) {
7654
7655                                                         // If prev can be converted to accepted input
7656                                                         conv = converters[ prev + " " + tmp[ 0 ] ] ||
7657                                                                 converters[ "* " + tmp[ 0 ] ];
7658                                                         if ( conv ) {
7659                                                                 // Condense equivalence converters
7660                                                                 if ( conv === true ) {
7661                                                                         conv = converters[ conv2 ];
7662
7663                                                                 // Otherwise, insert the intermediate dataType
7664                                                                 } else if ( converters[ conv2 ] !== true ) {
7665                                                                         current = tmp[ 0 ];
7666                                                                         dataTypes.unshift( tmp[ 1 ] );
7667                                                                 }
7668                                                                 break;
7669                                                         }
7670                                                 }
7671                                         }
7672                                 }
7673
7674                                 // Apply converter (if not an equivalence)
7675                                 if ( conv !== true ) {
7676
7677                                         // Unless errors are allowed to bubble, catch and return them
7678                                         if ( conv && s[ "throws" ] ) {
7679                                                 response = conv( response );
7680                                         } else {
7681                                                 try {
7682                                                         response = conv( response );
7683                                                 } catch ( e ) {
7684                                                         return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7685                                                 }
7686                                         }
7687                                 }
7688                         }
7689                 }
7690         }
7691
7692         return { state: "success", data: response };
7693 }
7694 // Install script dataType
7695 jQuery.ajaxSetup({
7696         accepts: {
7697                 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7698         },
7699         contents: {
7700                 script: /(?:java|ecma)script/
7701         },
7702         converters: {
7703                 "text script": function( text ) {
7704                         jQuery.globalEval( text );
7705                         return text;
7706                 }
7707         }
7708 });
7709
7710 // Handle cache's special case and crossDomain
7711 jQuery.ajaxPrefilter( "script", function( s ) {
7712         if ( s.cache === undefined ) {
7713                 s.cache = false;
7714         }
7715         if ( s.crossDomain ) {
7716                 s.type = "GET";
7717         }
7718 });
7719
7720 // Bind script tag hack transport
7721 jQuery.ajaxTransport( "script", function( s ) {
7722         // This transport only deals with cross domain requests
7723         if ( s.crossDomain ) {
7724                 var script, callback;
7725                 return {
7726                         send: function( _, complete ) {
7727                                 script = jQuery("<script>").prop({
7728                                         async: true,
7729                                         charset: s.scriptCharset,
7730                                         src: s.url
7731                                 }).on(
7732                                         "load error",
7733                                         callback = function( evt ) {
7734                                                 script.remove();
7735                                                 callback = null;
7736                                                 if ( evt ) {
7737                                                         complete( evt.type === "error" ? 404 : 200, evt.type );
7738                                                 }
7739                                         }
7740                                 );
7741                                 document.head.appendChild( script[ 0 ] );
7742                         },
7743                         abort: function() {
7744                                 if ( callback ) {
7745                                         callback();
7746                                 }
7747                         }
7748                 };
7749         }
7750 });
7751 var oldCallbacks = [],
7752         rjsonp = /(=)\?(?=&|$)|\?\?/;
7753
7754 // Default jsonp settings
7755 jQuery.ajaxSetup({
7756         jsonp: "callback",
7757         jsonpCallback: function() {
7758                 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
7759                 this[ callback ] = true;
7760                 return callback;
7761         }
7762 });
7763
7764 // Detect, normalize options and install callbacks for jsonp requests
7765 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7766
7767         var callbackName, overwritten, responseContainer,
7768                 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
7769                         "url" :
7770                         typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
7771                 );
7772
7773         // Handle iff the expected data type is "jsonp" or we have a parameter to set
7774         if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
7775
7776                 // Get callback name, remembering preexisting value associated with it
7777                 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
7778                         s.jsonpCallback() :
7779                         s.jsonpCallback;
7780
7781                 // Insert callback into url or form data
7782                 if ( jsonProp ) {
7783                         s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
7784                 } else if ( s.jsonp !== false ) {
7785                         s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
7786                 }
7787
7788                 // Use data converter to retrieve json after script execution
7789                 s.converters["script json"] = function() {
7790                         if ( !responseContainer ) {
7791                                 jQuery.error( callbackName + " was not called" );
7792                         }
7793                         return responseContainer[ 0 ];
7794                 };
7795
7796                 // force json dataType
7797                 s.dataTypes[ 0 ] = "json";
7798
7799                 // Install callback
7800                 overwritten = window[ callbackName ];
7801                 window[ callbackName ] = function() {
7802                         responseContainer = arguments;
7803                 };
7804
7805                 // Clean-up function (fires after converters)
7806                 jqXHR.always(function() {
7807                         // Restore preexisting value
7808                         window[ callbackName ] = overwritten;
7809
7810                         // Save back as free
7811                         if ( s[ callbackName ] ) {
7812                                 // make sure that re-using the options doesn't screw things around
7813                                 s.jsonpCallback = originalSettings.jsonpCallback;
7814
7815                                 // save the callback name for future use
7816                                 oldCallbacks.push( callbackName );
7817                         }
7818
7819                         // Call if it was a function and we have a response
7820                         if ( responseContainer && jQuery.isFunction( overwritten ) ) {
7821                                 overwritten( responseContainer[ 0 ] );
7822                         }
7823
7824                         responseContainer = overwritten = undefined;
7825                 });
7826
7827                 // Delegate to script
7828                 return "script";
7829         }
7830 });
7831 jQuery.ajaxSettings.xhr = function() {
7832         try {
7833                 return new XMLHttpRequest();
7834         } catch( e ) {}
7835 };
7836
7837 var xhrSupported = jQuery.ajaxSettings.xhr(),
7838         xhrSuccessStatus = {
7839                 // file protocol always yields status code 0, assume 200
7840                 0: 200,
7841                 // Support: IE9
7842                 // #1450: sometimes IE returns 1223 when it should be 204
7843                 1223: 204
7844         },
7845         // Support: IE9
7846         // We need to keep track of outbound xhr and abort them manually
7847         // because IE is not smart enough to do it all by itself
7848         xhrId = 0,
7849         xhrCallbacks = {};
7850
7851 if ( window.ActiveXObject ) {
7852         jQuery( window ).on( "unload", function() {
7853                 for( var key in xhrCallbacks ) {
7854                         xhrCallbacks[ key ]();
7855                 }
7856                 xhrCallbacks = undefined;
7857         });
7858 }
7859
7860 jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
7861 jQuery.support.ajax = xhrSupported = !!xhrSupported;
7862
7863 jQuery.ajaxTransport(function( options ) {
7864         var callback;
7865         // Cross domain only allowed if supported through XMLHttpRequest
7866         if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
7867                 return {
7868                         send: function( headers, complete ) {
7869                                 var i, id,
7870                                         xhr = options.xhr();
7871                                 xhr.open( options.type, options.url, options.async, options.username, options.password );
7872                                 // Apply custom fields if provided
7873                                 if ( options.xhrFields ) {
7874                                         for ( i in options.xhrFields ) {
7875                                                 xhr[ i ] = options.xhrFields[ i ];
7876                                         }
7877                                 }
7878                                 // Override mime type if needed
7879                                 if ( options.mimeType && xhr.overrideMimeType ) {
7880                                         xhr.overrideMimeType( options.mimeType );
7881                                 }
7882                                 // X-Requested-With header
7883                                 // For cross-domain requests, seeing as conditions for a preflight are
7884                                 // akin to a jigsaw puzzle, we simply never set it to be sure.
7885                                 // (it can always be set on a per-request basis or even using ajaxSetup)
7886                                 // For same-domain requests, won't change header if already provided.
7887                                 if ( !options.crossDomain && !headers["X-Requested-With"] ) {
7888                                         headers["X-Requested-With"] = "XMLHttpRequest";
7889                                 }
7890                                 // Set headers
7891                                 for ( i in headers ) {
7892                                         xhr.setRequestHeader( i, headers[ i ] );
7893                                 }
7894                                 // Callback
7895                                 callback = function( type ) {
7896                                         return function() {
7897                                                 if ( callback ) {
7898                                                         delete xhrCallbacks[ id ];
7899                                                         callback = xhr.onload = xhr.onerror = null;
7900                                                         if ( type === "abort" ) {
7901                                                                 xhr.abort();
7902                                                         } else if ( type === "error" ) {
7903                                                                 complete(
7904                                                                         // file protocol always yields status 0, assume 404
7905                                                                         xhr.status || 404,
7906                                                                         xhr.statusText
7907                                                                 );
7908                                                         } else {
7909                                                                 complete(
7910                                                                         xhrSuccessStatus[ xhr.status ] || xhr.status,
7911                                                                         xhr.statusText,
7912                                                                         // Support: IE9
7913                                                                         // #11426: When requesting binary data, IE9 will throw an exception
7914                                                                         // on any attempt to access responseText
7915                                                                         typeof xhr.responseText === "string" ? {
7916                                                                                 text: xhr.responseText
7917                                                                         } : undefined,
7918                                                                         xhr.getAllResponseHeaders()
7919                                                                 );
7920                                                         }
7921                                                 }
7922                                         };
7923                                 };
7924                                 // Listen to events
7925                                 xhr.onload = callback();
7926                                 xhr.onerror = callback("error");
7927                                 // Create the abort callback
7928                                 callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
7929                                 // Do send the request
7930                                 // This may raise an exception which is actually
7931                                 // handled in jQuery.ajax (so no try/catch here)
7932                                 xhr.send( options.hasContent && options.data || null );
7933                         },
7934                         abort: function() {
7935                                 if ( callback ) {
7936                                         callback();
7937                                 }
7938                         }
7939                 };
7940         }
7941 });
7942 var fxNow, timerId,
7943         rfxtypes = /^(?:toggle|show|hide)$/,
7944         rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
7945         rrun = /queueHooks$/,
7946         animationPrefilters = [ defaultPrefilter ],
7947         tweeners = {
7948                 "*": [function( prop, value ) {
7949                         var tween = this.createTween( prop, value ),
7950                                 target = tween.cur(),
7951                                 parts = rfxnum.exec( value ),
7952                                 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
7953
7954                                 // Starting value computation is required for potential unit mismatches
7955                                 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
7956                                         rfxnum.exec( jQuery.css( tween.elem, prop ) ),
7957                                 scale = 1,
7958                                 maxIterations = 20;
7959
7960                         if ( start && start[ 3 ] !== unit ) {
7961                                 // Trust units reported by jQuery.css
7962                                 unit = unit || start[ 3 ];
7963
7964                                 // Make sure we update the tween properties later on
7965                                 parts = parts || [];
7966
7967                                 // Iteratively approximate from a nonzero starting point
7968                                 start = +target || 1;
7969
7970                                 do {
7971                                         // If previous iteration zeroed out, double until we get *something*
7972                                         // Use a string for doubling factor so we don't accidentally see scale as unchanged below
7973                                         scale = scale || ".5";
7974
7975                                         // Adjust and apply
7976                                         start = start / scale;
7977                                         jQuery.style( tween.elem, prop, start + unit );
7978
7979                                 // Update scale, tolerating zero or NaN from tween.cur()
7980                                 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
7981                                 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
7982                         }
7983
7984                         // Update tween properties
7985                         if ( parts ) {
7986                                 start = tween.start = +start || +target || 0;
7987                                 tween.unit = unit;
7988                                 // If a +=/-= token was provided, we're doing a relative animation
7989                                 tween.end = parts[ 1 ] ?
7990                                         start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
7991                                         +parts[ 2 ];
7992                         }
7993
7994                         return tween;
7995                 }]
7996         };
7997
7998 // Animations created synchronously will run synchronously
7999 function createFxNow() {
8000         setTimeout(function() {
8001                 fxNow = undefined;
8002         });
8003         return ( fxNow = jQuery.now() );
8004 }
8005
8006 function createTween( value, prop, animation ) {
8007         var tween,
8008                 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8009                 index = 0,
8010                 length = collection.length;
8011         for ( ; index < length; index++ ) {
8012                 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
8013
8014                         // we're done with this property
8015                         return tween;
8016                 }
8017         }
8018 }
8019
8020 function Animation( elem, properties, options ) {
8021         var result,
8022                 stopped,
8023                 index = 0,
8024                 length = animationPrefilters.length,
8025                 deferred = jQuery.Deferred().always( function() {
8026                         // don't match elem in the :animated selector
8027                         delete tick.elem;
8028                 }),
8029                 tick = function() {
8030                         if ( stopped ) {
8031                                 return false;
8032                         }
8033                         var currentTime = fxNow || createFxNow(),
8034                                 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8035                                 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
8036                                 temp = remaining / animation.duration || 0,
8037                                 percent = 1 - temp,
8038                                 index = 0,
8039                                 length = animation.tweens.length;
8040
8041                         for ( ; index < length ; index++ ) {
8042                                 animation.tweens[ index ].run( percent );
8043                         }
8044
8045                         deferred.notifyWith( elem, [ animation, percent, remaining ]);
8046
8047                         if ( percent < 1 && length ) {
8048                                 return remaining;
8049                         } else {
8050                                 deferred.resolveWith( elem, [ animation ] );
8051                                 return false;
8052                         }
8053                 },
8054                 animation = deferred.promise({
8055                         elem: elem,
8056                         props: jQuery.extend( {}, properties ),
8057                         opts: jQuery.extend( true, { specialEasing: {} }, options ),
8058                         originalProperties: properties,
8059                         originalOptions: options,
8060                         startTime: fxNow || createFxNow(),
8061                         duration: options.duration,
8062                         tweens: [],
8063                         createTween: function( prop, end ) {
8064                                 var tween = jQuery.Tween( elem, animation.opts, prop, end,
8065                                                 animation.opts.specialEasing[ prop ] || animation.opts.easing );
8066                                 animation.tweens.push( tween );
8067                                 return tween;
8068                         },
8069                         stop: function( gotoEnd ) {
8070                                 var index = 0,
8071                                         // if we are going to the end, we want to run all the tweens
8072                                         // otherwise we skip this part
8073                                         length = gotoEnd ? animation.tweens.length : 0;
8074                                 if ( stopped ) {
8075                                         return this;
8076                                 }
8077                                 stopped = true;
8078                                 for ( ; index < length ; index++ ) {
8079                                         animation.tweens[ index ].run( 1 );
8080                                 }
8081
8082                                 // resolve when we played the last frame
8083                                 // otherwise, reject
8084                                 if ( gotoEnd ) {
8085                                         deferred.resolveWith( elem, [ animation, gotoEnd ] );
8086                                 } else {
8087                                         deferred.rejectWith( elem, [ animation, gotoEnd ] );
8088                                 }
8089                                 return this;
8090                         }
8091                 }),
8092                 props = animation.props;
8093
8094         propFilter( props, animation.opts.specialEasing );
8095
8096         for ( ; index < length ; index++ ) {
8097                 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8098                 if ( result ) {
8099                         return result;
8100                 }
8101         }
8102
8103         jQuery.map( props, createTween, animation );
8104
8105         if ( jQuery.isFunction( animation.opts.start ) ) {
8106                 animation.opts.start.call( elem, animation );
8107         }
8108
8109         jQuery.fx.timer(
8110                 jQuery.extend( tick, {
8111                         elem: elem,
8112                         anim: animation,
8113                         queue: animation.opts.queue
8114                 })
8115         );
8116
8117         // attach callbacks from options
8118         return animation.progress( animation.opts.progress )
8119                 .done( animation.opts.done, animation.opts.complete )
8120                 .fail( animation.opts.fail )
8121                 .always( animation.opts.always );
8122 }
8123
8124 function propFilter( props, specialEasing ) {
8125         var index, name, easing, value, hooks;
8126
8127         // camelCase, specialEasing and expand cssHook pass
8128         for ( index in props ) {
8129                 name = jQuery.camelCase( index );
8130                 easing = specialEasing[ name ];
8131                 value = props[ index ];
8132                 if ( jQuery.isArray( value ) ) {
8133                         easing = value[ 1 ];
8134                         value = props[ index ] = value[ 0 ];
8135                 }
8136
8137                 if ( index !== name ) {
8138                         props[ name ] = value;
8139                         delete props[ index ];
8140                 }
8141
8142                 hooks = jQuery.cssHooks[ name ];
8143                 if ( hooks && "expand" in hooks ) {
8144                         value = hooks.expand( value );
8145                         delete props[ name ];
8146
8147                         // not quite $.extend, this wont overwrite keys already present.
8148                         // also - reusing 'index' from above because we have the correct "name"
8149                         for ( index in value ) {
8150                                 if ( !( index in props ) ) {
8151                                         props[ index ] = value[ index ];
8152                                         specialEasing[ index ] = easing;
8153                                 }
8154                         }
8155                 } else {
8156                         specialEasing[ name ] = easing;
8157                 }
8158         }
8159 }
8160
8161 jQuery.Animation = jQuery.extend( Animation, {
8162
8163         tweener: function( props, callback ) {
8164                 if ( jQuery.isFunction( props ) ) {
8165                         callback = props;
8166                         props = [ "*" ];
8167                 } else {
8168                         props = props.split(" ");
8169                 }
8170
8171                 var prop,
8172                         index = 0,
8173                         length = props.length;
8174
8175                 for ( ; index < length ; index++ ) {
8176                         prop = props[ index ];
8177                         tweeners[ prop ] = tweeners[ prop ] || [];
8178                         tweeners[ prop ].unshift( callback );
8179                 }
8180         },
8181
8182         prefilter: function( callback, prepend ) {
8183                 if ( prepend ) {
8184                         animationPrefilters.unshift( callback );
8185                 } else {
8186                         animationPrefilters.push( callback );
8187                 }
8188         }
8189 });
8190
8191 function defaultPrefilter( elem, props, opts ) {
8192         /* jshint validthis: true */
8193         var prop, value, toggle, tween, hooks, oldfire,
8194                 anim = this,
8195                 orig = {},
8196                 style = elem.style,
8197                 hidden = elem.nodeType && isHidden( elem ),
8198                 dataShow = data_priv.get( elem, "fxshow" );
8199
8200         // handle queue: false promises
8201         if ( !opts.queue ) {
8202                 hooks = jQuery._queueHooks( elem, "fx" );
8203                 if ( hooks.unqueued == null ) {
8204                         hooks.unqueued = 0;
8205                         oldfire = hooks.empty.fire;
8206                         hooks.empty.fire = function() {
8207                                 if ( !hooks.unqueued ) {
8208                                         oldfire();
8209                                 }
8210                         };
8211                 }
8212                 hooks.unqueued++;
8213
8214                 anim.always(function() {
8215                         // doing this makes sure that the complete handler will be called
8216                         // before this completes
8217                         anim.always(function() {
8218                                 hooks.unqueued--;
8219                                 if ( !jQuery.queue( elem, "fx" ).length ) {
8220                                         hooks.empty.fire();
8221                                 }
8222                         });
8223                 });
8224         }
8225
8226         // height/width overflow pass
8227         if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8228                 // Make sure that nothing sneaks out
8229                 // Record all 3 overflow attributes because IE9-10 do not
8230                 // change the overflow attribute when overflowX and
8231                 // overflowY are set to the same value
8232                 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8233
8234                 // Set display property to inline-block for height/width
8235                 // animations on inline elements that are having width/height animated
8236                 if ( jQuery.css( elem, "display" ) === "inline" &&
8237                                 jQuery.css( elem, "float" ) === "none" ) {
8238
8239                         style.display = "inline-block";
8240                 }
8241         }
8242
8243         if ( opts.overflow ) {
8244                 style.overflow = "hidden";
8245                 anim.always(function() {
8246                         style.overflow = opts.overflow[ 0 ];
8247                         style.overflowX = opts.overflow[ 1 ];
8248                         style.overflowY = opts.overflow[ 2 ];
8249                 });
8250         }
8251
8252
8253         // show/hide pass
8254         for ( prop in props ) {
8255                 value = props[ prop ];
8256                 if ( rfxtypes.exec( value ) ) {
8257                         delete props[ prop ];
8258                         toggle = toggle || value === "toggle";
8259                         if ( value === ( hidden ? "hide" : "show" ) ) {
8260
8261                                 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
8262                                 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
8263                                         hidden = true;
8264                                 } else {
8265                                         continue;
8266                                 }
8267                         }
8268                         orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
8269                 }
8270         }
8271
8272         if ( !jQuery.isEmptyObject( orig ) ) {
8273                 if ( dataShow ) {
8274                         if ( "hidden" in dataShow ) {
8275                                 hidden = dataShow.hidden;
8276                         }
8277                 } else {
8278                         dataShow = data_priv.access( elem, "fxshow", {} );
8279                 }
8280
8281                 // store state if its toggle - enables .stop().toggle() to "reverse"
8282                 if ( toggle ) {
8283                         dataShow.hidden = !hidden;
8284                 }
8285                 if ( hidden ) {
8286                         jQuery( elem ).show();
8287                 } else {
8288                         anim.done(function() {
8289                                 jQuery( elem ).hide();
8290                         });
8291                 }
8292                 anim.done(function() {
8293                         var prop;
8294
8295                         data_priv.remove( elem, "fxshow" );
8296                         for ( prop in orig ) {
8297                                 jQuery.style( elem, prop, orig[ prop ] );
8298                         }
8299                 });
8300                 for ( prop in orig ) {
8301                         tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
8302
8303                         if ( !( prop in dataShow ) ) {
8304                                 dataShow[ prop ] = tween.start;
8305                                 if ( hidden ) {
8306                                         tween.end = tween.start;
8307                                         tween.start = prop === "width" || prop === "height" ? 1 : 0;
8308                                 }
8309                         }
8310                 }
8311         }
8312 }
8313
8314 function Tween( elem, options, prop, end, easing ) {
8315         return new Tween.prototype.init( elem, options, prop, end, easing );
8316 }
8317 jQuery.Tween = Tween;
8318
8319 Tween.prototype = {
8320         constructor: Tween,
8321         init: function( elem, options, prop, end, easing, unit ) {
8322                 this.elem = elem;
8323                 this.prop = prop;
8324                 this.easing = easing || "swing";
8325                 this.options = options;
8326                 this.start = this.now = this.cur();
8327                 this.end = end;
8328                 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8329         },
8330         cur: function() {
8331                 var hooks = Tween.propHooks[ this.prop ];
8332
8333                 return hooks && hooks.get ?
8334                         hooks.get( this ) :
8335                         Tween.propHooks._default.get( this );
8336         },
8337         run: function( percent ) {
8338                 var eased,
8339                         hooks = Tween.propHooks[ this.prop ];
8340
8341                 if ( this.options.duration ) {
8342                         this.pos = eased = jQuery.easing[ this.easing ](
8343                                 percent, this.options.duration * percent, 0, 1, this.options.duration
8344                         );
8345                 } else {
8346                         this.pos = eased = percent;
8347                 }
8348                 this.now = ( this.end - this.start ) * eased + this.start;
8349
8350                 if ( this.options.step ) {
8351                         this.options.step.call( this.elem, this.now, this );
8352                 }
8353
8354                 if ( hooks && hooks.set ) {
8355                         hooks.set( this );
8356                 } else {
8357                         Tween.propHooks._default.set( this );
8358                 }
8359                 return this;
8360         }
8361 };
8362
8363 Tween.prototype.init.prototype = Tween.prototype;
8364
8365 Tween.propHooks = {
8366         _default: {
8367                 get: function( tween ) {
8368                         var result;
8369
8370                         if ( tween.elem[ tween.prop ] != null &&
8371                                 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8372                                 return tween.elem[ tween.prop ];
8373                         }
8374
8375                         // passing an empty string as a 3rd parameter to .css will automatically
8376                         // attempt a parseFloat and fallback to a string if the parse fails
8377                         // so, simple values such as "10px" are parsed to Float.
8378                         // complex values such as "rotate(1rad)" are returned as is.
8379                         result = jQuery.css( tween.elem, tween.prop, "" );
8380                         // Empty strings, null, undefined and "auto" are converted to 0.
8381                         return !result || result === "auto" ? 0 : result;
8382                 },
8383                 set: function( tween ) {
8384                         // use step hook for back compat - use cssHook if its there - use .style if its
8385                         // available and use plain properties where available
8386                         if ( jQuery.fx.step[ tween.prop ] ) {
8387                                 jQuery.fx.step[ tween.prop ]( tween );
8388                         } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8389                                 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8390                         } else {
8391                                 tween.elem[ tween.prop ] = tween.now;
8392                         }
8393                 }
8394         }
8395 };
8396
8397 // Support: IE9
8398 // Panic based approach to setting things on disconnected nodes
8399
8400 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
8401         set: function( tween ) {
8402                 if ( tween.elem.nodeType && tween.elem.parentNode ) {
8403                         tween.elem[ tween.prop ] = tween.now;
8404                 }
8405         }
8406 };
8407
8408 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
8409         var cssFn = jQuery.fn[ name ];
8410         jQuery.fn[ name ] = function( speed, easing, callback ) {
8411                 return speed == null || typeof speed === "boolean" ?
8412                         cssFn.apply( this, arguments ) :
8413                         this.animate( genFx( name, true ), speed, easing, callback );
8414         };
8415 });
8416
8417 jQuery.fn.extend({
8418         fadeTo: function( speed, to, easing, callback ) {
8419
8420                 // show any hidden elements after setting opacity to 0
8421                 return this.filter( isHidden ).css( "opacity", 0 ).show()
8422
8423                         // animate to the value specified
8424                         .end().animate({ opacity: to }, speed, easing, callback );
8425         },
8426         animate: function( prop, speed, easing, callback ) {
8427                 var empty = jQuery.isEmptyObject( prop ),
8428                         optall = jQuery.speed( speed, easing, callback ),
8429                         doAnimation = function() {
8430                                 // Operate on a copy of prop so per-property easing won't be lost
8431                                 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
8432
8433                                 // Empty animations, or finishing resolves immediately
8434                                 if ( empty || data_priv.get( this, "finish" ) ) {
8435                                         anim.stop( true );
8436                                 }
8437                         };
8438                         doAnimation.finish = doAnimation;
8439
8440                 return empty || optall.queue === false ?
8441                         this.each( doAnimation ) :
8442                         this.queue( optall.queue, doAnimation );
8443         },
8444         stop: function( type, clearQueue, gotoEnd ) {
8445                 var stopQueue = function( hooks ) {
8446                         var stop = hooks.stop;
8447                         delete hooks.stop;
8448                         stop( gotoEnd );
8449                 };
8450
8451                 if ( typeof type !== "string" ) {
8452                         gotoEnd = clearQueue;
8453                         clearQueue = type;
8454                         type = undefined;
8455                 }
8456                 if ( clearQueue && type !== false ) {
8457                         this.queue( type || "fx", [] );
8458                 }
8459
8460                 return this.each(function() {
8461                         var dequeue = true,
8462                                 index = type != null && type + "queueHooks",
8463                                 timers = jQuery.timers,
8464                                 data = data_priv.get( this );
8465
8466                         if ( index ) {
8467                                 if ( data[ index ] && data[ index ].stop ) {
8468                                         stopQueue( data[ index ] );
8469                                 }
8470                         } else {
8471                                 for ( index in data ) {
8472                                         if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
8473                                                 stopQueue( data[ index ] );
8474                                         }
8475                                 }
8476                         }
8477
8478                         for ( index = timers.length; index--; ) {
8479                                 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
8480                                         timers[ index ].anim.stop( gotoEnd );
8481                                         dequeue = false;
8482                                         timers.splice( index, 1 );
8483                                 }
8484                         }
8485
8486                         // start the next in the queue if the last step wasn't forced
8487                         // timers currently will call their complete callbacks, which will dequeue
8488                         // but only if they were gotoEnd
8489                         if ( dequeue || !gotoEnd ) {
8490                                 jQuery.dequeue( this, type );
8491                         }
8492                 });
8493         },
8494         finish: function( type ) {
8495                 if ( type !== false ) {
8496                         type = type || "fx";
8497                 }
8498                 return this.each(function() {
8499                         var index,
8500                                 data = data_priv.get( this ),
8501                                 queue = data[ type + "queue" ],
8502                                 hooks = data[ type + "queueHooks" ],
8503                                 timers = jQuery.timers,
8504                                 length = queue ? queue.length : 0;
8505
8506                         // enable finishing flag on private data
8507                         data.finish = true;
8508
8509                         // empty the queue first
8510                         jQuery.queue( this, type, [] );
8511
8512                         if ( hooks && hooks.stop ) {
8513                                 hooks.stop.call( this, true );
8514                         }
8515
8516                         // look for any active animations, and finish them
8517                         for ( index = timers.length; index--; ) {
8518                                 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8519                                         timers[ index ].anim.stop( true );
8520                                         timers.splice( index, 1 );
8521                                 }
8522                         }
8523
8524                         // look for any animations in the old queue and finish them
8525                         for ( index = 0; index < length; index++ ) {
8526                                 if ( queue[ index ] && queue[ index ].finish ) {
8527                                         queue[ index ].finish.call( this );
8528                                 }
8529                         }
8530
8531                         // turn off finishing flag
8532                         delete data.finish;
8533                 });
8534         }
8535 });
8536
8537 // Generate parameters to create a standard animation
8538 function genFx( type, includeWidth ) {
8539         var which,
8540                 attrs = { height: type },
8541                 i = 0;
8542
8543         // if we include width, step value is 1 to do all cssExpand values,
8544         // if we don't include width, step value is 2 to skip over Left and Right
8545         includeWidth = includeWidth? 1 : 0;
8546         for( ; i < 4 ; i += 2 - includeWidth ) {
8547                 which = cssExpand[ i ];
8548                 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
8549         }
8550
8551         if ( includeWidth ) {
8552                 attrs.opacity = attrs.width = type;
8553         }
8554
8555         return attrs;
8556 }
8557
8558 // Generate shortcuts for custom animations
8559 jQuery.each({
8560         slideDown: genFx("show"),
8561         slideUp: genFx("hide"),
8562         slideToggle: genFx("toggle"),
8563         fadeIn: { opacity: "show" },
8564         fadeOut: { opacity: "hide" },
8565         fadeToggle: { opacity: "toggle" }
8566 }, function( name, props ) {
8567         jQuery.fn[ name ] = function( speed, easing, callback ) {
8568                 return this.animate( props, speed, easing, callback );
8569         };
8570 });
8571
8572 jQuery.speed = function( speed, easing, fn ) {
8573         var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8574                 complete: fn || !fn && easing ||
8575                         jQuery.isFunction( speed ) && speed,
8576                 duration: speed,
8577                 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8578         };
8579
8580         opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8581                 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8582
8583         // normalize opt.queue - true/undefined/null -> "fx"
8584         if ( opt.queue == null || opt.queue === true ) {
8585                 opt.queue = "fx";
8586         }
8587
8588         // Queueing
8589         opt.old = opt.complete;
8590
8591         opt.complete = function() {
8592                 if ( jQuery.isFunction( opt.old ) ) {
8593                         opt.old.call( this );
8594                 }
8595
8596                 if ( opt.queue ) {
8597                         jQuery.dequeue( this, opt.queue );
8598                 }
8599         };
8600
8601         return opt;
8602 };
8603
8604 jQuery.easing = {
8605         linear: function( p ) {
8606                 return p;
8607         },
8608         swing: function( p ) {
8609                 return 0.5 - Math.cos( p*Math.PI ) / 2;
8610         }
8611 };
8612
8613 jQuery.timers = [];
8614 jQuery.fx = Tween.prototype.init;
8615 jQuery.fx.tick = function() {
8616         var timer,
8617                 timers = jQuery.timers,
8618                 i = 0;
8619
8620         fxNow = jQuery.now();
8621
8622         for ( ; i < timers.length; i++ ) {
8623                 timer = timers[ i ];
8624                 // Checks the timer has not already been removed
8625                 if ( !timer() && timers[ i ] === timer ) {
8626                         timers.splice( i--, 1 );
8627                 }
8628         }
8629
8630         if ( !timers.length ) {
8631                 jQuery.fx.stop();
8632         }
8633         fxNow = undefined;
8634 };
8635
8636 jQuery.fx.timer = function( timer ) {
8637         if ( timer() && jQuery.timers.push( timer ) ) {
8638                 jQuery.fx.start();
8639         }
8640 };
8641
8642 jQuery.fx.interval = 13;
8643
8644 jQuery.fx.start = function() {
8645         if ( !timerId ) {
8646                 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
8647         }
8648 };
8649
8650 jQuery.fx.stop = function() {
8651         clearInterval( timerId );
8652         timerId = null;
8653 };
8654
8655 jQuery.fx.speeds = {
8656         slow: 600,
8657         fast: 200,
8658         // Default speed
8659         _default: 400
8660 };
8661
8662 // Back Compat <1.8 extension point
8663 jQuery.fx.step = {};
8664
8665 if ( jQuery.expr && jQuery.expr.filters ) {
8666         jQuery.expr.filters.animated = function( elem ) {
8667                 return jQuery.grep(jQuery.timers, function( fn ) {
8668                         return elem === fn.elem;
8669                 }).length;
8670         };
8671 }
8672 jQuery.fn.offset = function( options ) {
8673         if ( arguments.length ) {
8674                 return options === undefined ?
8675                         this :
8676                         this.each(function( i ) {
8677                                 jQuery.offset.setOffset( this, options, i );
8678                         });
8679         }
8680
8681         var docElem, win,
8682                 elem = this[ 0 ],
8683                 box = { top: 0, left: 0 },
8684                 doc = elem && elem.ownerDocument;
8685
8686         if ( !doc ) {
8687                 return;
8688         }
8689
8690         docElem = doc.documentElement;
8691
8692         // Make sure it's not a disconnected DOM node
8693         if ( !jQuery.contains( docElem, elem ) ) {
8694                 return box;
8695         }
8696
8697         // If we don't have gBCR, just use 0,0 rather than error
8698         // BlackBerry 5, iOS 3 (original iPhone)
8699         if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
8700                 box = elem.getBoundingClientRect();
8701         }
8702         win = getWindow( doc );
8703         return {
8704                 top: box.top + win.pageYOffset - docElem.clientTop,
8705                 left: box.left + win.pageXOffset - docElem.clientLeft
8706         };
8707 };
8708
8709 jQuery.offset = {
8710
8711         setOffset: function( elem, options, i ) {
8712                 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8713                         position = jQuery.css( elem, "position" ),
8714                         curElem = jQuery( elem ),
8715                         props = {};
8716
8717                 // Set position first, in-case top/left are set even on static elem
8718                 if ( position === "static" ) {
8719                         elem.style.position = "relative";
8720                 }
8721
8722                 curOffset = curElem.offset();
8723                 curCSSTop = jQuery.css( elem, "top" );
8724                 curCSSLeft = jQuery.css( elem, "left" );
8725                 calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8726
8727                 // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8728                 if ( calculatePosition ) {
8729                         curPosition = curElem.position();
8730                         curTop = curPosition.top;
8731                         curLeft = curPosition.left;
8732
8733                 } else {
8734                         curTop = parseFloat( curCSSTop ) || 0;
8735                         curLeft = parseFloat( curCSSLeft ) || 0;
8736                 }
8737
8738                 if ( jQuery.isFunction( options ) ) {
8739                         options = options.call( elem, i, curOffset );
8740                 }
8741
8742                 if ( options.top != null ) {
8743                         props.top = ( options.top - curOffset.top ) + curTop;
8744                 }
8745                 if ( options.left != null ) {
8746                         props.left = ( options.left - curOffset.left ) + curLeft;
8747                 }
8748
8749                 if ( "using" in options ) {
8750                         options.using.call( elem, props );
8751
8752                 } else {
8753                         curElem.css( props );
8754                 }
8755         }
8756 };
8757
8758
8759 jQuery.fn.extend({
8760
8761         position: function() {
8762                 if ( !this[ 0 ] ) {
8763                         return;
8764                 }
8765
8766                 var offsetParent, offset,
8767                         elem = this[ 0 ],
8768                         parentOffset = { top: 0, left: 0 };
8769
8770                 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
8771                 if ( jQuery.css( elem, "position" ) === "fixed" ) {
8772                         // We assume that getBoundingClientRect is available when computed position is fixed
8773                         offset = elem.getBoundingClientRect();
8774
8775                 } else {
8776                         // Get *real* offsetParent
8777                         offsetParent = this.offsetParent();
8778
8779                         // Get correct offsets
8780                         offset = this.offset();
8781                         if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
8782                                 parentOffset = offsetParent.offset();
8783                         }
8784
8785                         // Add offsetParent borders
8786                         parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
8787                         parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
8788                 }
8789
8790                 // Subtract parent offsets and element margins
8791                 return {
8792                         top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
8793                         left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
8794                 };
8795         },
8796
8797         offsetParent: function() {
8798                 return this.map(function() {
8799                         var offsetParent = this.offsetParent || docElem;
8800
8801                         while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
8802                                 offsetParent = offsetParent.offsetParent;
8803                         }
8804
8805                         return offsetParent || docElem;
8806                 });
8807         }
8808 });
8809
8810
8811 // Create scrollLeft and scrollTop methods
8812 jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
8813         var top = "pageYOffset" === prop;
8814
8815         jQuery.fn[ method ] = function( val ) {
8816                 return jQuery.access( this, function( elem, method, val ) {
8817                         var win = getWindow( elem );
8818
8819                         if ( val === undefined ) {
8820                                 return win ? win[ prop ] : elem[ method ];
8821                         }
8822
8823                         if ( win ) {
8824                                 win.scrollTo(
8825                                         !top ? val : window.pageXOffset,
8826                                         top ? val : window.pageYOffset
8827                                 );
8828
8829                         } else {
8830                                 elem[ method ] = val;
8831                         }
8832                 }, method, val, arguments.length, null );
8833         };
8834 });
8835
8836 function getWindow( elem ) {
8837         return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8838 }
8839 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
8840 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
8841         jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
8842                 // margin is only for outerHeight, outerWidth
8843                 jQuery.fn[ funcName ] = function( margin, value ) {
8844                         var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
8845                                 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
8846
8847                         return jQuery.access( this, function( elem, type, value ) {
8848                                 var doc;
8849
8850                                 if ( jQuery.isWindow( elem ) ) {
8851                                         // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
8852                                         // isn't a whole lot we can do. See pull request at this URL for discussion:
8853                                         // https://github.com/jquery/jquery/pull/764
8854                                         return elem.document.documentElement[ "client" + name ];
8855                                 }
8856
8857                                 // Get document width or height
8858                                 if ( elem.nodeType === 9 ) {
8859                                         doc = elem.documentElement;
8860
8861                                         // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
8862                                         // whichever is greatest
8863                                         return Math.max(
8864                                                 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
8865                                                 elem.body[ "offset" + name ], doc[ "offset" + name ],
8866                                                 doc[ "client" + name ]
8867                                         );
8868                                 }
8869
8870                                 return value === undefined ?
8871                                         // Get width or height on the element, requesting but not forcing parseFloat
8872                                         jQuery.css( elem, type, extra ) :
8873
8874                                         // Set width or height on the element
8875                                         jQuery.style( elem, type, value, extra );
8876                         }, type, chainable ? margin : undefined, chainable, null );
8877                 };
8878         });
8879 });
8880 // Limit scope pollution from any deprecated API
8881 // (function() {
8882
8883 // The number of elements contained in the matched element set
8884 jQuery.fn.size = function() {
8885         return this.length;
8886 };
8887
8888 jQuery.fn.andSelf = jQuery.fn.addBack;
8889
8890 // })();
8891 // Expose jQuery and $ identifiers, even in
8892 // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
8893 // and CommonJS for browser emulators (#13566)
8894 return (window.jQuery = window.$ = jQuery);
8895
8896 }));
8897
8898 /**
8899  * @license
8900  * Lo-Dash 2.4.1 <http://lodash.com/>
8901  * Copyright 2012-2014 The Dojo Foundation <http://dojofoundation.org/>
8902  * Based on Underscore.js 1.6.0 <http://underscorejs.org/LICENSE>
8903  * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8904  * Available under MIT license <http://lodash.com/license>
8905  */
8906 ;(function() {
8907
8908   /** Used as a safe reference for `undefined` in pre ES5 environments */
8909   var undefined;
8910
8911   /** Used to compose bitmasks for wrapper metadata */
8912   var BIND_FLAG = 1,
8913       BIND_KEY_FLAG = 2,
8914       CURRY_FLAG = 4,
8915       CURRY_BOUND_FLAG = 8,
8916       PARTIAL_FLAG = 16,
8917       PARTIAL_RIGHT_FLAG = 32;
8918
8919   /** Used as the size when optimizations are enabled for arrays */
8920   var LARGE_ARRAY_SIZE = 40;
8921
8922   /** Used as the max size of the `arrayPool` and `objectPool` */
8923   var MAX_POOL_SIZE = 40;
8924
8925   /** Used as the semantic version number */
8926   var version = '2.4.1';
8927
8928   /** Used as the property name for wrapper metadata */
8929   var expando = '__lodash@' + version + '__';
8930
8931   /** Used to generate unique IDs */
8932   var idCounter = 0;
8933
8934   /** Used to match empty string literals in compiled template source */
8935   var reEmptyStringLeading = /\b__p \+= '';/g,
8936       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
8937       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
8938
8939   /** Used to match HTML entities and HTML characters */
8940   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
8941       reUnescapedHtml = /[&<>"']/g;
8942
8943   /** Used to match template delimiters */
8944   var reEscape = /<%-([\s\S]+?)%>/g,
8945       reEvaluate = /<%([\s\S]+?)%>/g,
8946       reInterpolate = /<%=([\s\S]+?)%>/g;
8947
8948   /**
8949    * Used to match ES6 template delimiters
8950    * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
8951    */
8952   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
8953
8954   /** Used to match regexp flags from their coerced string values */
8955   var reFlags = /\w*$/;
8956
8957   /** Used to detected named functions */
8958   var reFuncName = /^\s*function[ \n\r\t]+\w/;
8959
8960   /** Used to detect hexadecimal string values */
8961   var reHexPrefix = /^0[xX]/;
8962
8963   /** Used to ensure capturing order of template delimiters */
8964   var reNoMatch = /($^)/;
8965
8966   /** Used to detect functions containing a `this` reference */
8967   var reThis = /\bthis\b/;
8968
8969   /** Used to match unescaped characters in compiled string literals */
8970   var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
8971
8972   /** Used to detect and test whitespace */
8973   var whitespace = (
8974     // whitespace
8975     ' \t\x0B\f\xA0\ufeff' +
8976
8977     // line terminators
8978     '\n\r\u2028\u2029' +
8979
8980     // unicode category "Zs" space separators
8981     '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
8982   );
8983
8984   /** Used to pool arrays and objects used internally */
8985   var arrayPool = [],
8986       objectPool = [];
8987
8988   /** Used to assign default `context` object properties */
8989   var contextProps = [
8990     'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
8991     'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', 'isFinite', 'isNaN',
8992     'parseInt', 'setTimeout', 'TypeError', 'window', 'WinRTError'
8993   ];
8994
8995   /** Used to fix the JScript [[DontEnum]] bug */
8996   var shadowedProps = [
8997     'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
8998     'toLocaleString', 'toString', 'valueOf'
8999   ];
9000
9001   /** Used to make template sourceURLs easier to identify */
9002   var templateCounter = 0;
9003
9004   /** `Object#toString` result shortcuts */
9005   var argsClass = '[object Arguments]',
9006       arrayClass = '[object Array]',
9007       boolClass = '[object Boolean]',
9008       dateClass = '[object Date]',
9009       errorClass = '[object Error]',
9010       funcClass = '[object Function]',
9011       numberClass = '[object Number]',
9012       objectClass = '[object Object]',
9013       regexpClass = '[object RegExp]',
9014       stringClass = '[object String]';
9015
9016   /** Used to identify object classifications that `_.clone` supports */
9017   var cloneableClasses = {};
9018   cloneableClasses[funcClass] = false;
9019   cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
9020   cloneableClasses[boolClass] = cloneableClasses[dateClass] =
9021   cloneableClasses[numberClass] = cloneableClasses[objectClass] =
9022   cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
9023
9024   /** Used as an internal `_.debounce` options object */
9025   var debounceOptions = {
9026     'leading': false,
9027     'maxWait': 0,
9028     'trailing': false
9029   };
9030
9031   /** Used as the property descriptor for wrapper metadata */
9032   var descriptor = {
9033     'configurable': false,
9034     'enumerable': false,
9035     'value': null,
9036     'writable': false
9037   };
9038
9039   /**
9040    * Used to convert characters to HTML entities.
9041    *
9042    * Note: Though the ">" character is escaped for symmetry, characters like
9043    * ">", "`", and "/" don't require escaping in HTML and have no special meaning
9044    * unless they're part of a tag or unquoted attribute value.
9045    * See [Mathias' article](http://mathiasbynens.be/notes/ambiguous-ampersands)
9046    * (under "semi-related fun fact") for more details.
9047    */
9048   var htmlEscapes = {
9049     '&': '&amp;',
9050     '<': '&lt;',
9051     '>': '&gt;',
9052     '"': '&quot;',
9053     "'": '&#39;'
9054   };
9055
9056   /** Used to convert HTML entities to characters */
9057   var htmlUnescapes = {
9058     '&amp;': '&',
9059     '&lt;': '<',
9060     '&gt;': '>',
9061     '&quot;': '"',
9062     '&#39;': "'"
9063   };
9064
9065   /** Used to determine if values are of the language type Object */
9066   var objectTypes = {
9067     'function': true,
9068     'object': true
9069   };
9070
9071   /** Used to escape characters for inclusion in compiled string literals */
9072   var stringEscapes = {
9073     '\\': '\\',
9074     "'": "'",
9075     '\n': 'n',
9076     '\r': 'r',
9077     '\t': 't',
9078     '\u2028': 'u2028',
9079     '\u2029': 'u2029'
9080   };
9081
9082   /** Used as a reference to the global object */
9083   var root = (objectTypes[typeof window] && window) || this;
9084
9085   /** Detect free variable `exports` */
9086   var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
9087
9088   /** Detect free variable `module` */
9089   var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
9090
9091   /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
9092   var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
9093   if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
9094     root = freeGlobal;
9095   }
9096
9097   /** Detect the popular CommonJS extension `module.exports` */
9098   var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
9099
9100   /*--------------------------------------------------------------------------*/
9101
9102   /**
9103    * The base implementation of `compareAscending` used to compare values and
9104    * sort them in ascending order without guaranteeing a stable sort.
9105    *
9106    * @private
9107    * @param {*} a The value to compare to `b`.
9108    * @param {*} b The value to compare to `a`.
9109    * @returns {number} Returns the sort order indicator for `a`.
9110    */
9111   function baseCompareAscending(a, b) {
9112     if (a !== b) {
9113       if (a > b || typeof a == 'undefined') {
9114         return 1;
9115       }
9116       if (a < b || typeof b == 'undefined') {
9117         return -1;
9118       }
9119     }
9120     return 0;
9121   }
9122
9123   /**
9124    * The base implementation of `_.indexOf` without support for binary searches.
9125    *
9126    * @private
9127    * @param {Array} array The array to search.
9128    * @param {*} value The value to search for.
9129    * @param {number} [fromIndex=0] The index to search from.
9130    * @returns {number} Returns the index of the matched value or `-1`.
9131    */
9132   function baseIndexOf(array, value, fromIndex) {
9133     var index = (fromIndex || 0) - 1,
9134         length = array ? array.length : 0;
9135
9136     while (++index < length) {
9137       if (array[index] === value) {
9138         return index;
9139       }
9140     }
9141     return -1;
9142   }
9143
9144   /**
9145    * An implementation of `_.contains` for cache objects that mimics the return
9146    * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
9147    *
9148    * @private
9149    * @param {Object} cache The cache object to inspect.
9150    * @param {*} value The value to search for.
9151    * @returns {number} Returns `0` if `value` is found, else `-1`.
9152    */
9153   function cacheIndexOf(cache, value) {
9154     return cache.has(value) ? 0 : -1;
9155   }
9156
9157   /**
9158    * Used by `_.max` and `_.min` as the default callback when a given
9159    * collection is a string value.
9160    *
9161    * @private
9162    * @param {string} value The character to inspect.
9163    * @returns {number} Returns the code unit of given character.
9164    */
9165   function charAtCallback(value) {
9166     return value.charCodeAt(0);
9167   }
9168
9169   /**
9170    * Gets the index of the first character of `string` that is not found in `chars`.
9171    *
9172    * @private
9173    * @param {string} string The string to inspect.
9174    * @returns {number} Returns the index of the first character not found in `chars`.
9175    */
9176   function charsLeftIndex(string, chars) {
9177     var index = -1,
9178         length = string.length;
9179
9180     while (++index < length) {
9181       if (chars.indexOf(string.charAt(index)) < 0) {
9182         break;
9183       }
9184     }
9185     return index;
9186   }
9187
9188   /**
9189    * Gets the index of the last character of `string` that is not found in `chars`.
9190    *
9191    * @private
9192    * @param {string} string The string to inspect.
9193    * @returns {number} Returns the index of the last character not found in `chars`.
9194    */
9195   function charsRightIndex(string, chars) {
9196     var index = string.length;
9197     while (index--) {
9198       if (chars.indexOf(string.charAt(index)) < 0) {
9199         break;
9200       }
9201     }
9202     return index;
9203   }
9204
9205   /**
9206    * Used by `sortBy` to compare transformed elements of a collection and stable
9207    * sort them in ascending order.
9208    *
9209    * @private
9210    * @param {Object} a The object to compare to `b`.
9211    * @param {Object} b The object to compare to `a`.
9212    * @returns {number} Returns the sort order indicator for `a`.
9213    */
9214   function compareAscending(a, b) {
9215     return baseCompareAscending(a.criteria, b.criteria) || a.index - b.index;
9216   }
9217
9218   /**
9219    * Used by `sortBy` to compare multiple properties of each element in a
9220    * collection and stable sort them in ascending order.
9221    *
9222    * @private
9223    * @param {Object} a The object to compare to `b`.
9224    * @param {Object} b The object to compare to `a`.
9225    * @returns {number} Returns the sort order indicator for `a`.
9226    */
9227   function compareMultipleAscending(a, b) {
9228     var ac = a.criteria,
9229         bc = b.criteria,
9230         index = -1,
9231         length = ac.length;
9232
9233     while (++index < length) {
9234       var result = baseCompareAscending(ac[index], bc[index]);
9235       if (result) {
9236         return result;
9237       }
9238     }
9239     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
9240     // that causes it, under certain circumstances, to provided the same value
9241     // for `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
9242     //
9243     // This also ensures a stable sort in V8 and other engines.
9244     // See https://code.google.com/p/v8/issues/detail?id=90
9245     return a.index - b.index;
9246   }
9247
9248   /**
9249    * Used by `escape` to convert characters to HTML entities.
9250    *
9251    * @private
9252    * @param {string} match The matched character to escape.
9253    * @returns {string} Returns the escaped character.
9254    */
9255   function escapeHtmlChar(match) {
9256     return htmlEscapes[match];
9257   }
9258
9259   /**
9260    * Used by `template` to escape characters for inclusion in compiled
9261    * string literals.
9262    *
9263    * @private
9264    * @param {string} match The matched character to escape.
9265    * @returns {string} Returns the escaped character.
9266    */
9267   function escapeStringChar(match) {
9268     return '\\' + stringEscapes[match];
9269   }
9270
9271   /**
9272    * Gets an array from the array pool or creates a new one if the pool is empty.
9273    *
9274    * @private
9275    * @returns {Array} The array from the pool.
9276    */
9277   function getArray() {
9278     return arrayPool.pop() || [];
9279   }
9280
9281   /**
9282    * Gets an object from the object pool or creates a new one if the pool is empty.
9283    *
9284    * @private
9285    * @returns {Object} The object from the pool.
9286    */
9287   function getObject() {
9288     return objectPool.pop() || {
9289       'criteria': null,
9290       'index': 0,
9291       'value': null
9292     };
9293   }
9294
9295   /**
9296    * Checks if `value` is a DOM node in IE < 9.
9297    *
9298    * @private
9299    * @param {*} value The value to check.
9300    * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
9301    */
9302   function isNode(value) {
9303     // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
9304     // methods that are `typeof` "string" and still can coerce nodes to strings
9305     return typeof value.toString != 'function' && typeof (value + '') == 'string';
9306   }
9307
9308   /**
9309    * Releases `array` back to the array pool.
9310    *
9311    * @private
9312    * @param {Array} array The array to release.
9313    */
9314   function releaseArray(array) {
9315     array.length = 0;
9316     if (arrayPool.length < MAX_POOL_SIZE) {
9317       arrayPool.push(array);
9318     }
9319   }
9320
9321   /**
9322    * Releases `object` back to the object pool.
9323    *
9324    * @private
9325    * @param {Object} object The object to release.
9326    */
9327   function releaseObject(object) {
9328     object.criteria = object.value = null;
9329     if (objectPool.length < MAX_POOL_SIZE) {
9330       objectPool.push(object);
9331     }
9332   }
9333
9334   /**
9335    * A fallback implementation of `trim` to remove leading and trailing
9336    * whitespace or specified characters from `string`.
9337    *
9338    * @private
9339    * @param {string} string The string to trim.
9340    * @param {string} [chars=whitespace] The characters to trim.
9341    * @returns {string} Returns the trimmed string.
9342    */
9343   function shimTrim(string, chars) {
9344     string = string == null ? '' : String(string);
9345     if (!string) {
9346       return string;
9347     }
9348     if (chars == null) {
9349       return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
9350     }
9351     chars = String(chars);
9352     return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
9353   }
9354
9355   /**
9356    * A fallback implementation of `trimLeft` to remove leading whitespace or
9357    * specified characters from `string`.
9358    *
9359    * @private
9360    * @param {string} string The string to trim.
9361    * @param {string} [chars=whitespace] The characters to trim.
9362    * @returns {string} Returns the trimmed string.
9363    */
9364   function shimTrimLeft(string, chars) {
9365     string = string == null ? '' : String(string);
9366     if (!string) {
9367       return string;
9368     }
9369     if (chars == null) {
9370       return string.slice(trimmedLeftIndex(string))
9371     }
9372     chars = String(chars);
9373     return string.slice(charsLeftIndex(string, chars));
9374   }
9375
9376   /**
9377    * A fallback implementation of `trimRight` to remove trailing whitespace or
9378    * specified characters from `string`.
9379    *
9380    * @private
9381    * @param {string} string The string to trim.
9382    * @param {string} [chars=whitespace] The characters to trim.
9383    * @returns {string} Returns the trimmed string.
9384    */
9385   function shimTrimRight(string, chars) {
9386     string = string == null ? '' : String(string);
9387     if (!string) {
9388       return string;
9389     }
9390     if (chars == null) {
9391       return string.slice(0, trimmedRightIndex(string) + 1)
9392     }
9393     chars = String(chars);
9394     return string.slice(0, charsRightIndex(string, chars) + 1);
9395   }
9396
9397   /**
9398    * Gets the index of the first non-whitespace character of `string`.
9399    *
9400    * @private
9401    * @param {string} string The string to inspect.
9402    * @returns {number} Returns the index of the first non-whitespace character.
9403    */
9404   function trimmedLeftIndex(string) {
9405     var index = -1,
9406         length = string.length;
9407
9408     while (++index < length) {
9409       var c = string.charCodeAt(index);
9410       if (!((c <= 160 && (c >= 9 && c <= 13) || c == 32 || c == 160) || c == 5760 || c == 6158 ||
9411           (c >= 8192 && (c <= 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)))) {
9412         break;
9413       }
9414     }
9415     return index;
9416   }
9417
9418   /**
9419    * Gets the index of the last non-whitespace character of `string`.
9420    *
9421    * @private
9422    * @param {string} string The string to inspect.
9423    * @returns {number} Returns the index of the last non-whitespace character.
9424    */
9425   function trimmedRightIndex(string) {
9426     var index = string.length;
9427     while (index--) {
9428       var c = string.charCodeAt(index);
9429       if (!((c <= 160 && (c >= 9 && c <= 13) || c == 32 || c == 160) || c == 5760 || c == 6158 ||
9430           (c >= 8192 && (c <= 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)))) {
9431         break;
9432       }
9433     }
9434     return index;
9435   }
9436
9437   /**
9438    * Used by `unescape` to convert HTML entities to characters.
9439    *
9440    * @private
9441    * @param {string} match The matched character to unescape.
9442    * @returns {string} Returns the unescaped character.
9443    */
9444   function unescapeHtmlChar(match) {
9445     return htmlUnescapes[match];
9446   }
9447
9448   /*--------------------------------------------------------------------------*/
9449
9450   /**
9451    * Create a new `lodash` function using the given context object.
9452    *
9453    * @static
9454    * @memberOf _
9455    * @category Utilities
9456    * @param {Object} [context=root] The context object.
9457    * @returns {Function} Returns a new `lodash` function.
9458    */
9459   function runInContext(context) {
9460     // Avoid issues with some ES3 environments that attempt to use values, named
9461     // after built-in constructors like `Object`, for the creation of literals.
9462     // ES5 clears this up by stating that literals must use built-in constructors.
9463     // See http://es5.github.io/#x11.1.5.
9464     context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
9465
9466     /** Native constructor references */
9467     var Array = context.Array,
9468         Boolean = context.Boolean,
9469         Date = context.Date,
9470         Error = context.Error,
9471         Function = context.Function,
9472         Math = context.Math,
9473         Number = context.Number,
9474         Object = context.Object,
9475         RegExp = context.RegExp,
9476         String = context.String,
9477         TypeError = context.TypeError;
9478
9479     /** Used for native method references */
9480     var arrayRef = Array.prototype,
9481         errorProto = Error.prototype,
9482         objectProto = Object.prototype,
9483         stringProto = String.prototype;
9484
9485     /** Used to detect DOM support */
9486     var document = (document = context.window) && document.document;
9487
9488     /** Used to restore the original `_` reference in `noConflict` */
9489     var oldDash = context._;
9490
9491     /** Used to resolve the internal [[Class]] of values */
9492     var toString = objectProto.toString;
9493
9494     /** Used to detect if a method is native */
9495     var reNative = RegExp('^' +
9496       String(toString)
9497         .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
9498         .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
9499     );
9500
9501     /** Native method shortcuts */
9502     var ceil = Math.ceil,
9503         clearTimeout = context.clearTimeout,
9504         floor = Math.floor,
9505         fnToString = Function.prototype.toString,
9506         getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
9507         hasOwnProperty = objectProto.hasOwnProperty,
9508         push = arrayRef.push,
9509         propertyIsEnumerable = objectProto.propertyIsEnumerable,
9510         Set = isNative(Set = context.Set) && Set,
9511         setTimeout = context.setTimeout,
9512         splice = arrayRef.splice,
9513         unshift = arrayRef.unshift;
9514
9515     /** Used to set meta data on functions */
9516     var defineProperty = (function() {
9517       // IE 8 only accepts DOM elements
9518       try {
9519         var o = {},
9520             func = isNative(func = Object.defineProperty) && func,
9521             result = func(o, o, o) && func;
9522       } catch(e) { }
9523       return result;
9524     }());
9525
9526     /* Native method shortcuts for methods with the same name as other `lodash` methods */
9527     var nativeContains = isNative(nativeContains = stringProto.contains) && nativeContains,
9528         nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
9529         nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
9530         nativeIsFinite = context.isFinite,
9531         nativeIsNaN = context.isNaN,
9532         nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
9533         nativeMax = Math.max,
9534         nativeMin = Math.min,
9535         nativeNow = isNative(nativeNow = Date.now) && nativeNow,
9536         nativeParseInt = context.parseInt,
9537         nativeRandom = Math.random,
9538         nativeTrim = isNative(nativeTrim = stringProto.trim) && !nativeTrim.call(whitespace) && nativeTrim,
9539         nativeTrimLeft = isNative(nativeTrimLeft = stringProto.trimLeft) && !nativeTrimLeft.call(whitespace) && nativeTrimLeft,
9540         nativeTrimRight = isNative(nativeTrimRight = stringProto.trimRight) && !nativeTrimRight.call(whitespace) && nativeTrimRight;
9541
9542     /** Used to lookup a built-in constructor by [[Class]] */
9543     var ctorByClass = {};
9544     ctorByClass[arrayClass] = Array;
9545     ctorByClass[boolClass] = Boolean;
9546     ctorByClass[dateClass] = Date;
9547     ctorByClass[funcClass] = Function;
9548     ctorByClass[objectClass] = Object;
9549     ctorByClass[numberClass] = Number;
9550     ctorByClass[regexpClass] = RegExp;
9551     ctorByClass[stringClass] = String;
9552
9553     /** Used to avoid iterating non-enumerable properties in IE < 9 */
9554     var nonEnumProps = {};
9555     nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
9556     nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
9557     nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
9558     nonEnumProps[objectClass] = { 'constructor': true };
9559
9560     (function() {
9561       var length = shadowedProps.length;
9562       while (length--) {
9563         var key = shadowedProps[length];
9564         for (var className in nonEnumProps) {
9565           if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
9566             nonEnumProps[className][key] = false;
9567           }
9568         }
9569       }
9570     }());
9571
9572     /*--------------------------------------------------------------------------*/
9573
9574     /**
9575      * Creates a `lodash` object which wraps the given value to enable intuitive
9576      * method chaining.
9577      *
9578      * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
9579      * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
9580      * and `unshift`
9581      *
9582      * Chaining is supported in custom builds as long as the `value` method is
9583      * implicitly or explicitly included in the build.
9584      *
9585      * The chainable wrapper functions are:
9586      * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
9587      * `compose`, `concat`, `constant`, `countBy`, `create`, `createCallback`,
9588      * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`,
9589      * `flatten`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
9590      * `forOwnRight`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`,
9591      * `invert`, `invoke`, `keys`, `map`, `mapValues`, `matches`, `max`, `memoize`,
9592      * `merge`, `min`, `noop`, `object`, `omit`, `once`, `pairs`, `partial`,
9593      * `partialRight`, `pick`, `pluck`, `property`, `pull`, `push`, `range`,
9594      * `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`,
9595      * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`,
9596      * `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, `xor`,
9597      * and `zip`
9598      *
9599      * The non-chainable wrapper functions are:
9600      * `capitalize`, `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`,
9601      * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`,
9602      * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
9603      * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
9604      * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
9605      * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `now`,
9606      * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`,
9607      * `size`, `some`, `sortedIndex`, `runInContext`, `template`, `trim`,
9608      * `trimLeft`, `trimRight`, `unescape`, `uniqueId`, and `value`
9609      *
9610      * The wrapper functions `first`, `last`, and `sample` return wrapped values
9611      * when `n` is provided, otherwise they return unwrapped values.
9612      *
9613      * Explicit chaining can be enabled by using the `_.chain` method.
9614      *
9615      * @name _
9616      * @constructor
9617      * @category Chaining
9618      * @param {*} value The value to wrap in a `lodash` instance.
9619      * @returns {Object} Returns a `lodash` instance.
9620      * @example
9621      *
9622      * var wrapped = _([1, 2, 3]);
9623      *
9624      * // returns an unwrapped value
9625      * wrapped.reduce(function(sum, num) {
9626      *   return sum + num;
9627      * });
9628      * // => 6
9629      *
9630      * // returns a wrapped value
9631      * var squares = wrapped.map(function(num) {
9632      *   return num * num;
9633      * });
9634      *
9635      * _.isArray(squares);
9636      * // => false
9637      *
9638      * _.isArray(squares.value());
9639      * // => true
9640      */
9641     function lodash(value) {
9642       // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
9643       return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
9644        ? value
9645        : new lodashWrapper(value);
9646     }
9647
9648     /**
9649      * A fast path for creating `lodash` wrapper objects.
9650      *
9651      * @private
9652      * @param {*} value The value to wrap in a `lodash` instance.
9653      * @param {boolean} [chainAll=false] A flag to enable chaining for all methods
9654      * @returns {Object} Returns a `lodash` instance.
9655      */
9656     function lodashWrapper(value, chainAll) {
9657       this.__chain__ = !!chainAll;
9658       this.__wrapped__ = value;
9659     }
9660     // ensure `new lodashWrapper` is an instance of `lodash`
9661     lodashWrapper.prototype = lodash.prototype;
9662
9663     /**
9664      * An object used to flag environments features.
9665      *
9666      * @static
9667      * @memberOf _
9668      * @type Object
9669      */
9670     var support = lodash.support = {};
9671
9672     (function() {
9673       var ctor = function() { this.x = 1; },
9674           object = { '0': 1, 'length': 1 },
9675           props = [];
9676
9677       ctor.prototype = { 'valueOf': 1, 'y': 1 };
9678       for (var key in new ctor) { props.push(key); }
9679       for (key in arguments) { }
9680
9681       /**
9682        * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
9683        *
9684        * @memberOf _.support
9685        * @type boolean
9686        */
9687       support.argsClass = toString.call(arguments) == argsClass;
9688
9689       /**
9690        * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
9691        *
9692        * @memberOf _.support
9693        * @type boolean
9694        */
9695       support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
9696
9697       /**
9698        * Detect if `name` or `message` properties of `Error.prototype` are
9699        * enumerable by default. (IE < 9, Safari < 5.1)
9700        *
9701        * @memberOf _.support
9702        * @type boolean
9703        */
9704       support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
9705
9706       /**
9707        * Detect if `prototype` properties are enumerable by default.
9708        *
9709        * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
9710        * (if the prototype or a property on the prototype has been set)
9711        * incorrectly sets a function's `prototype` property [[Enumerable]]
9712        * value to `true`.
9713        *
9714        * @memberOf _.support
9715        * @type boolean
9716        */
9717       support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
9718
9719       /**
9720        * Detect if functions can be decompiled by `Function#toString`
9721        * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
9722        *
9723        * @memberOf _.support
9724        * @type boolean
9725        */
9726       support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
9727
9728       /**
9729        * Detect if `Function#name` is supported (all but IE).
9730        *
9731        * @memberOf _.support
9732        * @type boolean
9733        */
9734       support.funcNames = typeof Function.name == 'string';
9735
9736       /**
9737        * Detect if `arguments` object indexes are non-enumerable
9738        * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
9739        *
9740        * @memberOf _.support
9741        * @type boolean
9742        */
9743       support.nonEnumArgs = key != 0;
9744
9745       /**
9746        * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
9747        *
9748        * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
9749        * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
9750        *
9751        * @memberOf _.support
9752        * @type boolean
9753        */
9754       support.nonEnumShadows = !/valueOf/.test(props);
9755
9756       /**
9757        * Detect if own properties are iterated after inherited properties (all but IE < 9).
9758        *
9759        * @memberOf _.support
9760        * @type boolean
9761        */
9762       support.ownLast = props[0] != 'x';
9763
9764       /**
9765        * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
9766        *
9767        * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
9768        * and `splice()` functions that fail to remove the last element, `value[0]`,
9769        * of array-like objects even though the `length` property is set to `0`.
9770        * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
9771        * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
9772        *
9773        * @memberOf _.support
9774        * @type boolean
9775        */
9776       support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
9777
9778       /**
9779        * Detect lack of support for accessing string characters by index.
9780        *
9781        * IE < 8 can't access characters by index and IE 8 can only access
9782        * characters by index on string literals.
9783        *
9784        * @memberOf _.support
9785        * @type boolean
9786        */
9787       support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
9788
9789       /**
9790        * Detect if the DOM is supported.
9791        *
9792        * @memberOf _.support
9793        * @type boolean
9794        */
9795       try {
9796         support.dom = document.createDocumentFragment().nodeType === 11;
9797       } catch(e) {
9798         support.dom = false;
9799       }
9800
9801       /**
9802        * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
9803        * and that the JS engine errors when attempting to coerce an object to
9804        * a string without a `toString` function.
9805        *
9806        * @memberOf _.support
9807        * @type boolean
9808        */
9809       try {
9810         support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
9811       } catch(e) {
9812         support.nodeClass = true;
9813       }
9814     }(1));
9815
9816     /**
9817      * By default, the template delimiters used by Lo-Dash are similar to those in
9818      * embedded Ruby (ERB). Change the following template settings to use alternative
9819      * delimiters.
9820      *
9821      * @static
9822      * @memberOf _
9823      * @type Object
9824      */
9825     lodash.templateSettings = {
9826
9827       /**
9828        * Used to detect `data` property values to be HTML-escaped.
9829        *
9830        * @memberOf _.templateSettings
9831        * @type RegExp
9832        */
9833       'escape': reEscape,
9834
9835       /**
9836        * Used to detect code to be evaluated.
9837        *
9838        * @memberOf _.templateSettings
9839        * @type RegExp
9840        */
9841       'evaluate': reEvaluate,
9842
9843       /**
9844        * Used to detect `data` property values to inject.
9845        *
9846        * @memberOf _.templateSettings
9847        * @type RegExp
9848        */
9849       'interpolate': reInterpolate,
9850
9851       /**
9852        * Used to reference the data object in the template text.
9853        *
9854        * @memberOf _.templateSettings
9855        * @type string
9856        */
9857       'variable': '',
9858
9859       /**
9860        * Used to import variables into the compiled template.
9861        *
9862        * @memberOf _.templateSettings
9863        * @type Object
9864        */
9865       'imports': {
9866
9867         /**
9868          * A reference to the `lodash` function.
9869          *
9870          * @memberOf _.templateSettings.imports
9871          * @type Function
9872          */
9873         '_': lodash
9874       }
9875     };
9876
9877     /*--------------------------------------------------------------------------*/
9878
9879     /**
9880      * The template used to create iterator functions.
9881      *
9882      * @private
9883      * @param {Object} data The data object used to populate the text.
9884      * @returns {string} Returns the interpolated text.
9885      */
9886     var iteratorTemplate = template(
9887       // assign the `result` variable an initial value
9888       'var result = <%= init %>;\n' +
9889
9890       // exit early if the first argument is not an object
9891       "if (!isObject(object)) {\n" +
9892       '  return result;\n' +
9893       '}' +
9894
9895       // add support for iterating over `arguments` objects if needed
9896       '<% if (support.nonEnumArgs) { %>\n' +
9897       'var length = object.length;\n' +
9898       'if (length && isArguments(object)) {\n' +
9899       '  key = -1;\n' +
9900       '  while (++key < length) {\n' +
9901       "    key += '';\n" +
9902       '    <%= loop %>;\n' +
9903       '  }\n' +
9904       '  return result;\n' +
9905       '}' +
9906       '<% } %>' +
9907
9908       // avoid iterating over `prototype` properties in older Firefox, Opera, and Safari
9909       '<% if (support.enumPrototypes) { %>\n' +
9910       "var skipProto = typeof object == 'function';\n" +
9911       '<% } %>' +
9912
9913       // avoid iterating over `Error.prototype` properties in older IE and Safari
9914       '<% if (support.enumErrorProps) { %>\n' +
9915       'var skipErrorProps = object === errorProto || object instanceof Error;\n' +
9916       '<% } %>' +
9917
9918       // define conditions used in the loop
9919       '<%' +
9920       'var conditions = [];\n' +
9921       "if (support.enumPrototypes) { conditions.push('!(skipProto && key == \\'prototype\\')'); }\n" +
9922       "if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (key == \\'message\\' || key == \\'name\\'))'); }" +
9923       '%>\n' +
9924
9925       // iterate over the object
9926       'for (var key in object) {\n<%' +
9927       "  if (useHas) { conditions.push('hasOwnProperty.call(object, key)'); }\n" +
9928       "  if (conditions.length) { %>  if (<%= conditions.join(' && ') %>) {\n  <% } %>" +
9929       '  <%= loop %>;' +
9930       '  <% if (conditions.length) { %>\n  }<% } %>\n' +
9931       '}\n' +
9932
9933       // Lo-Dash skips the `constructor` property when it infers it's iterating
9934       // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
9935       // attribute of an existing property and the `constructor` property of a
9936       // prototype defaults to non-enumerable.
9937       '<% if (support.nonEnumShadows) { %>\n' +
9938       'if (object !== objectProto) {\n' +
9939       "  var ctor = object.constructor,\n" +
9940       '      isProto = object === (ctor && ctor.prototype),\n' +
9941       '      className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object),\n' +
9942       '      nonEnum = nonEnumProps[className];\n' +
9943       '  <% for (var index = 0; index < 7; index++) { %>\n' +
9944       "  key = '<%= shadowedProps[index] %>';\n" +
9945       '  if ((!(isProto && nonEnum[key]) && hasOwnProperty.call(object, key))<%' +
9946       '      if (!useHas) { %> || (!nonEnum[key] && object[key] !== objectProto[key])<% }' +
9947       '    %>) {\n' +
9948       '    <%= loop %>;\n' +
9949       '  }' +
9950       '  <% } %>\n' +
9951       '}' +
9952       '<% } %>\n' +
9953
9954       'return result;'
9955     );
9956
9957     /*--------------------------------------------------------------------------*/
9958
9959     /**
9960      * The base implementation of `_.bind` that creates the bound function and
9961      * sets its meta data.
9962      *
9963      * @private
9964      * @param {Array} data The metadata array.
9965      * @returns {Function} Returns the new bound function.
9966      */
9967     function baseBind(data) {
9968       var func = data[0],
9969           thisArg = data[3],
9970           partialArgs = data[4];
9971
9972       function bound() {
9973         // `Function#bind` spec
9974         // http://es5.github.io/#x15.3.4.5
9975         if (partialArgs) {
9976           // avoid `arguments` object deoptimizations by using `slice` instead
9977           // of `Array.prototype.slice.call` and not assigning `arguments` to a
9978           // variable as a ternary expression
9979           var args = slice(partialArgs);
9980           push.apply(args, arguments);
9981         }
9982         // mimic the constructor's `return` behavior
9983         // http://es5.github.io/#x13.2.2
9984         if (this instanceof bound) {
9985           // ensure `new bound` is an instance of `func`
9986           var thisBinding = baseCreate(func.prototype),
9987               result = func.apply(thisBinding, args || arguments);
9988           return isObject(result) ? result : thisBinding;
9989         }
9990         return func.apply(thisArg, args || arguments);
9991       }
9992       setData(bound, data);
9993       return bound;
9994     }
9995
9996     /**
9997      * The base implementation of `_.clone` without argument juggling or support
9998      * for `thisArg` binding.
9999      *
10000      * @private
10001      * @param {*} value The value to clone.
10002      * @param {boolean} [isDeep=false] Specify a deep clone.
10003      * @param {Function} [callback] The function to customize cloning values.
10004      * @param {Array} [stackA=[]] Tracks traversed source objects.
10005      * @param {Array} [stackB=[]] Associates clones with source counterparts.
10006      * @returns {*} Returns the cloned value.
10007      */
10008     function baseClone(value, isDeep, callback, stackA, stackB) {
10009       if (callback) {
10010         var result = callback(value);
10011         if (typeof result != 'undefined') {
10012           return result;
10013         }
10014       }
10015       // inspect [[Class]]
10016       var isObj = isObject(value);
10017       if (isObj) {
10018         var className = toString.call(value);
10019         if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
10020           return value;
10021         }
10022         var ctor = ctorByClass[className];
10023         switch (className) {
10024           case boolClass:
10025           case dateClass:
10026             return new ctor(+value);
10027
10028           case numberClass:
10029           case stringClass:
10030             return new ctor(value);
10031
10032           case regexpClass:
10033             result = ctor(value.source, reFlags.exec(value));
10034             result.lastIndex = value.lastIndex;
10035             return result;
10036         }
10037       } else {
10038         return value;
10039       }
10040       var isArr = isArray(value);
10041       if (isDeep) {
10042         // check for circular references and return corresponding clone
10043         var initedStack = !stackA;
10044         stackA || (stackA = getArray());
10045         stackB || (stackB = getArray());
10046
10047         var length = stackA.length;
10048         while (length--) {
10049           if (stackA[length] == value) {
10050             return stackB[length];
10051           }
10052         }
10053         result = isArr ? ctor(value.length) : {};
10054       }
10055       else {
10056         result = isArr ? slice(value) : assign({}, value);
10057       }
10058       // add array properties assigned by `RegExp#exec`
10059       if (isArr) {
10060         if (hasOwnProperty.call(value, 'index')) {
10061           result.index = value.index;
10062         }
10063         if (hasOwnProperty.call(value, 'input')) {
10064           result.input = value.input;
10065         }
10066       }
10067       // exit for shallow clone
10068       if (!isDeep) {
10069         return result;
10070       }
10071       // add the source value to the stack of traversed objects
10072       // and associate it with its clone
10073       stackA.push(value);
10074       stackB.push(result);
10075
10076       // recursively populate clone (susceptible to call stack limits)
10077       (isArr ? baseEach : baseForOwn)(value, function(objValue, key) {
10078         result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
10079       });
10080
10081       if (initedStack) {
10082         releaseArray(stackA);
10083         releaseArray(stackB);
10084       }
10085       return result;
10086     }
10087
10088     /**
10089      * The base implementation of `_.create` without support for assigning
10090      * properties to the created object.
10091      *
10092      * @private
10093      * @param {Object} prototype The object to inherit from.
10094      * @returns {Object} Returns the new object.
10095      */
10096     function baseCreate(prototype) {
10097       return isObject(prototype) ? nativeCreate(prototype) : {};
10098     }
10099     // fallback for environments without `Object.create`
10100     if (!nativeCreate) {
10101       baseCreate = (function() {
10102         function Object() {}
10103         return function(prototype) {
10104           if (isObject(prototype)) {
10105             Object.prototype = prototype;
10106             var result = new Object;
10107             Object.prototype = null;
10108           }
10109           return result || context.Object();
10110         };
10111       }());
10112     }
10113
10114     /**
10115      * The base implementation of `_.createCallback` without support for creating
10116      * "_.pluck" or "_.where" style callbacks.
10117      *
10118      * @private
10119      * @param {*} [func=identity] The value to convert to a callback.
10120      * @param {*} [thisArg] The `this` binding of the created callback.
10121      * @param {number} [argCount] The number of arguments the callback accepts.
10122      * @returns {Function} Returns a callback function.
10123      */
10124     function baseCreateCallback(func, thisArg, argCount) {
10125       if (typeof func != 'function') {
10126         return identity;
10127       }
10128       // exit early for no `thisArg` or already bound by `Function#bind`
10129       if (typeof thisArg == 'undefined' || !('prototype' in func)) {
10130         return func;
10131       }
10132       var data = func[expando];
10133       if (typeof data == 'undefined') {
10134         if (support.funcNames) {
10135           data = !func.name;
10136         }
10137         data = data || !support.funcDecomp;
10138         if (!data) {
10139           var source = fnToString.call(func);
10140           if (!support.funcNames) {
10141             data = !reFuncName.test(source);
10142           }
10143           if (!data) {
10144             // checks if `func` references the `this` keyword and stores the result
10145             data = reThis.test(source);
10146             setData(func, data);
10147           }
10148         }
10149       }
10150       // exit early if there are no `this` references or `func` is bound
10151       if (data === false || (data !== true && data[1] & BIND_FLAG)) {
10152         return func;
10153       }
10154       switch (argCount) {
10155         case 1: return function(value) {
10156           return func.call(thisArg, value);
10157         };
10158         case 2: return function(a, b) {
10159           return func.call(thisArg, a, b);
10160         };
10161         case 3: return function(value, index, collection) {
10162           return func.call(thisArg, value, index, collection);
10163         };
10164         case 4: return function(accumulator, value, index, collection) {
10165           return func.call(thisArg, accumulator, value, index, collection);
10166         };
10167       }
10168       return bind(func, thisArg);
10169     }
10170
10171     /**
10172      * The base implementation of `createWrapper` that creates the wrapper and
10173      * sets its meta data.
10174      *
10175      * @private
10176      * @param {Array} data The metadata array.
10177      * @returns {Function} Returns the new function.
10178      */
10179     function baseCreateWrapper(data) {
10180       var func = data[0],
10181           bitmask = data[1],
10182           arity = data[2],
10183           thisArg = data[3],
10184           partialArgs = data[4],
10185           partialRightArgs = data[5];
10186
10187       var isBind = bitmask & BIND_FLAG,
10188           isBindKey = bitmask & BIND_KEY_FLAG,
10189           isCurry = bitmask & CURRY_FLAG,
10190           isCurryBound = bitmask & CURRY_BOUND_FLAG,
10191           key = func;
10192
10193       function bound() {
10194         var thisBinding = isBind ? thisArg : this;
10195         if (partialArgs) {
10196           var args = slice(partialArgs);
10197           push.apply(args, arguments);
10198         }
10199         if (partialRightArgs || isCurry) {
10200           args || (args = slice(arguments));
10201           if (partialRightArgs) {
10202             push.apply(args, partialRightArgs);
10203           }
10204           var argsLength = arguments.length;
10205           if (isCurry && argsLength < arity) {
10206             bitmask |= PARTIAL_FLAG;
10207             bitmask &= ~PARTIAL_RIGHT_FLAG
10208             if (!isCurryBound) {
10209               bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
10210             }
10211             var newArity = nativeMax(0, arity - argsLength);
10212             return baseCreateWrapper([func, bitmask, newArity, thisArg, args]);
10213           }
10214         }
10215         args || (args = arguments);
10216         if (isBindKey) {
10217           func = thisBinding[key];
10218         }
10219         if (this instanceof bound) {
10220           thisBinding = baseCreate(func.prototype);
10221           var result = func.apply(thisBinding, args);
10222           return isObject(result) ? result : thisBinding;
10223         }
10224         return func.apply(thisBinding, args);
10225       }
10226       setData(bound, data);
10227       return bound;
10228     }
10229
10230     /**
10231      * The base implementation of `_.difference` that accepts a single array
10232      * of values to exclude.
10233      *
10234      * @private
10235      * @param {Array} array The array to process.
10236      * @param {Array} [values] The array of values to exclude.
10237      * @returns {Array} Returns a new array of filtered values.
10238      */
10239     function baseDifference(array, values) {
10240       var index = -1,
10241           indexOf = getIndexOf(),
10242           length = array ? array.length : 0,
10243           result = [];
10244
10245       if (createCache && values && indexOf === baseIndexOf && values.length >= LARGE_ARRAY_SIZE) {
10246         indexOf = cacheIndexOf;
10247         values = createCache(values);
10248       }
10249       while (++index < length) {
10250         var value = array[index];
10251         if (indexOf(values, value) < 0) {
10252           result.push(value);
10253         }
10254       }
10255       return result;
10256     }
10257
10258     /**
10259      * The base implementation of `_.forEach` without support for callback
10260      * shorthands or `thisArg` binding.
10261      *
10262      * @private
10263      * @param {Array|Object|string} collection The collection to iterate over.
10264      * @param {Function} callback The function called per iteration.
10265      * @returns {Array|Object|string} Returns `collection`.
10266      */
10267     function baseEach(collection, callback) {
10268       var index = -1,
10269           iterable = collection,
10270           length = collection ? collection.length : 0;
10271
10272       if (typeof length == 'number') {
10273         if (support.unindexedChars && isString(iterable)) {
10274           iterable = iterable.split('');
10275         }
10276         while (++index < length) {
10277           if (callback(iterable[index], index, collection) === false) {
10278             break;
10279           }
10280         }
10281       } else {
10282         baseForOwn(collection, callback);
10283       }
10284       return collection;
10285     }
10286
10287     /**
10288      * The base implementation of `_.forEachRight` without support for callback
10289      * shorthands or `thisArg` binding.
10290      *
10291      * @private
10292      * @param {Array|Object|string} collection The collection to iterate over.
10293      * @param {Function} callback The function called per iteration.
10294      * @returns {Array|Object|string} Returns `collection`.
10295      */
10296     function baseEachRight(collection, callback) {
10297       var iterable = collection,
10298           length = collection ? collection.length : 0;
10299
10300       if (typeof length == 'number') {
10301         if (support.unindexedChars && isString(iterable)) {
10302           iterable = iterable.split('');
10303         }
10304         while (length--) {
10305           if (callback(iterable[length], length, collection) === false) {
10306             break;
10307           }
10308         }
10309       } else {
10310         baseForOwnRight(collection, callback);
10311       }
10312       return collection;
10313     }
10314
10315     /**
10316      * The base implementation of `_.flatten` without support for callback
10317      * shorthands or `thisArg` binding.
10318      *
10319      * @private
10320      * @param {Array} array The array to flatten.
10321      * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
10322      * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
10323      * @param {number} [fromIndex=0] The index to start from.
10324      * @returns {Array} Returns a new flattened array.
10325      */
10326     function baseFlatten(array, isShallow, isStrict, fromIndex) {
10327       var index = (fromIndex || 0) - 1,
10328           length = array ? array.length : 0,
10329           result = [];
10330
10331       while (++index < length) {
10332         var value = array[index];
10333
10334         if (value && typeof value == 'object' && typeof value.length == 'number'
10335             && (isArray(value) || isArguments(value))) {
10336           // recursively flatten arrays (susceptible to call stack limits)
10337           if (!isShallow) {
10338             value = baseFlatten(value, isShallow, isStrict);
10339           }
10340           var valIndex = -1,
10341               valLength = value.length,
10342               resIndex = result.length;
10343
10344           result.length += valLength;
10345           while (++valIndex < valLength) {
10346             result[resIndex++] = value[valIndex];
10347           }
10348         } else if (!isStrict) {
10349           result.push(value);
10350         }
10351       }
10352       return result;
10353     }
10354
10355     /**
10356      * The base implementation of `_.forOwn` without support for callback
10357      * shorthands or `thisArg` binding.
10358      *
10359      * @private
10360      * @param {Object} object The object to iterate over.
10361      * @param {Function} callback The function called per iteration.
10362      * @returns {Object} Returns `object`.
10363      */
10364     function baseForOwn(object, callback) {
10365       var index = -1,
10366           props = keys(object),
10367           length = props.length;
10368
10369       while (++index < length) {
10370         var key = props[index];
10371         if (callback(object[key], key, object) === false) {
10372           break;
10373         }
10374       }
10375       return object;
10376     }
10377
10378     /**
10379      * The base implementation of `_.forOwnRight` without support for callback
10380      * shorthands or `thisArg` binding.
10381      *
10382      * @private
10383      * @param {Object} object The object to iterate over.
10384      * @param {Function} callback The function called per iteration.
10385      * @returns {Object} Returns `object`.
10386      */
10387     function baseForOwnRight(object, callback) {
10388       var props = keys(object),
10389           length = props.length;
10390
10391       while (length--) {
10392         var key = props[length];
10393         if (callback(object[key], key, object) === false) {
10394           break;
10395         }
10396       }
10397       return object;
10398     }
10399
10400     /**
10401      * The base implementation of `_.isEqual`, without support for `thisArg` binding,
10402      * that allows partial "_.where" style comparisons.
10403      *
10404      * @private
10405      * @param {*} a The value to compare.
10406      * @param {*} b The other value to compare.
10407      * @param {Function} [callback] The function to customize comparing values.
10408      * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
10409      * @param {Array} [stackA=[]] Tracks traversed `a` objects.
10410      * @param {Array} [stackB=[]] Tracks traversed `b` objects.
10411      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
10412      */
10413     function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
10414       // used to indicate that when comparing objects, `a` has at least the properties of `b`
10415       if (callback) {
10416         var result = callback(a, b);
10417         if (typeof result != 'undefined') {
10418           return !!result;
10419         }
10420       }
10421       // exit early for identical values
10422       if (a === b) {
10423         // treat `+0` vs. `-0` as not equal
10424         return a !== 0 || (1 / a == 1 / b);
10425       }
10426       var type = typeof a,
10427           otherType = typeof b;
10428
10429       // exit early for unlike primitive values
10430       if (a === a &&
10431           !(a && (type == 'function' || type == 'object')) &&
10432           !(b && (otherType == 'function' || otherType == 'object'))) {
10433         return false;
10434       }
10435       // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
10436       // http://es5.github.io/#x15.3.4.4
10437       if (a == null || b == null) {
10438         return a === b;
10439       }
10440       // compare [[Class]] names
10441       var className = toString.call(a),
10442           otherClass = toString.call(b);
10443
10444       if (className == argsClass) {
10445         className = objectClass;
10446       }
10447       if (otherClass == argsClass) {
10448         otherClass = objectClass;
10449       }
10450       if (className != otherClass) {
10451         return false;
10452       }
10453       switch (className) {
10454         case boolClass:
10455         case dateClass:
10456           // coerce dates and booleans to numbers, dates to milliseconds and booleans
10457           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
10458           return +a == +b;
10459
10460         case numberClass:
10461           // treat `NaN` vs. `NaN` as equal
10462           return (a != +a)
10463             ? b != +b
10464             // but treat `+0` vs. `-0` as not equal
10465             : (a == 0 ? (1 / a == 1 / b) : a == +b);
10466
10467         case regexpClass:
10468         case stringClass:
10469           // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
10470           // treat string primitives and their corresponding object instances as equal
10471           return a == String(b);
10472       }
10473       var isArr = className == arrayClass;
10474       if (!isArr) {
10475         // unwrap any `lodash` wrapped values
10476         var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
10477             bWrapped = hasOwnProperty.call(b, '__wrapped__');
10478
10479         if (aWrapped || bWrapped) {
10480           return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
10481         }
10482         // exit for functions and DOM nodes
10483         if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
10484           return false;
10485         }
10486         // in older versions of Opera, `arguments` objects have `Array` constructors
10487         var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
10488             ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
10489
10490         // non `Object` object instances with different constructors are not equal
10491         if (ctorA != ctorB &&
10492               !(hasOwnProperty.call(a, 'constructor') && hasOwnProperty.call(b, 'constructor')) &&
10493               !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
10494               ('constructor' in a && 'constructor' in b)
10495             ) {
10496           return false;
10497         }
10498       }
10499       // assume cyclic structures are equal
10500       // the algorithm for detecting cyclic structures is adapted from ES 5.1
10501       // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
10502       var initedStack = !stackA;
10503       stackA || (stackA = getArray());
10504       stackB || (stackB = getArray());
10505
10506       var length = stackA.length;
10507       while (length--) {
10508         if (stackA[length] == a) {
10509           return stackB[length] == b;
10510         }
10511       }
10512       var size = 0;
10513       result = true;
10514
10515       // add `a` and `b` to the stack of traversed objects
10516       stackA.push(a);
10517       stackB.push(b);
10518
10519       // recursively compare objects and arrays (susceptible to call stack limits)
10520       if (isArr) {
10521         // compare lengths to determine if a deep comparison is necessary
10522         length = a.length;
10523         size = b.length;
10524         result = size == length;
10525
10526         if (result || isWhere) {
10527           // deep compare the contents, ignoring non-numeric properties
10528           while (size--) {
10529             var index = length,
10530                 value = b[size];
10531
10532             if (isWhere) {
10533               while (index--) {
10534                 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
10535                   break;
10536                 }
10537               }
10538             } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
10539               break;
10540             }
10541           }
10542         }
10543       }
10544       else {
10545         // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
10546         // which, in this case, is more costly
10547         baseForIn(b, function(value, key, b) {
10548           if (hasOwnProperty.call(b, key)) {
10549             // count the number of properties.
10550             size++;
10551             // deep compare each property value.
10552             return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
10553           }
10554         });
10555
10556         if (result && !isWhere) {
10557           // ensure both objects have the same number of properties
10558           baseForIn(a, function(value, key, a) {
10559             if (hasOwnProperty.call(a, key)) {
10560               // `size` will be `-1` if `a` has more properties than `b`
10561               return (result = --size > -1);
10562             }
10563           });
10564         }
10565       }
10566       stackA.pop();
10567       stackB.pop();
10568
10569       if (initedStack) {
10570         releaseArray(stackA);
10571         releaseArray(stackB);
10572       }
10573       return result;
10574     }
10575
10576     /**
10577      * The base implementation of `_.merge` without argument juggling or support
10578      * for `thisArg` binding.
10579      *
10580      * @private
10581      * @param {Object} object The destination object.
10582      * @param {Object} source The source object.
10583      * @param {Function} [callback] The function to customize merging properties.
10584      * @param {Array} [stackA=[]] Tracks traversed source objects.
10585      * @param {Array} [stackB=[]] Associates values with source counterparts.
10586      */
10587     function baseMerge(object, source, callback, stackA, stackB) {
10588       (isArray(source) ? baseEach : baseForOwn)(source, function(source, key) {
10589         var found,
10590             isArr,
10591             result = source,
10592             value = object[key];
10593
10594         if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
10595           // avoid merging previously merged cyclic sources
10596           var stackLength = stackA.length;
10597           while (stackLength--) {
10598             if ((found = stackA[stackLength] == source)) {
10599               value = stackB[stackLength];
10600               break;
10601             }
10602           }
10603           if (!found) {
10604             var isShallow;
10605             if (callback) {
10606               result = callback(value, source);
10607               if ((isShallow = typeof result != 'undefined')) {
10608                 value = result;
10609               }
10610             }
10611             if (!isShallow) {
10612               value = isArr
10613                 ? (isArray(value) ? value : [])
10614                 : (isPlainObject(value) ? value : {});
10615             }
10616             // add `source` and associated `value` to the stack of traversed objects
10617             stackA.push(source);
10618             stackB.push(value);
10619
10620             // recursively merge objects and arrays (susceptible to call stack limits)
10621             if (!isShallow) {
10622               baseMerge(value, source, callback, stackA, stackB);
10623             }
10624           }
10625         }
10626         else {
10627           if (callback) {
10628             result = callback(value, source);
10629             if (typeof result == 'undefined') {
10630               result = source;
10631             }
10632           }
10633           if (typeof result != 'undefined') {
10634             value = result;
10635           }
10636         }
10637         object[key] = value;
10638       });
10639     }
10640
10641     /**
10642      * The base implementation of `_.random` without argument juggling or support
10643      * for returning floating-point numbers.
10644      *
10645      * @private
10646      * @param {number} min The minimum possible value.
10647      * @param {number} max The maximum possible value.
10648      * @returns {number} Returns a random number.
10649      */
10650     function baseRandom(min, max) {
10651       return min + floor(nativeRandom() * (max - min + 1));
10652     }
10653
10654     /**
10655      * The base implementation of `_.uniq` without support for callback shorthands
10656      * or `thisArg` binding.
10657      *
10658      * @private
10659      * @param {Array} array The array to process.
10660      * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
10661      * @param {Function} [callback] The function called per iteration.
10662      * @returns {Array} Returns a duplicate-value-free array.
10663      */
10664     function baseUniq(array, isSorted, callback) {
10665       var index = -1,
10666           indexOf = getIndexOf(),
10667           length = array ? array.length : 0,
10668           isLarge = createCache && !isSorted && indexOf === baseIndexOf && length >= LARGE_ARRAY_SIZE,
10669           result = [];
10670
10671       if (isLarge) {
10672         var seen = createCache();
10673         indexOf = cacheIndexOf;
10674       } else {
10675         seen = callback ? getArray() : result;
10676       }
10677       while (++index < length) {
10678         var value = array[index],
10679             computed = callback ? callback(value, index, array) : value;
10680
10681         if (isSorted
10682               ? !index || seen[seen.length - 1] !== computed
10683               : indexOf(seen, computed) < 0
10684             ) {
10685           if (callback || isLarge) {
10686             seen.push(computed);
10687           }
10688           result.push(value);
10689         }
10690       }
10691       if (!isLarge && callback) {
10692         releaseArray(seen);
10693       }
10694       return result;
10695     }
10696
10697     /**
10698      * Creates a function that aggregates a collection, creating an object or
10699      * array composed from the results of running each element of the collection
10700      * through a callback. The given `setter` function sets the keys and values
10701      * of the composed object or array.
10702      *
10703      * @private
10704      * @param {Function} setter The setter function.
10705      * @param {boolean} [retArray=false] A flag to indicate that the aggregator
10706      *  function should return an array.
10707      * @returns {Function} Returns the new aggregator function.
10708      */
10709     function createAggregator(setter, retArray) {
10710       return function(collection, callback, thisArg) {
10711         var result = retArray ? [[], []] : {};
10712
10713         callback = lodash.createCallback(callback, thisArg, 3);
10714         if (isArray(collection)) {
10715           var index = -1,
10716               length = collection.length;
10717
10718           while (++index < length) {
10719             var value = collection[index];
10720             setter(result, value, callback(value, index, collection), collection);
10721           }
10722         } else {
10723           baseEach(collection, function(value, key, collection) {
10724             setter(result, value, callback(value, key, collection), collection);
10725           });
10726         }
10727         return result;
10728       };
10729     }
10730
10731     /**
10732      * Creates a cache object to optimize linear searches of large arrays.
10733      *
10734      * @private
10735      * @param {Array} [array=[]] The array to search.
10736      * @returns {Object} Returns the cache object.
10737      */
10738     var createCache = Set && function(array) {
10739       var cache = new Set,
10740           length = array ? array.length : 0;
10741
10742       cache.push = cache.add;
10743       while (length--) {
10744         cache.push(array[length]);
10745       }
10746       return cache;
10747     };
10748
10749     /**
10750      * Creates a function that, when called, either curries or invokes `func`
10751      * with an optional `this` binding and partially applied arguments.
10752      *
10753      * @private
10754      * @param {Function|string} func The function or method name to reference.
10755      * @param {number} bitmask The bitmask of flags to compose.
10756      *  The bitmask may be composed of the following flags:
10757      *  1  - `_.bind`
10758      *  2  - `_.bindKey`
10759      *  4  - `_.curry`
10760      *  8  - `_.curry` (bound)
10761      *  16 - `_.partial`
10762      *  32 - `_.partialRight`
10763      * @param {number} [arity] The arity of `func`.
10764      * @param {*} [thisArg] The `this` binding of `func`.
10765      * @param {Array} [partialArgs] An array of arguments to prepend to those
10766      *  provided to the new function.
10767      * @param {Array} [partialRightArgs] An array of arguments to append to those
10768      *  provided to the new function.
10769      * @returns {Function} Returns the new function.
10770      */
10771     function createWrapper(func, bitmask, arity, thisArg, partialArgs, partialRightArgs) {
10772       var isBind = bitmask & BIND_FLAG,
10773           isBindKey = bitmask & BIND_KEY_FLAG,
10774           isPartial = bitmask & PARTIAL_FLAG,
10775           isPartialRight = bitmask & PARTIAL_RIGHT_FLAG;
10776
10777       if (!isBindKey && !isFunction(func)) {
10778         throw new TypeError;
10779       }
10780       if (isPartial && !partialArgs.length) {
10781         bitmask &= ~PARTIAL_FLAG;
10782         isPartial = partialArgs = false;
10783       }
10784       if (isPartialRight && !partialRightArgs.length) {
10785         bitmask &= ~PARTIAL_RIGHT_FLAG;
10786         isPartialRight = partialRightArgs = false;
10787       }
10788       var data = !isBindKey && func[expando];
10789       if (data && data !== true) {
10790         // shallow clone `data`
10791         data = slice(data);
10792
10793         // clone partial left arguments
10794         if (data[4]) {
10795           data[4] = slice(data[4]);
10796         }
10797         // clone partial right arguments
10798         if (data[5]) {
10799           data[5] = slice(data[5]);
10800         }
10801         // set arity if provided
10802         if (typeof arity == 'number') {
10803           data[2] = arity;
10804         }
10805         // set `thisArg` if not previously bound
10806         var bound = data[1] & BIND_FLAG;
10807         if (isBind && !bound) {
10808           data[3] = thisArg;
10809         }
10810         // set if currying a bound function
10811         if (!isBind && bound) {
10812           bitmask |= CURRY_BOUND_FLAG;
10813         }
10814         // append partial left arguments
10815         if (isPartial) {
10816           if (data[4]) {
10817             push.apply(data[4], partialArgs);
10818           } else {
10819             data[4] = partialArgs;
10820           }
10821         }
10822         // prepend partial right arguments
10823         if (isPartialRight) {
10824           if (data[5]) {
10825             unshift.apply(data[5], partialRightArgs);
10826           } else {
10827             data[5] = partialRightArgs;
10828           }
10829         }
10830         // merge flags
10831         data[1] |= bitmask;
10832         return createWrapper.apply(null, data);
10833       }
10834       if (arity == null) {
10835         arity = isBindKey ? 0 : func.length;
10836       } else if (arity < 0) {
10837         arity = 0;
10838       }
10839       // fast path for `_.bind`
10840       data = [func, bitmask, arity, thisArg, partialArgs, partialRightArgs];
10841       return (bitmask == BIND_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG))
10842         ? baseBind(data)
10843         : baseCreateWrapper(data);
10844     }
10845
10846     /**
10847      * Creates compiled iteration functions.
10848      *
10849      * @private
10850      * @param {Object} [options] The compile options object.
10851      * @param {string} [options.args] A comma separated string of iteration function arguments.
10852      * @param {string} [options.init] The string representation of the initial `result` value.
10853      * @param {string} [options.loop] Code to execute in the object loop.
10854      * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
10855      * @returns {Function} Returns the compiled function.
10856      */
10857     function createIterator(options) {
10858       options.shadowedProps = shadowedProps;
10859       options.support = support;
10860
10861       // create the function factory
10862       var factory = Function(
10863           'errorClass, errorProto, hasOwnProperty, isArguments, isObject, objectProto, ' +
10864           'nonEnumProps, stringClass, stringProto, toString',
10865         'return function(' + options.args + ') {\n' + iteratorTemplate(options) + '\n}'
10866       );
10867
10868       // return the compiled function
10869       return factory(
10870         errorClass, errorProto, hasOwnProperty, isArguments, isObject, objectProto,
10871         nonEnumProps, stringClass, stringProto, toString
10872       );
10873     }
10874
10875     /**
10876      * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
10877      * customized this method returns the custom method, otherwise it returns
10878      * the `baseIndexOf` function.
10879      *
10880      * @private
10881      * @returns {Function} Returns the "indexOf" function.
10882      */
10883     function getIndexOf() {
10884       var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
10885       return result;
10886     }
10887
10888     /**
10889      * Checks if `value` is a native function.
10890      *
10891      * @private
10892      * @param {*} value The value to check.
10893      * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
10894      */
10895     function isNative(value) {
10896       return typeof value == 'function' && reNative.test(fnToString.call(value));
10897     }
10898
10899     /**
10900      * Sets wrapper metadata on a given function.
10901      *
10902      * @private
10903      * @param {Function} func The function to set data on.
10904      * @param {Array} value The data array to set.
10905      */
10906     var setData = !defineProperty ? noop : function(func, value) {
10907       descriptor.value = value;
10908       defineProperty(func, expando, descriptor);
10909     };
10910
10911     /**
10912      * A fallback implementation of `isPlainObject` which checks if a given value
10913      * is an object created by the `Object` constructor, assuming objects created
10914      * by the `Object` constructor have no inherited enumerable properties and that
10915      * there are no `Object.prototype` extensions.
10916      *
10917      * @private
10918      * @param {*} value The value to check.
10919      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10920      */
10921     function shimIsPlainObject(value) {
10922       var ctor,
10923           result;
10924
10925       // avoid non Object objects, `arguments` objects, and DOM elements
10926       if (!(value && toString.call(value) == objectClass) ||
10927           (!hasOwnProperty.call(value, 'constructor') &&
10928             (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) ||
10929           (!support.argsClass && isArguments(value)) ||
10930           (!support.nodeClass && isNode(value))) {
10931         return false;
10932       }
10933       // IE < 9 iterates inherited properties before own properties. If the first
10934       // iterated property is an object's own property then there are no inherited
10935       // enumerable properties.
10936       if (support.ownLast) {
10937         baseForIn(value, function(value, key, object) {
10938           result = hasOwnProperty.call(object, key);
10939           return false;
10940         });
10941         return result !== false;
10942       }
10943       // In most environments an object's own properties are iterated before
10944       // its inherited properties. If the last iterated property is an object's
10945       // own property then there are no inherited enumerable properties.
10946       baseForIn(value, function(value, key) {
10947         result = key;
10948       });
10949       return typeof result == 'undefined' || hasOwnProperty.call(value, result);
10950     }
10951
10952     /*--------------------------------------------------------------------------*/
10953
10954     /**
10955      * Checks if `value` is an `arguments` object.
10956      *
10957      * @static
10958      * @memberOf _
10959      * @category Objects
10960      * @param {*} value The value to check.
10961      * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
10962      * @example
10963      *
10964      * (function() { return _.isArguments(arguments); })(1, 2, 3);
10965      * // => true
10966      *
10967      * _.isArguments([1, 2, 3]);
10968      * // => false
10969      */
10970     function isArguments(value) {
10971       return value && typeof value == 'object' && typeof value.length == 'number' &&
10972         toString.call(value) == argsClass || false;
10973     }
10974     // fallback for environments that can't detect `arguments` objects by [[Class]]
10975     if (!support.argsClass) {
10976       isArguments = function(value) {
10977         return value && typeof value == 'object' && typeof value.length == 'number' &&
10978           hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
10979       };
10980     }
10981
10982     /**
10983      * The base implementation of `_.forIn` without support for callback
10984      * shorthands or `thisArg` binding.
10985      *
10986      * @private
10987      * @param {Object} object The object to iterate over.
10988      * @param {Function} callback The function called per iteration.
10989      * @returns {Object} Returns `object`.
10990      */
10991     var baseForIn = createIterator({
10992       'args': 'object, callback',
10993       'init': 'object',
10994       'loop': 'if (callback(object[key], key, object) === false) {\n    return result;\n  }',
10995       'useHas': false
10996     });
10997
10998     /**
10999      * A fallback implementation of `Object.keys` which produces an array of the
11000      * given object's own enumerable property names.
11001      *
11002      * @private
11003      * @type Function
11004      * @param {Object} object The object to inspect.
11005      * @returns {Array} Returns an array of property names.
11006      */
11007     var shimKeys = createIterator({
11008       'args': 'object',
11009       'init': '[]',
11010       'loop': 'result.push(key)',
11011       'useHas': true
11012     });
11013
11014     /*--------------------------------------------------------------------------*/
11015
11016     /**
11017      * Creates an array with all falsey values removed. The values `false`, `null`,
11018      * `0`, `""`, `undefined`, and `NaN` are all falsey.
11019      *
11020      * @static
11021      * @memberOf _
11022      * @category Arrays
11023      * @param {Array} array The array to compact.
11024      * @returns {Array} Returns a new array of filtered values.
11025      * @example
11026      *
11027      * _.compact([0, 1, false, 2, '', 3]);
11028      * // => [1, 2, 3]
11029      */
11030     function compact(array) {
11031       var index = -1,
11032           length = array ? array.length : 0,
11033           resIndex = 0,
11034           result = [];
11035
11036       while (++index < length) {
11037         var value = array[index];
11038         if (value) {
11039           result[resIndex++] = value;
11040         }
11041       }
11042       return result;
11043     }
11044
11045     /**
11046      * Creates an array excluding all values of the provided arrays using strict
11047      * equality for comparisons, i.e. `===`.
11048      *
11049      * @static
11050      * @memberOf _
11051      * @category Arrays
11052      * @param {Array} array The array to process.
11053      * @param {...Array} [values] The arrays of values to exclude.
11054      * @returns {Array} Returns a new array of filtered values.
11055      * @example
11056      *
11057      * _.difference([1, 2, 3], [5, 2, 10]);
11058      * // => [1, 3]
11059      */
11060     function difference(array) {
11061       return baseDifference(array, baseFlatten(arguments, true, true, 1));
11062     }
11063
11064     /**
11065      * This method is like `_.find` except that it returns the index of the first
11066      * element that passes the callback check, instead of the element itself.
11067      *
11068      * If a property name is provided for `callback` the created "_.pluck" style
11069      * callback will return the property value of the given element.
11070      *
11071      * If an object is provided for `callback` the created "_.where" style callback
11072      * will return `true` for elements that have the properties of the given object,
11073      * else `false`.
11074      *
11075      * @static
11076      * @memberOf _
11077      * @category Arrays
11078      * @param {Array} array The array to search.
11079      * @param {Function|Object|string} [callback=identity] The function called
11080      *  per iteration. If a property name or object is provided it will be used
11081      *  to create a "_.pluck" or "_.where" style callback, respectively.
11082      * @param {*} [thisArg] The `this` binding of `callback`.
11083      * @returns {number} Returns the index of the found element, else `-1`.
11084      * @example
11085      *
11086      * var characters = [
11087      *   { 'name': 'barney',  'age': 36 },
11088      *   { 'name': 'fred',    'age': 40, 'blocked': true },
11089      *   { 'name': 'pebbles', 'age': 1 }
11090      * ];
11091      *
11092      * _.findIndex(characters, function(chr) {
11093      *   return chr.age < 20;
11094      * });
11095      * // => 2
11096      *
11097      * // using "_.where" callback shorthand
11098      * _.findIndex(characters, { 'age': 36 });
11099      * // => 0
11100      *
11101      * // using "_.pluck" callback shorthand
11102      * _.findIndex(characters, 'blocked');
11103      * // => 1
11104      */
11105     function findIndex(array, callback, thisArg) {
11106       var index = -1,
11107           length = array ? array.length : 0;
11108
11109       callback = lodash.createCallback(callback, thisArg, 3);
11110       while (++index < length) {
11111         if (callback(array[index], index, array)) {
11112           return index;
11113         }
11114       }
11115       return -1;
11116     }
11117
11118     /**
11119      * This method is like `_.findIndex` except that it iterates over elements
11120      * of a `collection` from right to left.
11121      *
11122      * If a property name is provided for `callback` the created "_.pluck" style
11123      * callback will return the property value of the given element.
11124      *
11125      * If an object is provided for `callback` the created "_.where" style callback
11126      * will return `true` for elements that have the properties of the given object,
11127      * else `false`.
11128      *
11129      * @static
11130      * @memberOf _
11131      * @category Arrays
11132      * @param {Array} array The array to search.
11133      * @param {Function|Object|string} [callback=identity] The function called
11134      *  per iteration. If a property name or object is provided it will be used
11135      *  to create a "_.pluck" or "_.where" style callback, respectively.
11136      * @param {*} [thisArg] The `this` binding of `callback`.
11137      * @returns {number} Returns the index of the found element, else `-1`.
11138      * @example
11139      *
11140      * var characters = [
11141      *   { 'name': 'barney',  'age': 36, 'blocked': true },
11142      *   { 'name': 'fred',    'age': 40 },
11143      *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
11144      * ];
11145      *
11146      * _.findLastIndex(characters, function(chr) {
11147      *   return chr.age > 30;
11148      * });
11149      * // => 1
11150      *
11151      * // using "_.where" callback shorthand
11152      * _.findLastIndex(characters, { 'age': 36 });
11153      * // => 0
11154      *
11155      * // using "_.pluck" callback shorthand
11156      * _.findLastIndex(characters, 'blocked');
11157      * // => 2
11158      */
11159     function findLastIndex(array, callback, thisArg) {
11160       var length = array ? array.length : 0;
11161
11162       callback = lodash.createCallback(callback, thisArg, 3);
11163       while (length--) {
11164         if (callback(array[length], length, array)) {
11165           return length;
11166         }
11167       }
11168       return -1;
11169     }
11170
11171     /**
11172      * Gets the first element or first `n` elements of an array. If a callback
11173      * is provided elements at the beginning of the array are returned as long
11174      * as the callback returns truey. The callback is bound to `thisArg` and
11175      * invoked with three arguments; (value, index, array).
11176      *
11177      * If a property name is provided for `callback` the created "_.pluck" style
11178      * callback will return the property value of the given element.
11179      *
11180      * If an object is provided for `callback` the created "_.where" style callback
11181      * will return `true` for elements that have the properties of the given object,
11182      * else `false`.
11183      *
11184      * @static
11185      * @memberOf _
11186      * @alias head, take
11187      * @category Arrays
11188      * @param {Array} array The array to query.
11189      * @param {Function|Object|number|string} [callback] The function called
11190      *  per element or the number of elements to return. If a property name or
11191      *  object is provided it will be used to create a "_.pluck" or "_.where"
11192      *  style callback, respectively.
11193      * @param {*} [thisArg] The `this` binding of `callback`.
11194      * @returns {*} Returns the first element(s) of `array`.
11195      * @example
11196      *
11197      * _.first([1, 2, 3]);
11198      * // => 1
11199      *
11200      * // returns the first two elements
11201      * _.first([1, 2, 3], 2);
11202      * // => [1, 2]
11203      *
11204      * // returns elements from the beginning until the callback result is falsey
11205      * _.first([1, 2, 3], function(num) {
11206      *   return num < 3;
11207      * });
11208      * // => [1, 2]
11209      *
11210      * var characters = [
11211      *   { 'name': 'barney',  'employer': 'slate', 'blocked': true },
11212      *   { 'name': 'fred',    'employer': 'slate' },
11213      *   { 'name': 'pebbles', 'employer': 'na',    'blocked': true }
11214      * ];
11215      *
11216      * // using "_.pluck" callback shorthand
11217      * _.first(characters, 'blocked');
11218      * // => [{ 'name': 'barney', 'employer': 'slate', 'blocked': true }]
11219      *
11220      * // using "_.where" callback shorthand
11221      * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
11222      * // => ['barney', 'fred']
11223      */
11224     function first(array, callback, thisArg) {
11225       var n = 0,
11226           length = array ? array.length : 0;
11227
11228       if (typeof callback != 'number' && callback != null) {
11229         var index = -1;
11230         callback = lodash.createCallback(callback, thisArg, 3);
11231         while (++index < length && callback(array[index], index, array)) {
11232           n++;
11233         }
11234       } else {
11235         n = callback;
11236         if (n == null || thisArg) {
11237           return array ? array[0] : undefined;
11238         }
11239       }
11240       return slice(array, 0, n > 0 ? n : 0);
11241     }
11242
11243     /**
11244      * Flattens a nested array (the nesting can be to any depth). If `isShallow`
11245      * is truey, the array will only be flattened a single level. If a callback
11246      * is provided each element of the array is passed through the callback before
11247      * flattening. The callback is bound to `thisArg` and invoked with three
11248      * arguments; (value, index, array).
11249      *
11250      * If a property name is provided for `callback` the created "_.pluck" style
11251      * callback will return the property value of the given element.
11252      *
11253      * If an object is provided for `callback` the created "_.where" style callback
11254      * will return `true` for elements that have the properties of the given object,
11255      * else `false`.
11256      *
11257      * @static
11258      * @memberOf _
11259      * @category Arrays
11260      * @param {Array} array The array to flatten.
11261      * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
11262      * @param {Function|Object|string} [callback=identity] The function called
11263      *  per iteration. If a property name or object is provided it will be used
11264      *  to create a "_.pluck" or "_.where" style callback, respectively.
11265      * @param {*} [thisArg] The `this` binding of `callback`.
11266      * @returns {Array} Returns a new flattened array.
11267      * @example
11268      *
11269      * _.flatten([1, [2], [3, [[4]]]]);
11270      * // => [1, 2, 3, 4];
11271      *
11272      * // using `isShallow`
11273      * _.flatten([1, [2], [3, [[4]]]], true);
11274      * // => [1, 2, 3, [[4]]];
11275      *
11276      * var characters = [
11277      *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
11278      *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
11279      * ];
11280      *
11281      * // using "_.pluck" callback shorthand
11282      * _.flatten(characters, 'pets');
11283      * // => ['hoppy', 'baby puss', 'dino']
11284      */
11285     function flatten(array, isShallow, callback, thisArg) {
11286       var type = typeof isShallow;
11287
11288       // juggle arguments
11289       if (type != 'boolean' && isShallow != null) {
11290         thisArg = callback;
11291         callback = isShallow;
11292         isShallow = false;
11293
11294         // enables use as a callback for functions like `_.map`
11295         if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) {
11296           callback = null;
11297         }
11298       }
11299       if (callback != null) {
11300         array = map(array, callback, thisArg);
11301       }
11302       return baseFlatten(array, isShallow);
11303     }
11304
11305     /**
11306      * Gets the index at which the first occurrence of `value` is found using
11307      * strict equality for comparisons, i.e. `===`. If the array is already sorted
11308      * providing `true` for `fromIndex` will run a faster binary search.
11309      *
11310      * @static
11311      * @memberOf _
11312      * @category Arrays
11313      * @param {Array} array The array to search.
11314      * @param {*} value The value to search for.
11315      * @param {boolean|number} [fromIndex=0] The index to search from or `true`
11316      *  to perform a binary search on a sorted array.
11317      * @returns {number} Returns the index of the matched value or `-1`.
11318      * @example
11319      *
11320      * _.indexOf([1, 2, 3, 1, 2, 3], 2);
11321      * // => 1
11322      *
11323      * // using `fromIndex`
11324      * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
11325      * // => 4
11326      *
11327      * // performing a binary search
11328      * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
11329      * // => 2
11330      */
11331     function indexOf(array, value, fromIndex) {
11332       var length = array ? array.length : 0;
11333       if (typeof fromIndex == 'number') {
11334         fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
11335       } else if (fromIndex) {
11336         var index = sortedIndex(array, value);
11337         return (length && array[index] === value) ? index : -1;
11338       }
11339       return baseIndexOf(array, value, fromIndex);
11340     }
11341
11342     /**
11343      * Gets all but the last element or last `n` elements of an array. If a
11344      * callback is provided elements at the end of the array are excluded from
11345      * the result as long as the callback returns truey. The callback is bound
11346      * to `thisArg` and invoked with three arguments; (value, index, array).
11347      *
11348      * If a property name is provided for `callback` the created "_.pluck" style
11349      * callback will return the property value of the given element.
11350      *
11351      * If an object is provided for `callback` the created "_.where" style callback
11352      * will return `true` for elements that have the properties of the given object,
11353      * else `false`.
11354      *
11355      * @static
11356      * @memberOf _
11357      * @category Arrays
11358      * @param {Array} array The array to query.
11359      * @param {Function|Object|number|string} [callback=1] The function called
11360      *  per element or the number of elements to exclude. If a property name or
11361      *  object is provided it will be used to create a "_.pluck" or "_.where"
11362      *  style callback, respectively.
11363      * @param {*} [thisArg] The `this` binding of `callback`.
11364      * @returns {Array} Returns a slice of `array`.
11365      * @example
11366      *
11367      * _.initial([1, 2, 3]);
11368      * // => [1, 2]
11369      *
11370      * // excludes the last two elements
11371      * _.initial([1, 2, 3], 2);
11372      * // => [1]
11373      *
11374      * // excludes elements from the end until the callback fails
11375      * _.initial([1, 2, 3], function(num) {
11376      *   return num > 1;
11377      * });
11378      * // => [1]
11379      *
11380      * var characters = [
11381      *   { 'name': 'barney',  'employer': 'slate' },
11382      *   { 'name': 'fred',    'employer': 'slate', 'blocked': true },
11383      *   { 'name': 'pebbles', 'employer': 'na',    'blocked': true }
11384      * ];
11385      *
11386      * // using "_.pluck" callback shorthand
11387      * _.initial(characters, 'blocked');
11388      * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
11389      *
11390      * // using "_.where" callback shorthand
11391      * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
11392      * // => ['barney', 'fred']
11393      */
11394     function initial(array, callback, thisArg) {
11395       var n = 0,
11396           length = array ? array.length : 0;
11397
11398       if (typeof callback != 'number' && callback != null) {
11399         var index = length;
11400         callback = lodash.createCallback(callback, thisArg, 3);
11401         while (index-- && callback(array[index], index, array)) {
11402           n++;
11403         }
11404       } else {
11405         n = (callback == null || thisArg) ? 1 : callback || n;
11406       }
11407       n = length - n;
11408       return slice(array, 0, n > 0 ? n : 0);
11409     }
11410
11411     /**
11412      * Creates an array of unique values present in all provided arrays using
11413      * strict equality for comparisons, i.e. `===`.
11414      *
11415      * @static
11416      * @memberOf _
11417      * @category Arrays
11418      * @param {...Array} [array] The arrays to inspect.
11419      * @returns {Array} Returns an array of shared values.
11420      * @example
11421      *
11422      * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
11423      * // => [1, 2]
11424      */
11425     function intersection() {
11426       var args = [],
11427           argsIndex = -1,
11428           argsLength = arguments.length,
11429           caches = getArray(),
11430           indexOf = getIndexOf(),
11431           largePrereq = createCache && indexOf === baseIndexOf,
11432           seen = getArray();
11433
11434       while (++argsIndex < argsLength) {
11435         var value = arguments[argsIndex];
11436         if (isArray(value) || isArguments(value)) {
11437           args.push(value);
11438           caches.push(largePrereq && value.length >= LARGE_ARRAY_SIZE &&
11439             createCache(argsIndex ? args[argsIndex] : seen));
11440         }
11441       }
11442       var array = args[0],
11443           index = -1,
11444           length = array ? array.length : 0,
11445           result = [];
11446
11447       outer:
11448       while (++index < length) {
11449         var cache = caches[0];
11450         value = array[index];
11451
11452         if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
11453           argsIndex = argsLength;
11454           (cache || seen).push(value);
11455           while (--argsIndex) {
11456             cache = caches[argsIndex];
11457             if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
11458               continue outer;
11459             }
11460           }
11461           result.push(value);
11462         }
11463       }
11464       releaseArray(caches);
11465       releaseArray(seen);
11466       return result;
11467     }
11468
11469     /**
11470      * Gets the last element or last `n` elements of an array. If a callback is
11471      * provided elements at the end of the array are returned as long as the
11472      * callback returns truey. The callback is bound to `thisArg` and invoked
11473      * with three arguments; (value, index, array).
11474      *
11475      * If a property name is provided for `callback` the created "_.pluck" style
11476      * callback will return the property value of the given element.
11477      *
11478      * If an object is provided for `callback` the created "_.where" style callback
11479      * will return `true` for elements that have the properties of the given object,
11480      * else `false`.
11481      *
11482      * @static
11483      * @memberOf _
11484      * @category Arrays
11485      * @param {Array} array The array to query.
11486      * @param {Function|Object|number|string} [callback] The function called
11487      *  per element or the number of elements to return. If a property name or
11488      *  object is provided it will be used to create a "_.pluck" or "_.where"
11489      *  style callback, respectively.
11490      * @param {*} [thisArg] The `this` binding of `callback`.
11491      * @returns {*} Returns the last element(s) of `array`.
11492      * @example
11493      *
11494      * _.last([1, 2, 3]);
11495      * // => 3
11496      *
11497      * // returns the last two elements
11498      * _.last([1, 2, 3], 2);
11499      * // => [2, 3]
11500      *
11501      * // returns elements from the end until the callback fails
11502      * _.last([1, 2, 3], function(num) {
11503      *   return num > 1;
11504      * });
11505      * // => [2, 3]
11506      *
11507      * var characters = [
11508      *   { 'name': 'barney',  'employer': 'slate' },
11509      *   { 'name': 'fred',    'employer': 'slate', 'blocked': true },
11510      *   { 'name': 'pebbles', 'employer': 'na',    'blocked': true }
11511      * ];
11512      *
11513      * // using "_.pluck" callback shorthand
11514      * _.pluck(_.last(characters, 'blocked'), 'name');
11515      * // => ['fred', 'pebbles']
11516      *
11517      * // using "_.where" callback shorthand
11518      * _.last(characters, { 'employer': 'na' });
11519      * // => [{ 'name': 'pebbles', 'employer': 'na', 'blocked': true }]
11520      */
11521     function last(array, callback, thisArg) {
11522       var n = 0,
11523           length = array ? array.length : 0;
11524
11525       if (typeof callback != 'number' && callback != null) {
11526         var index = length;
11527         callback = lodash.createCallback(callback, thisArg, 3);
11528         while (index-- && callback(array[index], index, array)) {
11529           n++;
11530         }
11531       } else {
11532         n = callback;
11533         if (n == null || thisArg) {
11534           return array ? array[length - 1] : undefined;
11535         }
11536       }
11537       n = length - n;
11538       return slice(array,  n > 0 ? n : 0);
11539     }
11540
11541     /**
11542      * Gets the index at which the last occurrence of `value` is found using strict
11543      * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
11544      * as the offset from the end of the collection.
11545      *
11546      * If a property name is provided for `callback` the created "_.pluck" style
11547      * callback will return the property value of the given element.
11548      *
11549      * If an object is provided for `callback` the created "_.where" style callback
11550      * will return `true` for elements that have the properties of the given object,
11551      * else `false`.
11552      *
11553      * @static
11554      * @memberOf _
11555      * @category Arrays
11556      * @param {Array} array The array to search.
11557      * @param {*} value The value to search for.
11558      * @param {number} [fromIndex=array.length-1] The index to search from.
11559      * @returns {number} Returns the index of the matched value or `-1`.
11560      * @example
11561      *
11562      * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
11563      * // => 4
11564      *
11565      * // using `fromIndex`
11566      * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
11567      * // => 1
11568      */
11569     function lastIndexOf(array, value, fromIndex) {
11570       var index = array ? array.length : 0;
11571       if (typeof fromIndex == 'number') {
11572         index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
11573       }
11574       while (index--) {
11575         if (array[index] === value) {
11576           return index;
11577         }
11578       }
11579       return -1;
11580     }
11581
11582     /**
11583      * Removes all provided values from `array` using strict equality for
11584      * comparisons, i.e. `===`.
11585      *
11586      * @static
11587      * @memberOf _
11588      * @category Arrays
11589      * @param {Array} array The array to modify.
11590      * @param {...*} [value] The values to remove.
11591      * @returns {Array} Returns `array`.
11592      * @example
11593      *
11594      * var array = [1, 2, 3, 1, 2, 3];
11595      * _.pull(array, 2, 3);
11596      * console.log(array);
11597      * // => [1, 1]
11598      */
11599     function pull(array) {
11600       var args = arguments,
11601           argsIndex = 0,
11602           argsLength = args.length,
11603           length = array ? array.length : 0;
11604
11605       while (++argsIndex < argsLength) {
11606         var index = -1,
11607             value = args[argsIndex];
11608
11609         while (++index < length) {
11610           if (array[index] === value) {
11611             splice.call(array, index--, 1);
11612             length--;
11613           }
11614         }
11615       }
11616       return array;
11617     }
11618
11619     /**
11620      * Creates an array of numbers (positive and/or negative) progressing from
11621      * `start` up to but not including `end`. If `start` is less than `stop` a
11622      * zero-length range is created unless a negative `step` is specified.
11623      *
11624      * @static
11625      * @memberOf _
11626      * @category Arrays
11627      * @param {number} [start=0] The start of the range.
11628      * @param {number} end The end of the range.
11629      * @param {number} [step=1] The value to increment or decrement by.
11630      * @returns {Array} Returns a new range array.
11631      * @example
11632      *
11633      * _.range(4);
11634      * // => [0, 1, 2, 3]
11635      *
11636      * _.range(1, 5);
11637      * // => [1, 2, 3, 4]
11638      *
11639      * _.range(0, 20, 5);
11640      * // => [0, 5, 10, 15]
11641      *
11642      * _.range(0, -4, -1);
11643      * // => [0, -1, -2, -3]
11644      *
11645      * _.range(1, 4, 0);
11646      * // => [1, 1, 1]
11647      *
11648      * _.range(0);
11649      * // => []
11650      */
11651     function range(start, end, step) {
11652       start = +start || 0;
11653       step = typeof step == 'number' ? step : (+step || 1);
11654
11655       if (end == null) {
11656         end = start;
11657         start = 0;
11658       }
11659       // use `Array(length)` so engines like Chakra and V8 avoid slower modes
11660       // http://youtu.be/XAqIpGU8ZZk#t=17m25s
11661       var index = -1,
11662           length = nativeMax(0, ceil((end - start) / (step || 1))),
11663           result = Array(length);
11664
11665       while (++index < length) {
11666         result[index] = start;
11667         start += step;
11668       }
11669       return result;
11670     }
11671
11672     /**
11673      * Removes all elements from an array that the callback returns truey for
11674      * and returns an array of removed elements. The callback is bound to `thisArg`
11675      * and invoked with three arguments; (value, index, array).
11676      *
11677      * If a property name is provided for `callback` the created "_.pluck" style
11678      * callback will return the property value of the given element.
11679      *
11680      * If an object is provided for `callback` the created "_.where" style callback
11681      * will return `true` for elements that have the properties of the given object,
11682      * else `false`.
11683      *
11684      * @static
11685      * @memberOf _
11686      * @category Arrays
11687      * @param {Array} array The array to modify.
11688      * @param {Function|Object|string} [callback=identity] The function called
11689      *  per iteration. If a property name or object is provided it will be used
11690      *  to create a "_.pluck" or "_.where" style callback, respectively.
11691      * @param {*} [thisArg] The `this` binding of `callback`.
11692      * @returns {Array} Returns a new array of removed elements.
11693      * @example
11694      *
11695      * var array = [1, 2, 3, 4, 5, 6];
11696      * var evens = _.remove(array, function(num) { return num % 2 == 0; });
11697      *
11698      * console.log(array);
11699      * // => [1, 3, 5]
11700      *
11701      * console.log(evens);
11702      * // => [2, 4, 6]
11703      */
11704     function remove(array, callback, thisArg) {
11705       var index = -1,
11706           length = array ? array.length : 0,
11707           result = [];
11708
11709       callback = lodash.createCallback(callback, thisArg, 3);
11710       while (++index < length) {
11711         var value = array[index];
11712         if (callback(value, index, array)) {
11713           result.push(value);
11714           splice.call(array, index--, 1);
11715           length--;
11716         }
11717       }
11718       return result;
11719     }
11720
11721     /**
11722      * The opposite of `_.initial`; this method gets all but the first element or
11723      * first `n` elements of an array. If a callback function is provided elements
11724      * at the beginning of the array are excluded from the result as long as the
11725      * callback returns truey. The callback is bound to `thisArg` and invoked
11726      * with three arguments; (value, index, array).
11727      *
11728      * If a property name is provided for `callback` the created "_.pluck" style
11729      * callback will return the property value of the given element.
11730      *
11731      * If an object is provided for `callback` the created "_.where" style callback
11732      * will return `true` for elements that have the properties of the given object,
11733      * else `false`.
11734      *
11735      * @static
11736      * @memberOf _
11737      * @alias drop, tail
11738      * @category Arrays
11739      * @param {Array} array The array to query.
11740      * @param {Function|Object|number|string} [callback=1] The function called
11741      *  per element or the number of elements to exclude. If a property name or
11742      *  object is provided it will be used to create a "_.pluck" or "_.where"
11743      *  style callback, respectively.
11744      * @param {*} [thisArg] The `this` binding of `callback`.
11745      * @returns {Array} Returns a slice of `array`.
11746      * @example
11747      *
11748      * _.rest([1, 2, 3]);
11749      * // => [2, 3]
11750      *
11751      * // excludes the first two elements
11752      * _.rest([1, 2, 3], 2);
11753      * // => [3]
11754      *
11755      * // excludes elements from the beginning until the callback fails
11756      * _.rest([1, 2, 3], function(num) {
11757      *   return num < 3;
11758      * });
11759      * // => [3]
11760      *
11761      * var characters = [
11762      *   { 'name': 'barney',  'employer': 'slate', 'blocked': true },
11763      *   { 'name': 'fred',    'employer': 'slate' },
11764      *   { 'name': 'pebbles', 'employer': 'na',    'blocked': true }
11765      * ];
11766      *
11767      * // using "_.pluck" callback shorthand
11768      * _.pluck(_.rest(characters, 'blocked'), 'name');
11769      * // => ['fred', 'pebbles']
11770      *
11771      * // using "_.where" callback shorthand
11772      * _.rest(characters, { 'employer': 'slate' });
11773      * // => [{ 'name': 'pebbles', 'employer': 'na', 'blocked': true }]
11774      */
11775     function rest(array, callback, thisArg) {
11776       if (typeof callback != 'number' && callback != null) {
11777         var n = 0,
11778             index = -1,
11779             length = array ? array.length : 0;
11780
11781         callback = lodash.createCallback(callback, thisArg, 3);
11782         while (++index < length && callback(array[index], index, array)) {
11783           n++;
11784         }
11785       } else if (callback == null || thisArg) {
11786         n = 1;
11787       } else {
11788         n = callback > 0 ? callback : 0;
11789       }
11790       return slice(array, n);
11791     }
11792
11793     /**
11794      * Slices `array` from the `start` index up to, but not including, the `end` index.
11795      *
11796      * Note: This function is used instead of `Array#slice` to support node lists
11797      * in IE < 9 and to ensure dense arrays are returned.
11798      *
11799      * @static
11800      * @memberOf _
11801      * @category Arrays
11802      * @param {Array} array The array to slice.
11803      * @param {number} [start=0] The start index.
11804      * @param {number} [end=array.length] The end index.
11805      * @returns {Array} Returns the new array.
11806      */
11807     function slice(array, start, end) {
11808       var index = -1,
11809           length = array ? array.length : 0;
11810
11811       if (typeof start == 'undefined') {
11812         start = 0;
11813       } else if (start < 0) {
11814         start = nativeMax(length + start, 0);
11815       } else if (start > length) {
11816         start = length;
11817       }
11818       if (typeof end == 'undefined') {
11819         end = length;
11820       } else if (end < 0) {
11821         end = nativeMax(length + end, 0);
11822       } else if (end > length) {
11823         end = length;
11824       }
11825       length = end - start || 0;
11826
11827       var result = Array(length);
11828       while (++index < length) {
11829         result[index] = array[start + index];
11830       }
11831       return result;
11832     }
11833
11834     /**
11835      * Uses a binary search to determine the smallest index at which a value
11836      * should be inserted into a given sorted array in order to maintain the sort
11837      * order of the array. If a callback is provided it will be executed for
11838      * `value` and each element of `array` to compute their sort ranking. The
11839      * callback is bound to `thisArg` and invoked with one argument; (value).
11840      *
11841      * If a property name is provided for `callback` the created "_.pluck" style
11842      * callback will return the property value of the given element.
11843      *
11844      * If an object is provided for `callback` the created "_.where" style callback
11845      * will return `true` for elements that have the properties of the given object,
11846      * else `false`.
11847      *
11848      * @static
11849      * @memberOf _
11850      * @category Arrays
11851      * @param {Array} array The array to inspect.
11852      * @param {*} value The value to evaluate.
11853      * @param {Function|Object|string} [callback=identity] The function called
11854      *  per iteration. If a property name or object is provided it will be used
11855      *  to create a "_.pluck" or "_.where" style callback, respectively.
11856      * @param {*} [thisArg] The `this` binding of `callback`.
11857      * @returns {number} Returns the index at which `value` should be inserted
11858      *  into `array`.
11859      * @example
11860      *
11861      * _.sortedIndex([20, 30, 50], 40);
11862      * // => 2
11863      *
11864      * var dict = {
11865      *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
11866      * };
11867      *
11868      * // using `callback`
11869      * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
11870      *   return dict.wordToNumber[word];
11871      * });
11872      * // => 2
11873      *
11874      * // using `callback` with `thisArg`
11875      * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
11876      *   return this.wordToNumber[word];
11877      * }, dict);
11878      * // => 2
11879      *
11880      * // using "_.pluck" callback shorthand
11881      * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
11882      * // => 2
11883      */
11884     function sortedIndex(array, value, callback, thisArg) {
11885       var low = 0,
11886           high = array ? array.length : low;
11887
11888       // explicitly reference `identity` for better inlining in Firefox
11889       callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
11890       value = callback(value);
11891
11892       while (low < high) {
11893         var mid = (low + high) >>> 1;
11894         (callback(array[mid]) < value)
11895           ? low = mid + 1
11896           : high = mid;
11897       }
11898       return low;
11899     }
11900
11901     /**
11902      * Creates an array of unique values, in order, of the provided arrays using
11903      * strict equality for comparisons, i.e. `===`.
11904      *
11905      * @static
11906      * @memberOf _
11907      * @category Arrays
11908      * @param {...Array} [array] The arrays to inspect.
11909      * @returns {Array} Returns an array of combined values.
11910      * @example
11911      *
11912      * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
11913      * // => [1, 2, 3, 5, 4]
11914      */
11915     function union() {
11916       return baseUniq(baseFlatten(arguments, true, true));
11917     }
11918
11919     /**
11920      * Creates a duplicate-value-free version of an array using strict equality
11921      * for comparisons, i.e. `===`. If the array is sorted, providing
11922      * `true` for `isSorted` will use a faster algorithm. If a callback is provided
11923      * each element of `array` is passed through the callback before uniqueness
11924      * is computed. The callback is bound to `thisArg` and invoked with three
11925      * arguments; (value, index, array).
11926      *
11927      * If a property name is provided for `callback` the created "_.pluck" style
11928      * callback will return the property value of the given element.
11929      *
11930      * If an object is provided for `callback` the created "_.where" style callback
11931      * will return `true` for elements that have the properties of the given object,
11932      * else `false`.
11933      *
11934      * @static
11935      * @memberOf _
11936      * @alias unique
11937      * @category Arrays
11938      * @param {Array} array The array to process.
11939      * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
11940      * @param {Function|Object|string} [callback=identity] The function called
11941      *  per iteration. If a property name or object is provided it will be used
11942      *  to create a "_.pluck" or "_.where" style callback, respectively.
11943      * @param {*} [thisArg] The `this` binding of `callback`.
11944      * @returns {Array} Returns a duplicate-value-free array.
11945      * @example
11946      *
11947      * _.uniq([1, 2, 1, 3, 1]);
11948      * // => [1, 2, 3]
11949      *
11950      * // using `isSorted`
11951      * _.uniq([1, 1, 2, 2, 3], true);
11952      * // => [1, 2, 3]
11953      *
11954      * // using `callback`
11955      * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
11956      * // => ['A', 'b', 'C']
11957      *
11958      * // using `callback` with `thisArg`
11959      * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
11960      * // => [1, 2.5, 3]
11961      *
11962      * // using "_.pluck" callback shorthand
11963      * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
11964      * // => [{ 'x': 1 }, { 'x': 2 }]
11965      */
11966     function uniq(array, isSorted, callback, thisArg) {
11967       var type = typeof isSorted;
11968
11969       // juggle arguments
11970       if (type != 'boolean' && isSorted != null) {
11971         thisArg = callback;
11972         callback = isSorted;
11973         isSorted = false;
11974
11975         // enables use as a callback for functions like `_.map`
11976         if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) {
11977           callback = null;
11978         }
11979       }
11980       if (callback != null) {
11981         callback = lodash.createCallback(callback, thisArg, 3);
11982       }
11983       return baseUniq(array, isSorted, callback);
11984     }
11985
11986     /**
11987      * Creates an array excluding all provided values using strict equality for
11988      * comparisons, i.e. `===`.
11989      *
11990      * @static
11991      * @memberOf _
11992      * @category Arrays
11993      * @param {Array} array The array to filter.
11994      * @param {...*} [value] The values to exclude.
11995      * @returns {Array} Returns a new array of filtered values.
11996      * @example
11997      *
11998      * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
11999      * // => [2, 3, 4]
12000      */
12001     function without(array) {
12002       return baseDifference(array, slice(arguments, 1));
12003     }
12004
12005     /**
12006      * Creates an array that is the symmetric difference of the provided arrays.
12007      * See [Wikipedia](http://en.wikipedia.org/wiki/Symmetric_difference) for more details.
12008      *
12009      * @static
12010      * @memberOf _
12011      * @category Arrays
12012      * @param {...Array} [array] The arrays to inspect.
12013      * @returns {Array} Returns an array of values.
12014      * @example
12015      *
12016      * _.xor([1, 2, 3], [5, 2, 1, 4]);
12017      * // => [3, 5, 4]
12018      *
12019      * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
12020      * // => [1, 4, 5]
12021      */
12022     function xor() {
12023       var index = -1,
12024           length = arguments.length;
12025
12026       while (++index < length) {
12027         var array = arguments[index];
12028         if (isArray(array) || isArguments(array)) {
12029           var result = result
12030             ? baseDifference(result, array).concat(baseDifference(array, result))
12031             : array;
12032         }
12033       }
12034       return result ? baseUniq(result) : [];
12035     }
12036
12037     /**
12038      * Creates an array of grouped elements, the first of which contains the first
12039      * elements of the given arrays, the second of which contains the second elements
12040      * of the given arrays, and so on. If a zipped value is provided its corresponding
12041      * unzipped value will be returned.
12042      *
12043      * @static
12044      * @memberOf _
12045      * @alias unzip
12046      * @category Arrays
12047      * @param {...Array} [array] Arrays to process.
12048      * @returns {Array} Returns a new array of grouped elements.
12049      * @example
12050      *
12051      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
12052      * // => [['fred', 30, true], ['barney', 40, false]]
12053      *
12054      * _.unzip([['fred', 30, true], ['barney', 40, false]]);
12055      * // => [['fred', 'barney'], [30, 40], [true, false]]
12056      */
12057     function zip() {
12058       var array = arguments.length > 1 ? arguments : arguments[0],
12059           index = -1,
12060           length = array ? max(pluck(array, 'length')) : 0,
12061           result = Array(length < 0 ? 0 : length);
12062
12063       while (++index < length) {
12064         result[index] = pluck(array, index);
12065       }
12066       return result;
12067     }
12068
12069     /**
12070      * Creates an object composed from arrays of `keys` and `values`. Provide
12071      * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
12072      * or two arrays, one of `keys` and one of corresponding `values`.
12073      *
12074      * @static
12075      * @memberOf _
12076      * @alias object
12077      * @category Arrays
12078      * @param {Array} keys The array of keys.
12079      * @param {Array} [values=[]] The array of values.
12080      * @returns {Object} Returns an object composed of the given keys and
12081      *  corresponding values.
12082      * @example
12083      *
12084      * _.zipObject(['fred', 'barney'], [30, 40]);
12085      * // => { 'fred': 30, 'barney': 40 }
12086      */
12087     function zipObject(keys, values) {
12088       var index = -1,
12089           length = keys ? keys.length : 0,
12090           result = {};
12091
12092       if (!values && length && !isArray(keys[0])) {
12093         values = [];
12094       }
12095       while (++index < length) {
12096         var key = keys[index];
12097         if (values) {
12098           result[key] = values[index];
12099         } else if (key) {
12100           result[key[0]] = key[1];
12101         }
12102       }
12103       return result;
12104     }
12105
12106     /*--------------------------------------------------------------------------*/
12107
12108     /**
12109      * Creates a `lodash` object that wraps `value` with explicit method
12110      * chaining enabled.
12111      *
12112      * @static
12113      * @memberOf _
12114      * @category Chaining
12115      * @param {*} value The value to wrap.
12116      * @returns {Object} Returns the wrapper object.
12117      * @example
12118      *
12119      * var characters = [
12120      *   { 'name': 'barney',  'age': 36 },
12121      *   { 'name': 'fred',    'age': 40 },
12122      *   { 'name': 'pebbles', 'age': 1 }
12123      * ];
12124      *
12125      * var youngest = _.chain(characters)
12126      *     .sortBy('age')
12127      *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
12128      *     .first()
12129      *     .value();
12130      * // => 'pebbles is 1'
12131      */
12132     function chain(value) {
12133       value = new lodashWrapper(value);
12134       value.__chain__ = true;
12135       return value;
12136     }
12137
12138     /**
12139      * This method invokes `interceptor` and returns `value`. The interceptor is
12140      * bound to `thisArg` and invoked with one argument; (value). The purpose of
12141      * this method is to "tap into" a method chain in order to perform operations
12142      * on intermediate results within the chain.
12143      *
12144      * @static
12145      * @memberOf _
12146      * @category Chaining
12147      * @param {*} value The value to provide to `interceptor`.
12148      * @param {Function} interceptor The function to invoke.
12149      * @param {*} [thisArg] The `this` binding of `interceptor`.
12150      * @returns {*} Returns `value`.
12151      * @example
12152      *
12153      * _([1, 2, 3, 4])
12154      *  .tap(function(array) { array.pop(); })
12155      *  .reverse()
12156      *  .value();
12157      * // => [3, 2, 1]
12158      */
12159     function tap(value, interceptor, thisArg) {
12160       interceptor.call(thisArg, value);
12161       return value;
12162     }
12163
12164     /**
12165      * Enables explicit method chaining on the wrapper object.
12166      *
12167      * @name chain
12168      * @memberOf _
12169      * @category Chaining
12170      * @returns {*} Returns the wrapper object.
12171      * @example
12172      *
12173      * var characters = [
12174      *   { 'name': 'barney', 'age': 36 },
12175      *   { 'name': 'fred',   'age': 40 }
12176      * ];
12177      *
12178      * // without explicit chaining
12179      * _(characters).first();
12180      * // => { 'name': 'barney', 'age': 36 }
12181      *
12182      * // with explicit chaining
12183      * _(characters).chain()
12184      *   .first()
12185      *   .pick('age')
12186      *   .value();
12187      * // => { 'age': 36 }
12188      */
12189     function wrapperChain() {
12190       this.__chain__ = true;
12191       return this;
12192     }
12193
12194     /**
12195      * Produces the `toString` result of the wrapped value.
12196      *
12197      * @name toString
12198      * @memberOf _
12199      * @category Chaining
12200      * @returns {string} Returns the string result.
12201      * @example
12202      *
12203      * _([1, 2, 3]).toString();
12204      * // => '1,2,3'
12205      */
12206     function wrapperToString() {
12207       return String(this.__wrapped__);
12208     }
12209
12210     /**
12211      * Extracts the wrapped value.
12212      *
12213      * @name valueOf
12214      * @memberOf _
12215      * @alias value
12216      * @category Chaining
12217      * @returns {*} Returns the wrapped value.
12218      * @example
12219      *
12220      * _([1, 2, 3]).valueOf();
12221      * // => [1, 2, 3]
12222      */
12223     function wrapperValueOf() {
12224       return this.__wrapped__;
12225     }
12226
12227     /*--------------------------------------------------------------------------*/
12228
12229
12230     /**
12231      * Creates an array of elements from the specified indexes, or keys, of the
12232      * `collection`. Indexes may be specified as individual arguments or as arrays
12233      * of indexes.
12234      *
12235      * @static
12236      * @memberOf _
12237      * @category Collections
12238      * @param {Array|Object|string} collection The collection to iterate over.
12239      * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
12240      *   to retrieve, specified as individual indexes or arrays of indexes.
12241      * @returns {Array} Returns a new array of elements corresponding to the
12242      *  provided indexes.
12243      * @example
12244      *
12245      * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
12246      * // => ['a', 'c', 'e']
12247      *
12248      * _.at(['fred', 'barney', 'pebbles'], 0, 2);
12249      * // => ['fred', 'pebbles']
12250      */
12251     function at(collection, guard) {
12252       var args = arguments,
12253           index = -1,
12254           props = baseFlatten(args, true, false, 1),
12255           length = props.length,
12256           type = typeof guard;
12257
12258       // enables use as a callback for functions like `_.map`
12259       if ((type == 'number' || type == 'string') && args[2] && args[2][guard] === collection) {
12260         length = 1;
12261       }
12262       if (support.unindexedChars && isString(collection)) {
12263         collection = collection.split('');
12264       }
12265       var result = Array(length);
12266       while(++index < length) {
12267         result[index] = collection[props[index]];
12268       }
12269       return result;
12270     }
12271
12272     /**
12273      * Checks if a given value is present in a collection using strict equality
12274      * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
12275      * offset from the end of the collection.
12276      *
12277      * @static
12278      * @memberOf _
12279      * @alias include
12280      * @category Collections
12281      * @param {Array|Object|string} collection The collection to iterate over.
12282      * @param {*} target The value to check for.
12283      * @param {number} [fromIndex=0] The index to search from.
12284      * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
12285      * @example
12286      *
12287      * _.contains([1, 2, 3], 1);
12288      * // => true
12289      *
12290      * _.contains([1, 2, 3], 1, 2);
12291      * // => false
12292      *
12293      * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
12294      * // => true
12295      *
12296      * _.contains('pebbles', 'eb');
12297      * // => true
12298      */
12299     function contains(collection, target, fromIndex) {
12300       var length = collection ? collection.length : 0;
12301       fromIndex = typeof fromIndex == 'number' ? fromIndex : 0;
12302
12303       if (typeof length == 'number') {
12304         if (fromIndex >= length) {
12305           return false;
12306         }
12307         if (typeof collection == 'string' || !isArray(collection) && isString(collection)) {
12308           return nativeContains
12309             ? nativeContains.call(collection, target, fromIndex)
12310             : collection.indexOf(target, fromIndex) > -1;
12311         }
12312         var indexOf = getIndexOf();
12313         fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
12314         return indexOf(collection, target, fromIndex) > -1;
12315       }
12316       var index = -1,
12317           result = false;
12318
12319       baseEach(collection, function(value) {
12320         if (++index >= fromIndex) {
12321           return !(result = value === target);
12322         }
12323       });
12324
12325       return result;
12326     }
12327
12328     /**
12329      * Creates an object composed of keys generated from the results of running
12330      * each element of `collection` through the callback. The corresponding value
12331      * of each key is the number of times the key was returned by the callback.
12332      * The callback is bound to `thisArg` and invoked with three arguments;
12333      * (value, index|key, collection).
12334      *
12335      * If a property name is provided for `callback` the created "_.pluck" style
12336      * callback will return the property value of the given element.
12337      *
12338      * If an object is provided for `callback` the created "_.where" style callback
12339      * will return `true` for elements that have the properties of the given object,
12340      * else `false`.
12341      *
12342      * @static
12343      * @memberOf _
12344      * @category Collections
12345      * @param {Array|Object|string} collection The collection to iterate over.
12346      * @param {Function|Object|string} [callback=identity] The function called
12347      *  per iteration. If a property name or object is provided it will be used
12348      *  to create a "_.pluck" or "_.where" style callback, respectively.
12349      * @param {*} [thisArg] The `this` binding of `callback`.
12350      * @returns {Object} Returns the composed aggregate object.
12351      * @example
12352      *
12353      * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
12354      * // => { '4': 1, '6': 2 }
12355      *
12356      * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
12357      * // => { '4': 1, '6': 2 }
12358      *
12359      * _.countBy(['one', 'two', 'three'], 'length');
12360      * // => { '3': 2, '5': 1 }
12361      */
12362     var countBy = createAggregator(function(result, value, key) {
12363       (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
12364     });
12365
12366     /**
12367      * Checks if the callback returns truey value for **all** elements of a
12368      * collection. The callback is bound to `thisArg` and invoked with three
12369      * arguments; (value, index|key, collection).
12370      *
12371      * If a property name is provided for `callback` the created "_.pluck" style
12372      * callback will return the property value of the given element.
12373      *
12374      * If an object is provided for `callback` the created "_.where" style callback
12375      * will return `true` for elements that have the properties of the given object,
12376      * else `false`.
12377      *
12378      * @static
12379      * @memberOf _
12380      * @alias all
12381      * @category Collections
12382      * @param {Array|Object|string} collection The collection to iterate over.
12383      * @param {Function|Object|string} [callback=identity] The function called
12384      *  per iteration. If a property name or object is provided it will be used
12385      *  to create a "_.pluck" or "_.where" style callback, respectively.
12386      * @param {*} [thisArg] The `this` binding of `callback`.
12387      * @returns {boolean} Returns `true` if all elements passed the callback check,
12388      *  else `false`.
12389      * @example
12390      *
12391      * _.every([true, 1, null, 'yes']);
12392      * // => false
12393      *
12394      * var characters = [
12395      *   { 'name': 'barney', 'age': 36 },
12396      *   { 'name': 'fred',   'age': 40 }
12397      * ];
12398      *
12399      * // using "_.pluck" callback shorthand
12400      * _.every(characters, 'age');
12401      * // => true
12402      *
12403      * // using "_.where" callback shorthand
12404      * _.every(characters, { 'age': 36 });
12405      * // => false
12406      */
12407     function every(collection, callback, thisArg) {
12408       var result = true;
12409
12410       callback = lodash.createCallback(callback, thisArg, 3);
12411       if (isArray(collection)) {
12412         var index = -1,
12413             length = collection.length;
12414
12415         while (++index < length) {
12416           if (!callback(collection[index], index, collection)) {
12417             return false;
12418           }
12419         }
12420       } else {
12421         baseEach(collection, function(value, index, collection) {
12422           return (result = !!callback(value, index, collection));
12423         });
12424       }
12425       return result;
12426     }
12427
12428     /**
12429      * Iterates over elements of a collection, returning an array of all elements
12430      * the callback returns truey for. The callback is bound to `thisArg` and
12431      * invoked with three arguments; (value, index|key, collection).
12432      *
12433      * If a property name is provided for `callback` the created "_.pluck" style
12434      * callback will return the property value of the given element.
12435      *
12436      * If an object is provided for `callback` the created "_.where" style callback
12437      * will return `true` for elements that have the properties of the given object,
12438      * else `false`.
12439      *
12440      * @static
12441      * @memberOf _
12442      * @alias select
12443      * @category Collections
12444      * @param {Array|Object|string} collection The collection to iterate over.
12445      * @param {Function|Object|string} [callback=identity] The function called
12446      *  per iteration. If a property name or object is provided it will be used
12447      *  to create a "_.pluck" or "_.where" style callback, respectively.
12448      * @param {*} [thisArg] The `this` binding of `callback`.
12449      * @returns {Array} Returns a new array of elements that passed the callback check.
12450      * @example
12451      *
12452      * var evens = _.filter([1, 2, 3, 4], function(num) { return num % 2 == 0; });
12453      * // => [2, 4]
12454      *
12455      * var characters = [
12456      *   { 'name': 'barney', 'age': 36 },
12457      *   { 'name': 'fred',   'age': 40, 'blocked': true }
12458      * ];
12459      *
12460      * // using "_.pluck" callback shorthand
12461      * _.filter(characters, 'blocked');
12462      * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
12463      *
12464      * // using "_.where" callback shorthand
12465      * _.filter(characters, { 'age': 36 });
12466      * // => [{ 'name': 'barney', 'age': 36 }]
12467      */
12468     function filter(collection, callback, thisArg) {
12469       var result = [];
12470
12471       callback = lodash.createCallback(callback, thisArg, 3);
12472       if (isArray(collection)) {
12473         var index = -1,
12474             length = collection.length;
12475
12476         while (++index < length) {
12477           var value = collection[index];
12478           if (callback(value, index, collection)) {
12479             result.push(value);
12480           }
12481         }
12482       } else {
12483         baseEach(collection, function(value, index, collection) {
12484           if (callback(value, index, collection)) {
12485             result.push(value);
12486           }
12487         });
12488       }
12489       return result;
12490     }
12491
12492     /**
12493      * Iterates over elements of a collection, returning the first element that
12494      * the callback returns truey for. The callback is bound to `thisArg` and
12495      * invoked with three arguments; (value, index|key, collection).
12496      *
12497      * If a property name is provided for `callback` the created "_.pluck" style
12498      * callback will return the property value of the given element.
12499      *
12500      * If an object is provided for `callback` the created "_.where" style callback
12501      * will return `true` for elements that have the properties of the given object,
12502      * else `false`.
12503      *
12504      * @static
12505      * @memberOf _
12506      * @alias detect, findWhere
12507      * @category Collections
12508      * @param {Array|Object|string} collection The collection to iterate over.
12509      * @param {Function|Object|string} [callback=identity] The function called
12510      *  per iteration. If a property name or object is provided it will be used
12511      *  to create a "_.pluck" or "_.where" style callback, respectively.
12512      * @param {*} [thisArg] The `this` binding of `callback`.
12513      * @returns {*} Returns the found element, else `undefined`.
12514      * @example
12515      *
12516      * var characters = [
12517      *   { 'name': 'barney',  'age': 36 },
12518      *   { 'name': 'fred',    'age': 40, 'blocked': true },
12519      *   { 'name': 'pebbles', 'age': 1 }
12520      * ];
12521      *
12522      * _.find(characters, function(chr) {
12523      *   return chr.age < 40;
12524      * });
12525      * // => { 'name': 'barney', 'age': 36 }
12526      *
12527      * // using "_.where" callback shorthand
12528      * _.find(characters, { 'age': 1 });
12529      * // =>  { 'name': 'pebbles', 'age': 1 }
12530      *
12531      * // using "_.pluck" callback shorthand
12532      * _.find(characters, 'blocked');
12533      * // => { 'name': 'fred', 'age': 40, 'blocked': true }
12534      */
12535     function find(collection, callback, thisArg) {
12536       callback = lodash.createCallback(callback, thisArg, 3);
12537       if (isArray(collection)) {
12538         var index = -1,
12539             length = collection.length;
12540
12541         while (++index < length) {
12542           var value = collection[index];
12543           if (callback(value, index, collection)) {
12544             return value;
12545           }
12546         }
12547       } else {
12548         var result;
12549         baseEach(collection, function(value, index, collection) {
12550           if (callback(value, index, collection)) {
12551             result = value;
12552             return false;
12553           }
12554         });
12555         return result;
12556       }
12557     }
12558
12559     /**
12560      * This method is like `_.find` except that it iterates over elements
12561      * of a `collection` from right to left.
12562      *
12563      * @static
12564      * @memberOf _
12565      * @category Collections
12566      * @param {Array|Object|string} collection The collection to iterate over.
12567      * @param {Function|Object|string} [callback=identity] The function called
12568      *  per iteration. If a property name or object is provided it will be used
12569      *  to create a "_.pluck" or "_.where" style callback, respectively.
12570      * @param {*} [thisArg] The `this` binding of `callback`.
12571      * @returns {*} Returns the found element, else `undefined`.
12572      * @example
12573      *
12574      * _.findLast([1, 2, 3, 4], function(num) {
12575      *   return num % 2 == 1;
12576      * });
12577      * // => 3
12578      */
12579     function findLast(collection, callback, thisArg) {
12580       var result;
12581
12582       callback = lodash.createCallback(callback, thisArg, 3);
12583       baseEachRight(collection, function(value, index, collection) {
12584         if (callback(value, index, collection)) {
12585           result = value;
12586           return false;
12587         }
12588       });
12589       return result;
12590     }
12591
12592     /**
12593      * Iterates over elements of a collection, executing the callback for each
12594      * element. The callback is bound to `thisArg` and invoked with three arguments;
12595      * (value, index|key, collection). Callbacks may exit iteration early by
12596      * explicitly returning `false`.
12597      *
12598      * Note: As with other "Collections" methods, objects with a `length` property
12599      * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
12600      * may be used for object iteration.
12601      *
12602      * @static
12603      * @memberOf _
12604      * @alias each
12605      * @category Collections
12606      * @param {Array|Object|string} collection The collection to iterate over.
12607      * @param {Function} [callback=identity] The function called per iteration.
12608      * @param {*} [thisArg] The `this` binding of `callback`.
12609      * @returns {Array|Object|string} Returns `collection`.
12610      * @example
12611      *
12612      * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
12613      * // => logs each number and returns '1,2,3'
12614      *
12615      * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
12616      * // => logs each number and returns the object (property order is not guaranteed across environments)
12617      */
12618     function forEach(collection, callback, thisArg) {
12619       if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
12620         var index = -1,
12621             length = collection.length;
12622
12623         while (++index < length) {
12624           if (callback(collection[index], index, collection) === false) {
12625             break;
12626           }
12627         }
12628       } else {
12629         baseEach(collection, baseCreateCallback(callback, thisArg, 3));
12630       }
12631       return collection;
12632     }
12633
12634     /**
12635      * This method is like `_.forEach` except that it iterates over elements
12636      * of a `collection` from right to left.
12637      *
12638      * @static
12639      * @memberOf _
12640      * @alias eachRight
12641      * @category Collections
12642      * @param {Array|Object|string} collection The collection to iterate over.
12643      * @param {Function} [callback=identity] The function called per iteration.
12644      * @param {*} [thisArg] The `this` binding of `callback`.
12645      * @returns {Array|Object|string} Returns `collection`.
12646      * @example
12647      *
12648      * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
12649      * // => logs each number from right to left and returns '3,2,1'
12650      */
12651     function forEachRight(collection, callback, thisArg) {
12652       if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
12653         var length = collection.length;
12654         while (length--) {
12655           if (callback(collection[length], length, collection) === false) {
12656             break;
12657           }
12658         }
12659       } else {
12660         baseEachRight(collection, baseCreateCallback(callback, thisArg, 3));
12661       }
12662       return collection;
12663     }
12664
12665     /**
12666      * Creates an object composed of keys generated from the results of running
12667      * each element of a collection through the callback. The corresponding value
12668      * of each key is an array of the elements responsible for generating the key.
12669      * The callback is bound to `thisArg` and invoked with three arguments;
12670      * (value, index|key, collection).
12671      *
12672      * If a property name is provided for `callback` the created "_.pluck" style
12673      * callback will return the property value of the given element.
12674      *
12675      * If an object is provided for `callback` the created "_.where" style callback
12676      * will return `true` for elements that have the properties of the given object,
12677      * else `false`.
12678      *
12679      * @static
12680      * @memberOf _
12681      * @category Collections
12682      * @param {Array|Object|string} collection The collection to iterate over.
12683      * @param {Function|Object|string} [callback=identity] The function called
12684      *  per iteration. If a property name or object is provided it will be used
12685      *  to create a "_.pluck" or "_.where" style callback, respectively.
12686      * @param {*} [thisArg] The `this` binding of `callback`.
12687      * @returns {Object} Returns the composed aggregate object.
12688      * @example
12689      *
12690      * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
12691      * // => { '4': [4.2], '6': [6.1, 6.4] }
12692      *
12693      * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
12694      * // => { '4': [4.2], '6': [6.1, 6.4] }
12695      *
12696      * // using "_.pluck" callback shorthand
12697      * _.groupBy(['one', 'two', 'three'], 'length');
12698      * // => { '3': ['one', 'two'], '5': ['three'] }
12699      */
12700     var groupBy = createAggregator(function(result, value, key) {
12701       if (hasOwnProperty.call(result, key)) {
12702         result[key].push(value);
12703       } else {
12704         result[key] = [value];
12705       }
12706     });
12707
12708     /**
12709      * Creates an object composed of keys generated from the results of running
12710      * each element of the collection through the given callback. The corresponding
12711      * value of each key is the last element responsible for generating the key.
12712      * The callback is bound to `thisArg` and invoked with three arguments;
12713      * (value, index|key, collection).
12714      *
12715      * If a property name is provided for `callback` the created "_.pluck" style
12716      * callback will return the property value of the given element.
12717      *
12718      * If an object is provided for `callback` the created "_.where" style callback
12719      * will return `true` for elements that have the properties of the given object,
12720      * else `false`.
12721      *
12722      * @static
12723      * @memberOf _
12724      * @category Collections
12725      * @param {Array|Object|string} collection The collection to iterate over.
12726      * @param {Function|Object|string} [callback=identity] The function called
12727      *  per iteration. If a property name or object is provided it will be used
12728      *  to create a "_.pluck" or "_.where" style callback, respectively.
12729      * @param {*} [thisArg] The `this` binding of `callback`.
12730      * @returns {Object} Returns the composed aggregate object.
12731      * @example
12732      *
12733      * var keys = [
12734      *   { 'dir': 'left', 'code': 97 },
12735      *   { 'dir': 'right', 'code': 100 }
12736      * ];
12737      *
12738      * _.indexBy(keys, 'dir');
12739      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
12740      *
12741      * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
12742      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
12743      *
12744      * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
12745      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
12746      */
12747     var indexBy = createAggregator(function(result, value, key) {
12748       result[key] = value;
12749     });
12750
12751     /**
12752      * Invokes the method named by `methodName` on each element in the `collection`
12753      * returning an array of the results of each invoked method. Additional arguments
12754      * will be provided to each invoked method. If `methodName` is a function it
12755      * will be invoked for, and `this` bound to, each element in the `collection`.
12756      *
12757      * @static
12758      * @memberOf _
12759      * @category Collections
12760      * @param {Array|Object|string} collection The collection to iterate over.
12761      * @param {Function|string} methodName The name of the method to invoke or
12762      *  the function invoked per iteration.
12763      * @param {...*} [args] Arguments to invoke the method with.
12764      * @returns {Array} Returns a new array of the results of each invoked method.
12765      * @example
12766      *
12767      * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
12768      * // => [[1, 5, 7], [1, 2, 3]]
12769      *
12770      * _.invoke([123, 456], String.prototype.split, '');
12771      * // => [['1', '2', '3'], ['4', '5', '6']]
12772      */
12773     function invoke(collection, methodName) {
12774       var index = -1,
12775           isFunc = typeof methodName == 'function',
12776           length = collection ? collection.length : 0,
12777           result = Array(typeof length == 'number' ? length : 0);
12778
12779       if (arguments.length < 3 && isArray(collection)) {
12780         while (++index < length) {
12781           var value = collection[index];
12782           result[index] = isFunc ? methodName.call(value) : value[methodName]();
12783         }
12784       } else {
12785         var args = slice(arguments, 2);
12786         baseEach(collection, function(value) {
12787           result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
12788         });
12789       }
12790       return result;
12791     }
12792
12793     /**
12794      * Creates an array of values by running each element in the collection
12795      * through the callback. The callback is bound to `thisArg` and invoked with
12796      * three arguments; (value, index|key, collection).
12797      *
12798      * If a property name is provided for `callback` the created "_.pluck" style
12799      * callback will return the property value of the given element.
12800      *
12801      * If an object is provided for `callback` the created "_.where" style callback
12802      * will return `true` for elements that have the properties of the given object,
12803      * else `false`.
12804      *
12805      * @static
12806      * @memberOf _
12807      * @alias collect
12808      * @category Collections
12809      * @param {Array|Object|string} collection The collection to iterate over.
12810      * @param {Function|Object|string} [callback=identity] The function called
12811      *  per iteration. If a property name or object is provided it will be used
12812      *  to create a "_.pluck" or "_.where" style callback, respectively.
12813      * @param {*} [thisArg] The `this` binding of `callback`.
12814      * @returns {Array} Returns a new array of the results of each `callback` execution.
12815      * @example
12816      *
12817      * _.map([1, 2, 3], function(num) { return num * 3; });
12818      * // => [3, 6, 9]
12819      *
12820      * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
12821      * // => [3, 6, 9] (property order is not guaranteed across environments)
12822      *
12823      * var characters = [
12824      *   { 'name': 'barney', 'age': 36 },
12825      *   { 'name': 'fred',   'age': 40 }
12826      * ];
12827      *
12828      * // using "_.pluck" callback shorthand
12829      * _.map(characters, 'name');
12830      * // => ['barney', 'fred']
12831      */
12832     function map(collection, callback, thisArg) {
12833       var index = -1,
12834           length = collection ? collection.length : 0,
12835           result = Array(typeof length == 'number' ? length : 0);
12836
12837       callback = lodash.createCallback(callback, thisArg, 3);
12838       if (isArray(collection)) {
12839         while (++index < length) {
12840           result[index] = callback(collection[index], index, collection);
12841         }
12842       } else {
12843         baseEach(collection, function(value, key, collection) {
12844           result[++index] = callback(value, key, collection);
12845         });
12846       }
12847       return result;
12848     }
12849
12850     /**
12851      * Retrieves the maximum value of a collection. If the collection is empty or
12852      * falsey `-Infinity` is returned. If a callback is provided it will be executed
12853      * for each value in the collection to generate the criterion by which the value
12854      * is ranked. The callback is bound to `thisArg` and invoked with three
12855      * arguments; (value, index, collection).
12856      *
12857      * If a property name is provided for `callback` the created "_.pluck" style
12858      * callback will return the property value of the given element.
12859      *
12860      * If an object is provided for `callback` the created "_.where" style callback
12861      * will return `true` for elements that have the properties of the given object,
12862      * else `false`.
12863      *
12864      * @static
12865      * @memberOf _
12866      * @category Collections
12867      * @param {Array|Object|string} collection The collection to iterate over.
12868      * @param {Function|Object|string} [callback=identity] The function called
12869      *  per iteration. If a property name or object is provided it will be used
12870      *  to create a "_.pluck" or "_.where" style callback, respectively.
12871      * @param {*} [thisArg] The `this` binding of `callback`.
12872      * @returns {*} Returns the maximum value.
12873      * @example
12874      *
12875      * _.max([4, 2, 8, 6]);
12876      * // => 8
12877      *
12878      * var characters = [
12879      *   { 'name': 'barney', 'age': 36 },
12880      *   { 'name': 'fred',   'age': 40 }
12881      * ];
12882      *
12883      * _.max(characters, function(chr) { return chr.age; });
12884      * // => { 'name': 'fred', 'age': 40 };
12885      *
12886      * // using "_.pluck" callback shorthand
12887      * _.max(characters, 'age');
12888      * // => { 'name': 'fred', 'age': 40 };
12889      */
12890     function max(collection, callback, thisArg) {
12891       var computed = -Infinity,
12892           result = computed,
12893           type = typeof callback;
12894
12895       // enables use as a callback for functions like `_.map`
12896       if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) {
12897         callback = null;
12898       }
12899       if (callback == null && isArray(collection)) {
12900         var index = -1,
12901             length = collection.length;
12902
12903         while (++index < length) {
12904           var value = collection[index];
12905           if (value > result) {
12906             result = value;
12907           }
12908         }
12909       } else {
12910         callback = (callback == null && isString(collection))
12911           ? charAtCallback
12912           : lodash.createCallback(callback, thisArg, 3);
12913
12914         baseEach(collection, function(value, index, collection) {
12915           var current = callback(value, index, collection);
12916           if (current > computed) {
12917             computed = current;
12918             result = value;
12919           }
12920         });
12921       }
12922       return result;
12923     }
12924
12925     /**
12926      * Retrieves the minimum value of a collection. If the collection is empty or
12927      * falsey `Infinity` is returned. If a callback is provided it will be executed
12928      * for each value in the collection to generate the criterion by which the value
12929      * is ranked. The callback is bound to `thisArg` and invoked with three
12930      * arguments; (value, index, collection).
12931      *
12932      * If a property name is provided for `callback` the created "_.pluck" style
12933      * callback will return the property value of the given element.
12934      *
12935      * If an object is provided for `callback` the created "_.where" style callback
12936      * will return `true` for elements that have the properties of the given object,
12937      * else `false`.
12938      *
12939      * @static
12940      * @memberOf _
12941      * @category Collections
12942      * @param {Array|Object|string} collection The collection to iterate over.
12943      * @param {Function|Object|string} [callback=identity] The function called
12944      *  per iteration. If a property name or object is provided it will be used
12945      *  to create a "_.pluck" or "_.where" style callback, respectively.
12946      * @param {*} [thisArg] The `this` binding of `callback`.
12947      * @returns {*} Returns the minimum value.
12948      * @example
12949      *
12950      * _.min([4, 2, 8, 6]);
12951      * // => 2
12952      *
12953      * var characters = [
12954      *   { 'name': 'barney', 'age': 36 },
12955      *   { 'name': 'fred',   'age': 40 }
12956      * ];
12957      *
12958      * _.min(characters, function(chr) { return chr.age; });
12959      * // => { 'name': 'barney', 'age': 36 };
12960      *
12961      * // using "_.pluck" callback shorthand
12962      * _.min(characters, 'age');
12963      * // => { 'name': 'barney', 'age': 36 };
12964      */
12965     function min(collection, callback, thisArg) {
12966       var computed = Infinity,
12967           result = computed,
12968           type = typeof callback;
12969
12970       // enables use as a callback for functions like `_.map`
12971       if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) {
12972         callback = null;
12973       }
12974       if (callback == null && isArray(collection)) {
12975         var index = -1,
12976             length = collection.length;
12977
12978         while (++index < length) {
12979           var value = collection[index];
12980           if (value < result) {
12981             result = value;
12982           }
12983         }
12984       } else {
12985         callback = (callback == null && isString(collection))
12986           ? charAtCallback
12987           : lodash.createCallback(callback, thisArg, 3);
12988
12989         baseEach(collection, function(value, index, collection) {
12990           var current = callback(value, index, collection);
12991           if (current < computed) {
12992             computed = current;
12993             result = value;
12994           }
12995         });
12996       }
12997       return result;
12998     }
12999
13000     /**
13001      * Creates an array of elements split into two groups, the first of which
13002      * contains elements the callback returns truey for, while the second of which
13003      * contains elements the callback returns falsey for. The callback is bound
13004      * to `thisArg` and invoked with three arguments; (value, index|key, collection).
13005      *
13006      * If a property name is provided for `callback` the created "_.pluck" style
13007      * callback will return the property value of the given element.
13008      *
13009      * If an object is provided for `callback` the created "_.where" style callback
13010      * will return `true` for elements that have the properties of the given object,
13011      * else `false`.
13012      *
13013      * @static
13014      * @memberOf _
13015      * @category Collections
13016      * @param {Array|Object|string} collection The collection to iterate over.
13017      * @param {Function|Object|string} [callback=identity] The function called
13018      *  per iteration. If a property name or object is provided it will be used
13019      *  to create a "_.pluck" or "_.where" style callback, respectively.
13020      * @param {*} [thisArg] The `this` binding of `callback`.
13021      * @returns {Array} Returns a new array of grouped elements.
13022      * @example
13023      *
13024      * _.partition([1, 2, 3], function(num) { return num % 2; });
13025      * // => [[1, 3], [2]]
13026      *
13027      * _.partition([1.2, 2.3, 3.4], function(num) { return this.floor(num) % 2; }, Math);
13028      * // => [[1, 3], [2]]
13029      *
13030      * var characters = [
13031      *   { 'name': 'barney',  'age': 36 },
13032      *   { 'name': 'fred',    'age': 40, 'blocked': true },
13033      *   { 'name': 'pebbles', 'age': 1 }
13034      * ];
13035      *
13036      * // using "_.where" callback shorthand
13037      * _.map(_.partition(characters, { 'age': 1 }), function(array) { return _.pluck(array, 'name'); });
13038      * // => [['pebbles'], ['barney', 'fred']]
13039      *
13040      * // using "_.pluck" callback shorthand
13041      * _.map(_.partition(characters, 'blocked'), function(array) { return _.pluck(array, 'name'); });
13042      * // => [['fred'], ['barney', 'pebbles']]
13043      */
13044     var partition = createAggregator(function(result, value, key) {
13045       result[key ? 0 : 1].push(value);
13046     }, true);
13047
13048     /**
13049      * Retrieves the value of a specified property from all elements in the collection.
13050      *
13051      * @static
13052      * @memberOf _
13053      * @type Function
13054      * @category Collections
13055      * @param {Array|Object|string} collection The collection to iterate over.
13056      * @param {string} key The name of the property to pluck.
13057      * @returns {Array} Returns a new array of property values.
13058      * @example
13059      *
13060      * var characters = [
13061      *   { 'name': 'barney', 'age': 36 },
13062      *   { 'name': 'fred',   'age': 40 }
13063      * ];
13064      *
13065      * _.pluck(characters, 'name');
13066      * // => ['barney', 'fred']
13067      */
13068     var pluck = map;
13069
13070     /**
13071      * Reduces a collection to a value which is the accumulated result of running
13072      * each element in the collection through the callback, where each successive
13073      * callback execution consumes the return value of the previous execution. If
13074      * `accumulator` is not provided the first element of the collection will be
13075      * used as the initial `accumulator` value. The callback is bound to `thisArg`
13076      * and invoked with four arguments; (accumulator, value, index|key, collection).
13077      *
13078      * @static
13079      * @memberOf _
13080      * @alias foldl, inject
13081      * @category Collections
13082      * @param {Array|Object|string} collection The collection to iterate over.
13083      * @param {Function} [callback=identity] The function called per iteration.
13084      * @param {*} [accumulator] Initial value of the accumulator.
13085      * @param {*} [thisArg] The `this` binding of `callback`.
13086      * @returns {*} Returns the accumulated value.
13087      * @example
13088      *
13089      * var sum = _.reduce([1, 2, 3], function(sum, num) {
13090      *   return sum + num;
13091      * });
13092      * // => 6
13093      *
13094      * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
13095      *   result[key] = num * 3;
13096      *   return result;
13097      * }, {});
13098      * // => { 'a': 3, 'b': 6, 'c': 9 }
13099      */
13100     function reduce(collection, callback, accumulator, thisArg) {
13101       var noaccum = arguments.length < 3;
13102
13103       callback = lodash.createCallback(callback, thisArg, 4);
13104       if (isArray(collection)) {
13105         var index = -1,
13106             length = collection.length;
13107
13108         if (noaccum && length) {
13109           accumulator = collection[++index];
13110         }
13111         while (++index < length) {
13112           accumulator = callback(accumulator, collection[index], index, collection);
13113         }
13114       } else {
13115         baseEach(collection, function(value, index, collection) {
13116           accumulator = noaccum
13117             ? (noaccum = false, value)
13118             : callback(accumulator, value, index, collection)
13119         });
13120       }
13121       return accumulator;
13122     }
13123
13124     /**
13125      * This method is like `_.reduce` except that it iterates over elements
13126      * of a `collection` from right to left.
13127      *
13128      * @static
13129      * @memberOf _
13130      * @alias foldr
13131      * @category Collections
13132      * @param {Array|Object|string} collection The collection to iterate over.
13133      * @param {Function} [callback=identity] The function called per iteration.
13134      * @param {*} [accumulator] Initial value of the accumulator.
13135      * @param {*} [thisArg] The `this` binding of `callback`.
13136      * @returns {*} Returns the accumulated value.
13137      * @example
13138      *
13139      * var list = [[0, 1], [2, 3], [4, 5]];
13140      * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
13141      * // => [4, 5, 2, 3, 0, 1]
13142      */
13143     function reduceRight(collection, callback, accumulator, thisArg) {
13144       var noaccum = arguments.length < 3;
13145
13146       callback = lodash.createCallback(callback, thisArg, 4);
13147       baseEachRight(collection, function(value, index, collection) {
13148         accumulator = noaccum
13149           ? (noaccum = false, value)
13150           : callback(accumulator, value, index, collection);
13151       });
13152       return accumulator;
13153     }
13154
13155     /**
13156      * The opposite of `_.filter`; this method returns the elements of a
13157      * collection that the callback does **not** return truey for.
13158      *
13159      * If a property name is provided for `callback` the created "_.pluck" style
13160      * callback will return the property value of the given element.
13161      *
13162      * If an object is provided for `callback` the created "_.where" style callback
13163      * will return `true` for elements that have the properties of the given object,
13164      * else `false`.
13165      *
13166      * @static
13167      * @memberOf _
13168      * @category Collections
13169      * @param {Array|Object|string} collection The collection to iterate over.
13170      * @param {Function|Object|string} [callback=identity] The function called
13171      *  per iteration. If a property name or object is provided it will be used
13172      *  to create a "_.pluck" or "_.where" style callback, respectively.
13173      * @param {*} [thisArg] The `this` binding of `callback`.
13174      * @returns {Array} Returns a new array of elements that failed the callback check.
13175      * @example
13176      *
13177      * var odds = _.reject([1, 2, 3, 4], function(num) { return num % 2 == 0; });
13178      * // => [1, 3]
13179      *
13180      * var characters = [
13181      *   { 'name': 'barney', 'age': 36 },
13182      *   { 'name': 'fred',   'age': 40, 'blocked': true }
13183      * ];
13184      *
13185      * // using "_.pluck" callback shorthand
13186      * _.reject(characters, 'blocked');
13187      * // => [{ 'name': 'barney', 'age': 36 }]
13188      *
13189      * // using "_.where" callback shorthand
13190      * _.reject(characters, { 'age': 36 });
13191      * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
13192      */
13193     function reject(collection, callback, thisArg) {
13194       callback = lodash.createCallback(callback, thisArg, 3);
13195       return filter(collection, function(value, index, collection) {
13196         return !callback(value, index, collection);
13197       });
13198     }
13199
13200     /**
13201      * Retrieves a random element or `n` random elements from a collection.
13202      *
13203      * @static
13204      * @memberOf _
13205      * @category Collections
13206      * @param {Array|Object|string} collection The collection to sample.
13207      * @param {number} [n] The number of elements to sample.
13208      * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
13209      * @returns {*} Returns the random sample(s) of `collection`.
13210      * @example
13211      *
13212      * _.sample([1, 2, 3, 4]);
13213      * // => 2
13214      *
13215      * _.sample([1, 2, 3, 4], 2);
13216      * // => [3, 1]
13217      */
13218     function sample(collection, n, guard) {
13219       if (collection && typeof collection.length != 'number') {
13220         collection = values(collection);
13221       } else if (support.unindexedChars && isString(collection)) {
13222         collection = collection.split('');
13223       }
13224       if (n == null || guard) {
13225         return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
13226       }
13227       var result = shuffle(collection);
13228       result.length = nativeMin(nativeMax(0, n), result.length);
13229       return result;
13230     }
13231
13232     /**
13233      * Creates an array of shuffled values, using a version of the Fisher-Yates
13234      * shuffle. See [Wikipedia](http://en.wikipedia.org/wiki/Fisher-Yates_shuffle) for more details.
13235      *
13236      * @static
13237      * @memberOf _
13238      * @category Collections
13239      * @param {Array|Object|string} collection The collection to shuffle.
13240      * @returns {Array} Returns a new shuffled collection.
13241      * @example
13242      *
13243      * _.shuffle([1, 2, 3, 4]);
13244      * // => [4, 1, 3, 2]
13245      */
13246     function shuffle(collection) {
13247       var index = -1,
13248           length = collection ? collection.length : 0,
13249           result = Array(typeof length == 'number' ? length : 0);
13250
13251       baseEach(collection, function(value) {
13252         var rand = baseRandom(0, ++index);
13253         result[index] = result[rand];
13254         result[rand] = value;
13255       });
13256
13257       return result;
13258     }
13259
13260     /**
13261      * Gets the size of the `collection` by returning `collection.length` for arrays
13262      * and array-like objects or the number of own enumerable properties for objects.
13263      *
13264      * @static
13265      * @memberOf _
13266      * @category Collections
13267      * @param {Array|Object|string} collection The collection to inspect.
13268      * @returns {number} Returns `collection.length` or number of own enumerable properties.
13269      * @example
13270      *
13271      * _.size([1, 2]);
13272      * // => 2
13273      *
13274      * _.size({ 'one': 1, 'two': 2, 'three': 3 });
13275      * // => 3
13276      *
13277      * _.size('pebbles');
13278      * // => 7
13279      */
13280     function size(collection) {
13281       var length = collection ? collection.length : 0;
13282       return typeof length == 'number' ? length : keys(collection).length;
13283     }
13284
13285     /**
13286      * Checks if the callback returns a truey value for **any** element of a
13287      * collection. The function returns as soon as it finds a passing value and
13288      * does not iterate over the entire collection. The callback is bound to
13289      * `thisArg` and invoked with three arguments; (value, index|key, collection).
13290      *
13291      * If a property name is provided for `callback` the created "_.pluck" style
13292      * callback will return the property value of the given element.
13293      *
13294      * If an object is provided for `callback` the created "_.where" style callback
13295      * will return `true` for elements that have the properties of the given object,
13296      * else `false`.
13297      *
13298      * @static
13299      * @memberOf _
13300      * @alias any
13301      * @category Collections
13302      * @param {Array|Object|string} collection The collection to iterate over.
13303      * @param {Function|Object|string} [callback=identity] The function called
13304      *  per iteration. If a property name or object is provided it will be used
13305      *  to create a "_.pluck" or "_.where" style callback, respectively.
13306      * @param {*} [thisArg] The `this` binding of `callback`.
13307      * @returns {boolean} Returns `true` if any element passed the callback check,
13308      *  else `false`.
13309      * @example
13310      *
13311      * _.some([null, 0, 'yes', false], Boolean);
13312      * // => true
13313      *
13314      * var characters = [
13315      *   { 'name': 'barney', 'age': 36 },
13316      *   { 'name': 'fred',   'age': 40, 'blocked': true }
13317      * ];
13318      *
13319      * // using "_.pluck" callback shorthand
13320      * _.some(characters, 'blocked');
13321      * // => true
13322      *
13323      * // using "_.where" callback shorthand
13324      * _.some(characters, { 'age': 1 });
13325      * // => false
13326      */
13327     function some(collection, callback, thisArg) {
13328       var result;
13329
13330       callback = lodash.createCallback(callback, thisArg, 3);
13331       if (isArray(collection)) {
13332         var index = -1,
13333             length = collection.length;
13334
13335         while (++index < length) {
13336           if (callback(collection[index], index, collection)) {
13337             return true;
13338           }
13339         }
13340       } else {
13341         baseEach(collection, function(value, index, collection) {
13342           return !(result = callback(value, index, collection));
13343         });
13344       }
13345       return !!result;
13346     }
13347
13348     /**
13349      * Creates an array of elements, sorted in ascending order by the results of
13350      * running each element in a collection through the callback. This method
13351      * performs a stable sort, that is, it will preserve the original sort order
13352      * of equal elements. The callback is bound to `thisArg` and invoked with
13353      * three arguments; (value, index|key, collection).
13354      *
13355      * If a property name is provided for `callback` the created "_.pluck" style
13356      * callback will return the property value of the given element.
13357      *
13358      * If an array of property names is provided for `callback` the collection
13359      * will be sorted by each property value.
13360      *
13361      * If an object is provided for `callback` the created "_.where" style callback
13362      * will return `true` for elements that have the properties of the given object,
13363      * else `false`.
13364      *
13365      * @static
13366      * @memberOf _
13367      * @category Collections
13368      * @param {Array|Object|string} collection The collection to iterate over.
13369      * @param {Array|Function|Object|string} [callback=identity] The function called
13370      *  per iteration. If a property name or object is provided it will be used
13371      *  to create a "_.pluck" or "_.where" style callback, respectively.
13372      * @param {*} [thisArg] The `this` binding of `callback`.
13373      * @returns {Array} Returns a new array of sorted elements.
13374      * @example
13375      *
13376      * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
13377      * // => [3, 1, 2]
13378      *
13379      * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
13380      * // => [3, 1, 2]
13381      *
13382      * var characters = [
13383      *   { 'name': 'barney',  'age': 36 },
13384      *   { 'name': 'fred',    'age': 40 },
13385      *   { 'name': 'barney',  'age': 26 },
13386      *   { 'name': 'fred',    'age': 30 }
13387      * ];
13388      *
13389      * // using "_.pluck" callback shorthand
13390      * _.map(_.sortBy(characters, 'age'), _.values);
13391      * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
13392      *
13393      * // sorting by multiple properties
13394      * _.map(_.sortBy(characters, ['name', 'age']), _.values);
13395      * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
13396      */
13397     function sortBy(collection, callback, thisArg) {
13398       var index = -1,
13399           multi = callback && isArray(callback),
13400           length = collection ? collection.length : 0,
13401           result = Array(typeof length == 'number' ? length : 0);
13402
13403       if (!multi) {
13404         callback = lodash.createCallback(callback, thisArg, 3);
13405       }
13406       baseEach(collection, function(value, key, collection) {
13407         if (multi) {
13408           var length = callback.length,
13409               criteria = Array(length);
13410
13411           while (length--) {
13412             criteria[length] = value[callback[length]];
13413           }
13414         } else {
13415           criteria = callback(value, key, collection);
13416         }
13417         var object = result[++index] = getObject();
13418         object.criteria = criteria;
13419         object.index = index;
13420         object.value = value;
13421       });
13422
13423       length = result.length;
13424       result.sort(multi ? compareMultipleAscending : compareAscending);
13425       while (length--) {
13426         var object = result[length];
13427         result[length] = object.value;
13428         releaseObject(object);
13429       }
13430       return result;
13431     }
13432
13433     /**
13434      * Converts the `collection` to an array.
13435      *
13436      * @static
13437      * @memberOf _
13438      * @category Collections
13439      * @param {Array|Object|string} collection The collection to convert.
13440      * @returns {Array} Returns the new converted array.
13441      * @example
13442      *
13443      * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
13444      * // => [2, 3, 4]
13445      */
13446     function toArray(collection) {
13447       if (collection && typeof collection.length == 'number') {
13448         return (support.unindexedChars && isString(collection))
13449           ? collection.split('')
13450           : slice(collection);
13451       }
13452       return values(collection);
13453     }
13454
13455     /**
13456      * Performs a deep comparison between each element in `collection` and the
13457      * `source` object, returning an array of all elements that have equivalent
13458      * property values.
13459      *
13460      * @static
13461      * @memberOf _
13462      * @type Function
13463      * @category Collections
13464      * @param {Array|Object|string} collection The collection to iterate over.
13465      * @param {Object} source The object of property values to filter by.
13466      * @returns {Array} Returns a new array of elements that have the given properties.
13467      * @example
13468      *
13469      * var characters = [
13470      *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
13471      *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
13472      * ];
13473      *
13474      * _.where(characters, { 'age': 36 });
13475      * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
13476      *
13477      * _.where(characters, { 'pets': ['dino'] });
13478      * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
13479      */
13480     var where = filter;
13481
13482     /*--------------------------------------------------------------------------*/
13483
13484     /**
13485      * Creates a function that executes `func`, with  the `this` binding and
13486      * arguments of the created function, only after being called `n` times.
13487      *
13488      * @static
13489      * @memberOf _
13490      * @category Functions
13491      * @param {number} n The number of times the function must be called before
13492      *  `func` is executed.
13493      * @param {Function} func The function to restrict.
13494      * @returns {Function} Returns the new restricted function.
13495      * @example
13496      *
13497      * var saves = ['profile', 'settings'];
13498      *
13499      * var done = _.after(saves.length, function() {
13500      *   console.log('Done saving!');
13501      * });
13502      *
13503      * _.forEach(saves, function(type) {
13504      *   asyncSave({ 'type': type, 'complete': done });
13505      * });
13506      * // => logs 'Done saving!', after all saves have completed
13507      */
13508     function after(n, func) {
13509       if (!isFunction(func)) {
13510         throw new TypeError;
13511       }
13512       return function() {
13513         if (--n < 1) {
13514           return func.apply(this, arguments);
13515         }
13516       };
13517     }
13518
13519     /**
13520      * Creates a function that, when called, invokes `func` with the `this`
13521      * binding of `thisArg` and prepends any additional `bind` arguments to those
13522      * provided to the bound function.
13523      *
13524      * Note: Unlike native `Function#bind` this method does not set the `length`
13525      * property of bound functions.
13526      *
13527      * @static
13528      * @memberOf _
13529      * @category Functions
13530      * @param {Function} func The function to bind.
13531      * @param {*} [thisArg] The `this` binding of `func`.
13532      * @param {...*} [args] Arguments to be partially applied.
13533      * @returns {Function} Returns the new bound function.
13534      * @example
13535      *
13536      * var func = function(greeting) {
13537      *   return greeting + ' ' + this.name;
13538      * };
13539      *
13540      * func = _.bind(func, { 'name': 'fred' }, 'hi');
13541      * func();
13542      * // => 'hi fred'
13543      */
13544     function bind(func, thisArg) {
13545       if (arguments.length < 3) {
13546         return createWrapper(func, BIND_FLAG, null, thisArg);
13547       }
13548       if (func) {
13549         var arity = func[expando] ? func[expando][2] : func.length,
13550             partialArgs = slice(arguments, 2);
13551
13552         arity -= partialArgs.length;
13553       }
13554       return createWrapper(func, BIND_FLAG | PARTIAL_FLAG, arity, thisArg, partialArgs);
13555     }
13556
13557     /**
13558      * Binds methods of an object to the object itself, overwriting the existing
13559      * method. Method names may be specified as individual arguments or as arrays
13560      * of method names. If no method names are provided all the function properties
13561      * of `object` will be bound.
13562      *
13563      * Note: This method does not set the `length` property of bound functions.
13564      *
13565      * @static
13566      * @memberOf _
13567      * @category Functions
13568      * @param {Object} object The object to bind and assign the bound methods to.
13569      * @param {...string} [methodName] The object method names to
13570      *  bind, specified as individual method names or arrays of method names.
13571      * @returns {Object} Returns `object`.
13572      * @example
13573      *
13574      * var view = {
13575      *   'label': 'docs',
13576      *   'onClick': function() { console.log('clicked ' + this.label); }
13577      * };
13578      *
13579      * _.bindAll(view);
13580      * jQuery('#docs').on('click', view.onClick);
13581      * // => logs 'clicked docs', when the button is clicked
13582      */
13583     function bindAll(object) {
13584       var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
13585           index = -1,
13586           length = funcs.length;
13587
13588       while (++index < length) {
13589         var key = funcs[index];
13590         object[key] = createWrapper(object[key], BIND_FLAG, null, object);
13591       }
13592       return object;
13593     }
13594
13595     /**
13596      * Creates a function that, when called, invokes the method at `object[key]`
13597      * and prepends any additional `bindKey` arguments to those provided to the bound
13598      * function. This method differs from `_.bind` by allowing bound functions to
13599      * reference methods that will be redefined or don't yet exist.
13600      * See [Peter Michaux's article](http://michaux.ca/articles/lazy-function-definition-pattern)
13601      * for more details.
13602      *
13603      * @static
13604      * @memberOf _
13605      * @category Functions
13606      * @param {Object} object The object the method belongs to.
13607      * @param {string} key The key of the method.
13608      * @param {...*} [args] Arguments to be partially applied.
13609      * @returns {Function} Returns the new bound function.
13610      * @example
13611      *
13612      * var object = {
13613      *   'name': 'fred',
13614      *   'greet': function(greeting) {
13615      *     return greeting + ' ' + this.name;
13616      *   }
13617      * };
13618      *
13619      * var func = _.bindKey(object, 'greet', 'hi');
13620      * func();
13621      * // => 'hi fred'
13622      *
13623      * object.greet = function(greeting) {
13624      *   return greeting + 'ya ' + this.name + '!';
13625      * };
13626      *
13627      * func();
13628      * // => 'hiya fred!'
13629      */
13630     function bindKey(object, key) {
13631       return arguments.length < 3
13632         ? createWrapper(key, BIND_FLAG | BIND_KEY_FLAG, null, object)
13633         : createWrapper(key, BIND_FLAG | BIND_KEY_FLAG | PARTIAL_FLAG, null, object, slice(arguments, 2));
13634     }
13635
13636     /**
13637      * Creates a function that is the composition of the provided functions,
13638      * where each function consumes the return value of the function that follows.
13639      * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
13640      * Each function is executed with the `this` binding of the composed function.
13641      *
13642      * @static
13643      * @memberOf _
13644      * @category Functions
13645      * @param {...Function} [func] Functions to compose.
13646      * @returns {Function} Returns the new composed function.
13647      * @example
13648      *
13649      * var realNameMap = {
13650      *   'pebbles': 'penelope'
13651      * };
13652      *
13653      * var format = function(name) {
13654      *   name = realNameMap[name.toLowerCase()] || name;
13655      *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
13656      * };
13657      *
13658      * var greet = function(formatted) {
13659      *   return 'Hiya ' + formatted + '!';
13660      * };
13661      *
13662      * var welcome = _.compose(greet, format);
13663      * welcome('pebbles');
13664      * // => 'Hiya Penelope!'
13665      */
13666     function compose() {
13667       var funcs = arguments,
13668           funcsLength = funcs.length,
13669           length = funcsLength;
13670
13671       while (length--) {
13672         if (!isFunction(funcs[length])) {
13673           throw new TypeError;
13674         }
13675       }
13676       return function() {
13677         var length = funcsLength - 1,
13678             result = funcs[length].apply(this, arguments);
13679
13680         while (length--) {
13681           result = funcs[length].call(this, result);
13682         }
13683         return result;
13684       };
13685     }
13686
13687     /**
13688      * Creates a function which accepts one or more arguments of `func` that when
13689      * invoked either executes `func` returning its result, if all `func` arguments
13690      * have been provided, or returns a function that accepts one or more of the
13691      * remaining `func` arguments, and so on. The arity of `func` can be specified
13692      * if `func.length` is not sufficient.
13693      *
13694      * Note: This method does not set the `length` property of curried functions.
13695      *
13696      * @static
13697      * @memberOf _
13698      * @category Functions
13699      * @param {Function} func The function to curry.
13700      * @param {number} [arity=func.length] The arity of `func`.
13701      * @returns {Function} Returns the new curried function.
13702      * @example
13703      *
13704      * var curried = _.curry(function(a, b, c) {
13705      *   console.log(a + b + c);
13706      * });
13707      *
13708      * curried(1)(2)(3);
13709      * // => 6
13710      *
13711      * curried(1, 2)(3);
13712      * // => 6
13713      *
13714      * curried(1, 2, 3);
13715      * // => 6
13716      */
13717     function curry(func, arity) {
13718       if (typeof arity != 'number') {
13719         arity = +arity || (func ? func.length : 0);
13720       }
13721       return createWrapper(func, CURRY_FLAG, arity);
13722     }
13723
13724     /**
13725      * Creates a function that will delay the execution of `func` until after
13726      * `wait` milliseconds have elapsed since the last time it was invoked.
13727      * Provide an options object to indicate that `func` should be invoked on
13728      * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
13729      * to the debounced function will return the result of the last `func` call.
13730      *
13731      * Note: If `leading` and `trailing` options are `true` `func` will be called
13732      * on the trailing edge of the timeout only if the the debounced function is
13733      * invoked more than once during the `wait` timeout.
13734      *
13735      * @static
13736      * @memberOf _
13737      * @category Functions
13738      * @param {Function} func The function to debounce.
13739      * @param {number} wait The number of milliseconds to delay.
13740      * @param {Object} [options] The options object.
13741      * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
13742      * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
13743      * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
13744      * @returns {Function} Returns the new debounced function.
13745      * @example
13746      *
13747      * // avoid costly calculations while the window size is in flux
13748      * var lazyLayout = _.debounce(calculateLayout, 150);
13749      * jQuery(window).on('resize', lazyLayout);
13750      *
13751      * // execute `sendMail` when the click event is fired, debouncing subsequent calls
13752      * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
13753      *   'leading': true,
13754      *   'trailing': false
13755      * });
13756      *
13757      * // ensure `batchLog` is executed once after 1 second of debounced calls
13758      * var source = new EventSource('/stream');
13759      * source.addEventListener('message', _.debounce(batchLog, 250, {
13760      *   'maxWait': 1000
13761      * }, false);
13762      */
13763     function debounce(func, wait, options) {
13764       var args,
13765           maxTimeoutId,
13766           result,
13767           stamp,
13768           thisArg,
13769           timeoutId,
13770           trailingCall,
13771           lastCalled = 0,
13772           maxWait = false,
13773           trailing = true;
13774
13775       if (!isFunction(func)) {
13776         throw new TypeError;
13777       }
13778       wait = nativeMax(0, wait) || 0;
13779       if (options === true) {
13780         var leading = true;
13781         trailing = false;
13782       } else if (isObject(options)) {
13783         leading = options.leading;
13784         maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
13785         trailing = 'trailing' in options ? options.trailing : trailing;
13786       }
13787       var delayed = function() {
13788         var remaining = wait - (now() - stamp);
13789         if (remaining <= 0 || remaining > wait) {
13790           if (maxTimeoutId) {
13791             clearTimeout(maxTimeoutId);
13792           }
13793           var isCalled = trailingCall;
13794           maxTimeoutId = timeoutId = trailingCall = undefined;
13795           if (isCalled) {
13796             lastCalled = now();
13797             result = func.apply(thisArg, args);
13798             if (!timeoutId && !maxTimeoutId) {
13799               args = thisArg = null;
13800             }
13801           }
13802         } else {
13803           timeoutId = setTimeout(delayed, remaining);
13804         }
13805       };
13806
13807       var maxDelayed = function() {
13808         if (timeoutId) {
13809           clearTimeout(timeoutId);
13810         }
13811         maxTimeoutId = timeoutId = trailingCall = undefined;
13812         if (trailing || (maxWait !== wait)) {
13813           lastCalled = now();
13814           result = func.apply(thisArg, args);
13815           if (!timeoutId && !maxTimeoutId) {
13816             args = thisArg = null;
13817           }
13818         }
13819       };
13820
13821       return function() {
13822         args = arguments;
13823         stamp = now();
13824         thisArg = this;
13825         trailingCall = trailing && (timeoutId || !leading);
13826
13827         if (maxWait === false) {
13828           var leadingCall = leading && !timeoutId;
13829         } else {
13830           if (!maxTimeoutId && !leading) {
13831             lastCalled = stamp;
13832           }
13833           var remaining = maxWait - (stamp - lastCalled),
13834               isCalled = remaining <= 0 || remaining > maxWait;
13835
13836           if (isCalled) {
13837             if (maxTimeoutId) {
13838               maxTimeoutId = clearTimeout(maxTimeoutId);
13839             }
13840             lastCalled = stamp;
13841             result = func.apply(thisArg, args);
13842           }
13843           else if (!maxTimeoutId) {
13844             maxTimeoutId = setTimeout(maxDelayed, remaining);
13845           }
13846         }
13847         if (isCalled && timeoutId) {
13848           timeoutId = clearTimeout(timeoutId);
13849         }
13850         else if (!timeoutId && wait !== maxWait) {
13851           timeoutId = setTimeout(delayed, wait);
13852         }
13853         if (leadingCall) {
13854           isCalled = true;
13855           result = func.apply(thisArg, args);
13856         }
13857         if (isCalled && !timeoutId && !maxTimeoutId) {
13858           args = thisArg = null;
13859         }
13860         return result;
13861       };
13862     }
13863
13864     /**
13865      * Defers executing the `func` function until the current call stack has cleared.
13866      * Additional arguments will be provided to `func` when it is invoked.
13867      *
13868      * @static
13869      * @memberOf _
13870      * @category Functions
13871      * @param {Function} func The function to defer.
13872      * @param {...*} [args] Arguments to invoke the function with.
13873      * @returns {number} Returns the timer id.
13874      * @example
13875      *
13876      * _.defer(function(text) { console.log(text); }, 'deferred');
13877      * // logs 'deferred' after one or more milliseconds
13878      */
13879     function defer(func) {
13880       if (!isFunction(func)) {
13881         throw new TypeError;
13882       }
13883       var args = slice(arguments, 1);
13884       return setTimeout(function() { func.apply(undefined, args); }, 1);
13885     }
13886
13887     /**
13888      * Executes the `func` function after `wait` milliseconds. Additional arguments
13889      * will be provided to `func` when it is invoked.
13890      *
13891      * @static
13892      * @memberOf _
13893      * @category Functions
13894      * @param {Function} func The function to delay.
13895      * @param {number} wait The number of milliseconds to delay execution.
13896      * @param {...*} [args] Arguments to invoke the function with.
13897      * @returns {number} Returns the timer id.
13898      * @example
13899      *
13900      * _.delay(function(text) { console.log(text); }, 1000, 'later');
13901      * // => logs 'later' after one second
13902      */
13903     function delay(func, wait) {
13904       if (!isFunction(func)) {
13905         throw new TypeError;
13906       }
13907       var args = slice(arguments, 2);
13908       return setTimeout(function() { func.apply(undefined, args); }, wait);
13909     }
13910
13911     /**
13912      * Creates a function that memoizes the result of `func`. If `resolver` is
13913      * provided it will be used to determine the cache key for storing the result
13914      * based on the arguments provided to the memoized function. By default, the
13915      * first argument provided to the memoized function is used as the cache key.
13916      * The `func` is executed with the `this` binding of the memoized function.
13917      * The result cache is exposed as the `cache` property on the memoized function.
13918      *
13919      * @static
13920      * @memberOf _
13921      * @category Functions
13922      * @param {Function} func The function to have its output memoized.
13923      * @param {Function} [resolver] A function used to resolve the cache key.
13924      * @returns {Function} Returns the new memoizing function.
13925      * @example
13926      *
13927      * var fibonacci = _.memoize(function(n) {
13928      *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
13929      * });
13930      *
13931      * fibonacci(9)
13932      * // => 34
13933      *
13934      * var data = {
13935      *   'fred': { 'name': 'fred', 'age': 40 },
13936      *   'pebbles': { 'name': 'pebbles', 'age': 1 }
13937      * };
13938      *
13939      * // modifying the result cache
13940      * var get = _.memoize(function(name) { return data[name]; }, _.identity);
13941      * get('pebbles');
13942      * // => { 'name': 'pebbles', 'age': 1 }
13943      *
13944      * get.cache.pebbles.name = 'penelope';
13945      * get('pebbles');
13946      * // => { 'name': 'penelope', 'age': 1 }
13947      */
13948     function memoize(func, resolver) {
13949       if (!isFunction(func)) {
13950         throw new TypeError;
13951       }
13952       var memoized = function() {
13953         var cache = memoized.cache,
13954             key = resolver ? resolver.apply(this, arguments) : '_' + arguments[0];
13955
13956         return hasOwnProperty.call(cache, key)
13957           ? cache[key]
13958           : (cache[key] = func.apply(this, arguments));
13959       }
13960       memoized.cache = {};
13961       return memoized;
13962     }
13963
13964     /**
13965      * Creates a function that is restricted to execute `func` once. Repeat calls to
13966      * the function will return the value of the first call. The `func` is executed
13967      * with the `this` binding of the created function.
13968      *
13969      * @static
13970      * @memberOf _
13971      * @category Functions
13972      * @param {Function} func The function to restrict.
13973      * @returns {Function} Returns the new restricted function.
13974      * @example
13975      *
13976      * var initialize = _.once(createApplication);
13977      * initialize();
13978      * initialize();
13979      * // `initialize` executes `createApplication` once
13980      */
13981     function once(func) {
13982       var ran,
13983           result;
13984
13985       if (!isFunction(func)) {
13986         throw new TypeError;
13987       }
13988       return function() {
13989         if (ran) {
13990           return result;
13991         }
13992         ran = true;
13993         result = func.apply(this, arguments);
13994
13995         // clear the `func` variable so the function may be garbage collected
13996         func = null;
13997         return result;
13998       };
13999     }
14000
14001     /**
14002      * Creates a function that, when called, invokes `func` with any additional
14003      * `partial` arguments prepended to those provided to the new function. This
14004      * method is similar to `_.bind` except it does **not** alter the `this` binding.
14005      *
14006      * Note: This method does not set the `length` property of partially applied
14007      * functions.
14008      *
14009      * @static
14010      * @memberOf _
14011      * @category Functions
14012      * @param {Function} func The function to partially apply arguments to.
14013      * @param {...*} [args] Arguments to be partially applied.
14014      * @returns {Function} Returns the new partially applied function.
14015      * @example
14016      *
14017      * var greet = function(greeting, name) { return greeting + ' ' + name; };
14018      * var hi = _.partial(greet, 'hi');
14019      * hi('fred');
14020      * // => 'hi fred'
14021      */
14022     function partial(func) {
14023       if (func) {
14024         var arity = func[expando] ? func[expando][2] : func.length,
14025             partialArgs = slice(arguments, 1);
14026
14027         arity -= partialArgs.length;
14028       }
14029       return createWrapper(func, PARTIAL_FLAG, arity, null, partialArgs);
14030     }
14031
14032     /**
14033      * This method is like `_.partial` except that `partial` arguments are
14034      * appended to those provided to the new function.
14035      *
14036      * Note: This method does not set the `length` property of partially applied
14037      * functions.
14038      *
14039      * @static
14040      * @memberOf _
14041      * @category Functions
14042      * @param {Function} func The function to partially apply arguments to.
14043      * @param {...*} [args] Arguments to be partially applied.
14044      * @returns {Function} Returns the new partially applied function.
14045      * @example
14046      *
14047      * var defaultsDeep = _.partialRight(_.merge, _.defaults);
14048      *
14049      * var options = {
14050      *   'variable': 'data',
14051      *   'imports': { 'jq': $ }
14052      * };
14053      *
14054      * defaultsDeep(options, _.templateSettings);
14055      *
14056      * options.variable
14057      * // => 'data'
14058      *
14059      * options.imports
14060      * // => { '_': _, 'jq': $ }
14061      */
14062     function partialRight(func) {
14063       if (func) {
14064         var arity = func[expando] ? func[expando][2] : func.length,
14065             partialRightArgs = slice(arguments, 1);
14066
14067         arity -= partialRightArgs.length;
14068       }
14069       return createWrapper(func, PARTIAL_RIGHT_FLAG, arity, null, null, partialRightArgs);
14070     }
14071
14072     /**
14073      * Creates a function that, when executed, will only call the `func` function
14074      * at most once per every `wait` milliseconds. Provide an options object to
14075      * indicate that `func` should be invoked on the leading and/or trailing edge
14076      * of the `wait` timeout. Subsequent calls to the throttled function will
14077      * return the result of the last `func` call.
14078      *
14079      * Note: If `leading` and `trailing` options are `true` `func` will be called
14080      * on the trailing edge of the timeout only if the the throttled function is
14081      * invoked more than once during the `wait` timeout.
14082      *
14083      * @static
14084      * @memberOf _
14085      * @category Functions
14086      * @param {Function} func The function to throttle.
14087      * @param {number} wait The number of milliseconds to throttle executions to.
14088      * @param {Object} [options] The options object.
14089      * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
14090      * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
14091      * @returns {Function} Returns the new throttled function.
14092      * @example
14093      *
14094      * // avoid excessively updating the position while scrolling
14095      * var throttled = _.throttle(updatePosition, 100);
14096      * jQuery(window).on('scroll', throttled);
14097      *
14098      * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
14099      * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
14100      *   'trailing': false
14101      * }));
14102      */
14103     function throttle(func, wait, options) {
14104       var leading = true,
14105           trailing = true;
14106
14107       if (!isFunction(func)) {
14108         throw new TypeError;
14109       }
14110       if (options === false) {
14111         leading = false;
14112       } else if (isObject(options)) {
14113         leading = 'leading' in options ? options.leading : leading;
14114         trailing = 'trailing' in options ? options.trailing : trailing;
14115       }
14116       debounceOptions.leading = leading;
14117       debounceOptions.maxWait = wait;
14118       debounceOptions.trailing = trailing;
14119
14120       return debounce(func, wait, debounceOptions);
14121     }
14122
14123     /**
14124      * Creates a function that provides `value` to the wrapper function as its
14125      * first argument. Additional arguments provided to the function are appended
14126      * to those provided to the wrapper function. The wrapper is executed with
14127      * the `this` binding of the created function.
14128      *
14129      * @static
14130      * @memberOf _
14131      * @category Functions
14132      * @param {*} value The value to wrap.
14133      * @param {Function} wrapper The wrapper function.
14134      * @returns {Function} Returns the new function.
14135      * @example
14136      *
14137      * var p = _.wrap(_.escape, function(func, text) {
14138      *   return '<p>' + func(text) + '</p>';
14139      * });
14140      *
14141      * p('fred, barney, & pebbles');
14142      * // => '<p>fred, barney, &amp; pebbles</p>'
14143      */
14144     function wrap(value, wrapper) {
14145       return createWrapper(wrapper, PARTIAL_FLAG, null, null, [value]);
14146     }
14147
14148     /*--------------------------------------------------------------------------*/
14149
14150
14151     /**
14152      * Assigns own enumerable properties of source object(s) to the destination
14153      * object. Subsequent sources will overwrite property assignments of previous
14154      * sources. If a callback is provided it will be executed to produce the
14155      * assigned values. The callback is bound to `thisArg` and invoked with two
14156      * arguments; (objectValue, sourceValue).
14157      *
14158      * @static
14159      * @memberOf _
14160      * @alias extend
14161      * @category Objects
14162      * @param {Object} object The destination object.
14163      * @param {...Object} [source] The source objects.
14164      * @param {Function} [callback] The function to customize assigning values.
14165      * @param {*} [thisArg] The `this` binding of `callback`.
14166      * @returns {Object} Returns the destination object.
14167      * @example
14168      *
14169      * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
14170      * // => { 'name': 'fred', 'employer': 'slate' }
14171      *
14172      * var defaults = _.partialRight(_.assign, function(a, b) {
14173      *   return typeof a == 'undefined' ? b : a;
14174      * });
14175      *
14176      * defaults({ 'name': 'barney' }, { 'name': 'fred', 'employer': 'slate' });
14177      * // => { 'name': 'barney', 'employer': 'slate' }
14178      */
14179     function assign(object, source, guard) {
14180       var args = arguments,
14181           argsIndex = 0,
14182           argsLength = args.length,
14183           type = typeof guard;
14184
14185       // enables use as a callback for functions like `_.reduce`
14186       if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
14187         argsLength = 2;
14188       }
14189       // juggle arguments
14190       if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
14191         var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
14192       } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
14193         callback = args[--argsLength];
14194       }
14195       while (++argsIndex < argsLength) {
14196         source = args[argsIndex];
14197         if (isObject(source)) {
14198           var index = -1,
14199               props = keys(source),
14200               length = props.length;
14201
14202           while (++index < length) {
14203             var key = props[index];
14204             object[key] = callback ? callback(object[key], source[key]) : source[key];
14205           }
14206         }
14207       }
14208       return object;
14209     }
14210
14211     /**
14212      * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
14213      * be cloned, otherwise they will be assigned by reference. If a callback
14214      * is provided it will be executed to produce the cloned values. If the
14215      * callback returns `undefined` cloning will be handled by the method instead.
14216      * The callback is bound to `thisArg` and invoked with one argument; (value).
14217      *
14218      * Note: This method is loosely based on the structured clone algorithm. Functions
14219      * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
14220      * objects created by constructors other than `Object` are cloned to plain `Object` objects.
14221      * See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
14222      * for more details.
14223      *
14224      * @static
14225      * @memberOf _
14226      * @category Objects
14227      * @param {*} value The value to clone.
14228      * @param {boolean} [isDeep=false] Specify a deep clone.
14229      * @param {Function} [callback] The function to customize cloning values.
14230      * @param {*} [thisArg] The `this` binding of `callback`.
14231      * @returns {*} Returns the cloned value.
14232      * @example
14233      *
14234      * var characters = [
14235      *   { 'name': 'barney', 'age': 36 },
14236      *   { 'name': 'fred',   'age': 40 }
14237      * ];
14238      *
14239      * var shallow = _.clone(characters);
14240      * shallow[0] === characters[0];
14241      * // => true
14242      *
14243      * var deep = _.clone(characters, true);
14244      * deep[0] === characters[0];
14245      * // => false
14246      *
14247      * _.mixin({
14248      *   'clone': _.partialRight(_.clone, function(value) {
14249      *     return _.isElement(value) ? value.cloneNode(false) : undefined;
14250      *   })
14251      * });
14252      *
14253      * var clone = _.clone(document.body);
14254      * clone.childNodes.length;
14255      * // => 0
14256      */
14257     function clone(value, isDeep, callback, thisArg) {
14258       var type = typeof isDeep;
14259
14260       // juggle arguments
14261       if (type != 'boolean' && isDeep != null) {
14262         thisArg = callback;
14263         callback = isDeep;
14264         isDeep = false;
14265
14266         // enables use as a callback for functions like `_.map`
14267         if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === value) {
14268           callback = null;
14269         }
14270       }
14271       return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
14272     }
14273
14274     /**
14275      * Creates a deep clone of `value`. If a callback is provided it will be
14276      * executed to produce the cloned values. If the callback returns `undefined`
14277      * cloning will be handled by the method instead. The callback is bound to
14278      * `thisArg` and invoked with one argument; (value).
14279      *
14280      * Note: This method is loosely based on the structured clone algorithm. Functions
14281      * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
14282      * objects created by constructors other than `Object` are cloned to plain `Object` objects.
14283      * See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
14284      * for more details.
14285      *
14286      * @static
14287      * @memberOf _
14288      * @category Objects
14289      * @param {*} value The value to deep clone.
14290      * @param {Function} [callback] The function to customize cloning values.
14291      * @param {*} [thisArg] The `this` binding of `callback`.
14292      * @returns {*} Returns the deep cloned value.
14293      * @example
14294      *
14295      * var characters = [
14296      *   { 'name': 'barney', 'age': 36 },
14297      *   { 'name': 'fred',   'age': 40 }
14298      * ];
14299      *
14300      * var deep = _.cloneDeep(characters);
14301      * deep[0] === characters[0];
14302      * // => false
14303      *
14304      * var view = {
14305      *   'label': 'docs',
14306      *   'node': element
14307      * };
14308      *
14309      * var clone = _.cloneDeep(view, function(value) {
14310      *   return _.isElement(value) ? value.cloneNode(true) : undefined;
14311      * });
14312      *
14313      * clone.node == view.node;
14314      * // => false
14315      */
14316     function cloneDeep(value, callback, thisArg) {
14317       return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
14318     }
14319
14320     /**
14321      * Creates an object that inherits from the given `prototype` object. If a
14322      * `properties` object is provided its own enumerable properties are assigned
14323      * to the created object.
14324      *
14325      * @static
14326      * @memberOf _
14327      * @category Objects
14328      * @param {Object} prototype The object to inherit from.
14329      * @param {Object} [properties] The properties to assign to the object.
14330      * @returns {Object} Returns the new object.
14331      * @example
14332      *
14333      * function Shape() {
14334      *   this.x = 0;
14335      *   this.y = 0;
14336      * }
14337      *
14338      * function Circle() {
14339      *   Shape.call(this);
14340      * }
14341      *
14342      * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
14343      *
14344      * var circle = new Circle;
14345      * circle instanceof Circle;
14346      * // => true
14347      *
14348      * circle instanceof Shape;
14349      * // => true
14350      */
14351     function create(prototype, properties) {
14352       var result = baseCreate(prototype);
14353       return properties ? assign(result, properties) : result;
14354     }
14355
14356     /**
14357      * Assigns own enumerable properties of source object(s) to the destination
14358      * object for all destination properties that resolve to `undefined`. Once a
14359      * property is set, additional defaults of the same property will be ignored.
14360      *
14361      * @static
14362      * @memberOf _
14363      * @category Objects
14364      * @param {Object} object The destination object.
14365      * @param {...Object} [source] The source objects.
14366      * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
14367      * @returns {Object} Returns the destination object.
14368      * @example
14369      *
14370      * _.defaults({ 'name': 'barney' }, { 'name': 'fred', 'employer': 'slate' });
14371      * // => { 'name': 'barney', 'employer': 'slate' }
14372      */
14373     function defaults(object, source, guard) {
14374       var args = arguments,
14375           argsIndex = 0,
14376           argsLength = args.length,
14377           type = typeof guard;
14378
14379       // enables use as a callback for functions like `_.reduce`
14380       if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
14381         argsLength = 2;
14382       }
14383       while (++argsIndex < argsLength) {
14384         source = args[argsIndex];
14385         if (isObject(source)) {
14386           var index = -1,
14387               props = keys(source),
14388               length = props.length;
14389
14390           while (++index < length) {
14391             var key = props[index];
14392             if (typeof object[key] == 'undefined') {
14393               object[key] = source[key];
14394             }
14395           }
14396         }
14397       }
14398       return object;
14399     }
14400
14401     /**
14402      * This method is like `_.findIndex` except that it returns the key of the
14403      * first element that passes the callback check, instead of the element itself.
14404      *
14405      * If a property name is provided for `callback` the created "_.pluck" style
14406      * callback will return the property value of the given element.
14407      *
14408      * If an object is provided for `callback` the created "_.where" style callback
14409      * will return `true` for elements that have the properties of the given object,
14410      * else `false`.
14411      *
14412      * @static
14413      * @memberOf _
14414      * @category Objects
14415      * @param {Object} object The object to search.
14416      * @param {Function|Object|string} [callback=identity] The function called per
14417      *  iteration. If a property name or object is provided it will be used to
14418      *  create a "_.pluck" or "_.where" style callback, respectively.
14419      * @param {*} [thisArg] The `this` binding of `callback`.
14420      * @returns {string|undefined} Returns the key of the found element, else `undefined`.
14421      * @example
14422      *
14423      * var characters = {
14424      *   'barney': { 'age': 36 },
14425      *   'fred': { 'age': 40, 'blocked': true },
14426      *   'pebbles': { 'age': 1 }
14427      * };
14428      *
14429      * _.findKey(characters, function(chr) {
14430      *   return chr.age < 40;
14431      * });
14432      * // => 'barney' (property order is not guaranteed across environments)
14433      *
14434      * // using "_.where" callback shorthand
14435      * _.findKey(characters, { 'age': 1 });
14436      * // => 'pebbles'
14437      *
14438      * // using "_.pluck" callback shorthand
14439      * _.findKey(characters, 'blocked');
14440      * // => 'fred'
14441      */
14442     function findKey(object, callback, thisArg) {
14443       var result;
14444
14445       callback = lodash.createCallback(callback, thisArg, 3);
14446       baseForOwn(object, function(value, key, object) {
14447         if (callback(value, key, object)) {
14448           result = key;
14449           return false;
14450         }
14451       });
14452       return result;
14453     }
14454
14455     /**
14456      * This method is like `_.findKey` except that it iterates over elements
14457      * of a `collection` in the opposite order.
14458      *
14459      * If a property name is provided for `callback` the created "_.pluck" style
14460      * callback will return the property value of the given element.
14461      *
14462      * If an object is provided for `callback` the created "_.where" style callback
14463      * will return `true` for elements that have the properties of the given object,
14464      * else `false`.
14465      *
14466      * @static
14467      * @memberOf _
14468      * @category Objects
14469      * @param {Object} object The object to search.
14470      * @param {Function|Object|string} [callback=identity] The function called per
14471      *  iteration. If a property name or object is provided it will be used to
14472      *  create a "_.pluck" or "_.where" style callback, respectively.
14473      * @param {*} [thisArg] The `this` binding of `callback`.
14474      * @returns {string|undefined} Returns the key of the found element, else `undefined`.
14475      * @example
14476      *
14477      * var characters = {
14478      *   'barney': { 'age': 36, 'blocked': true },
14479      *   'fred': { 'age': 40 },
14480      *   'pebbles': { 'age': 1, 'blocked': true }
14481      * };
14482      *
14483      * _.findLastKey(characters, function(chr) {
14484      *   return chr.age < 40;
14485      * });
14486      * // => returns `pebbles`, assuming `_.findKey` returns `barney`
14487      *
14488      * // using "_.where" callback shorthand
14489      * _.findLastKey(characters, { 'age': 40 });
14490      * // => 'fred'
14491      *
14492      * // using "_.pluck" callback shorthand
14493      * _.findLastKey(characters, 'blocked');
14494      * // => 'pebbles'
14495      */
14496     function findLastKey(object, callback, thisArg) {
14497       var result;
14498
14499       callback = lodash.createCallback(callback, thisArg, 3);
14500       baseForOwnRight(object, function(value, key, object) {
14501         if (callback(value, key, object)) {
14502           result = key;
14503           return false;
14504         }
14505       });
14506       return result;
14507     }
14508
14509     /**
14510      * Iterates over own and inherited enumerable properties of an object,
14511      * executing the callback for each property. The callback is bound to `thisArg`
14512      * and invoked with three arguments; (value, key, object). Callbacks may exit
14513      * iteration early by explicitly returning `false`.
14514      *
14515      * @static
14516      * @memberOf _
14517      * @type Function
14518      * @category Objects
14519      * @param {Object} object The object to iterate over.
14520      * @param {Function} [callback=identity] The function called per iteration.
14521      * @param {*} [thisArg] The `this` binding of `callback`.
14522      * @returns {Object} Returns `object`.
14523      * @example
14524      *
14525      * function Shape() {
14526      *   this.x = 0;
14527      *   this.y = 0;
14528      * }
14529      *
14530      * Shape.prototype.move = function(x, y) {
14531      *   this.x += x;
14532      *   this.y += y;
14533      * };
14534      *
14535      * _.forIn(new Shape, function(value, key) {
14536      *   console.log(key);
14537      * });
14538      * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
14539      */
14540     function forIn(object, callback, thisArg) {
14541       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
14542       return baseForIn(object, callback);
14543     }
14544
14545     /**
14546      * This method is like `_.forIn` except that it iterates over elements
14547      * of a `collection` in the opposite order.
14548      *
14549      * @static
14550      * @memberOf _
14551      * @category Objects
14552      * @param {Object} object The object to iterate over.
14553      * @param {Function} [callback=identity] The function called per iteration.
14554      * @param {*} [thisArg] The `this` binding of `callback`.
14555      * @returns {Object} Returns `object`.
14556      * @example
14557      *
14558      * function Shape() {
14559      *   this.x = 0;
14560      *   this.y = 0;
14561      * }
14562      *
14563      * Shape.prototype.move = function(x, y) {
14564      *   this.x += x;
14565      *   this.y += y;
14566      * };
14567      *
14568      * _.forInRight(new Shape, function(value, key) {
14569      *   console.log(key);
14570      * });
14571      * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
14572      */
14573     function forInRight(object, callback, thisArg) {
14574       var pairs = [];
14575       baseForIn(object, function(value, key) {
14576         pairs.push(key, value);
14577       });
14578
14579       var length = pairs.length;
14580       callback = baseCreateCallback(callback, thisArg, 3);
14581       while (length--) {
14582         if (callback(pairs[length--], pairs[length], object) === false) {
14583           break;
14584         }
14585       }
14586       return object;
14587     }
14588
14589     /**
14590      * Iterates over own enumerable properties of an object, executing the callback
14591      * for each property. The callback is bound to `thisArg` and invoked with three
14592      * arguments; (value, key, object). Callbacks may exit iteration early by
14593      * explicitly returning `false`.
14594      *
14595      * @static
14596      * @memberOf _
14597      * @category Objects
14598      * @param {Object} object The object to iterate over.
14599      * @param {Function} [callback=identity] The function called per iteration.
14600      * @param {*} [thisArg] The `this` binding of `callback`.
14601      * @returns {Object} Returns `object`.
14602      * @example
14603      *
14604      * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
14605      *   console.log(key);
14606      * });
14607      * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
14608      */
14609     function forOwn(object, callback, thisArg) {
14610       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
14611       return baseForOwn(object, callback);
14612     }
14613
14614     /**
14615      * This method is like `_.forOwn` except that it iterates over elements
14616      * of a `collection` in the opposite order.
14617      *
14618      * @static
14619      * @memberOf _
14620      * @category Objects
14621      * @param {Object} object The object to iterate over.
14622      * @param {Function} [callback=identity] The function called per iteration.
14623      * @param {*} [thisArg] The `this` binding of `callback`.
14624      * @returns {Object} Returns `object`.
14625      * @example
14626      *
14627      * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
14628      *   console.log(key);
14629      * });
14630      * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
14631      */
14632     function forOwnRight(object, callback, thisArg) {
14633       var props = keys(object),
14634           length = props.length;
14635
14636       callback = baseCreateCallback(callback, thisArg, 3);
14637       while (length--) {
14638         var key = props[length];
14639         if (callback(object[key], key, object) === false) {
14640           break;
14641         }
14642       }
14643       return object;
14644     }
14645
14646     /**
14647      * Creates a sorted array of property names of all enumerable properties,
14648      * own and inherited, of `object` that have function values.
14649      *
14650      * @static
14651      * @memberOf _
14652      * @alias methods
14653      * @category Objects
14654      * @param {Object} object The object to inspect.
14655      * @returns {Array} Returns an array of property names that have function values.
14656      * @example
14657      *
14658      * _.functions(_);
14659      * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
14660      */
14661     function functions(object) {
14662       var result = [];
14663       baseForIn(object, function(value, key) {
14664         if (isFunction(value)) {
14665           result.push(key);
14666         }
14667       });
14668       return result.sort();
14669     }
14670
14671     /**
14672      * Checks if the specified property name exists as a direct property of `object`,
14673      * instead of an inherited property.
14674      *
14675      * @static
14676      * @memberOf _
14677      * @category Objects
14678      * @param {Object} object The object to inspect.
14679      * @param {string} key The name of the property to check.
14680      * @returns {boolean} Returns `true` if key is a direct property, else `false`.
14681      * @example
14682      *
14683      * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
14684      * // => true
14685      */
14686     function has(object, key) {
14687       return object ? hasOwnProperty.call(object, key) : false;
14688     }
14689
14690     /**
14691      * Creates an object composed of the inverted keys and values of the given
14692      * object. If the given object contains duplicate values, subsequent values
14693      * will overwrite property assignments of previous values unless `multiValue`
14694      * is `true`.
14695      *
14696      * @static
14697      * @memberOf _
14698      * @category Objects
14699      * @param {Object} object The object to invert.
14700      * @param {boolean} [multiValue=false] Allow multiple values per key.
14701      * @returns {Object} Returns the created inverted object.
14702      * @example
14703      *
14704      * _.invert({ 'first': 'fred', 'second': 'barney' });
14705      * // => { 'fred': 'first', 'barney': 'second' }
14706      *
14707      * // without `multiValue`
14708      * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' });
14709      * // => { 'fred': 'third', 'barney': 'second' }
14710      *
14711      * // with `multiValue`
14712      * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }, true);
14713      * // => { 'fred': ['first', 'third'], 'barney': ['second'] }
14714      */
14715     function invert(object, multiValue) {
14716       var index = -1,
14717           props = keys(object),
14718           length = props.length,
14719           result = {};
14720
14721       while (++index < length) {
14722         var key = props[index],
14723             value = object[key];
14724
14725         if (multiValue) {
14726           if (hasOwnProperty.call(result, value)) {
14727             result[value].push(key);
14728           } else {
14729             result[value] = [key];
14730           }
14731         }
14732         else {
14733           result[value] = key;
14734         }
14735       }
14736       return result;
14737     }
14738
14739     /**
14740      * Checks if `value` is an array.
14741      *
14742      * @static
14743      * @memberOf _
14744      * @type Function
14745      * @category Objects
14746      * @param {*} value The value to check.
14747      * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
14748      * @example
14749      *
14750      * (function() { return _.isArray(arguments); })();
14751      * // => false
14752      *
14753      * _.isArray([1, 2, 3]);
14754      * // => true
14755      */
14756     var isArray = nativeIsArray || function(value) {
14757       return value && typeof value == 'object' && typeof value.length == 'number' &&
14758         toString.call(value) == arrayClass || false;
14759     };
14760
14761     /**
14762      * Checks if `value` is a boolean value.
14763      *
14764      * @static
14765      * @memberOf _
14766      * @category Objects
14767      * @param {*} value The value to check.
14768      * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
14769      * @example
14770      *
14771      * _.isBoolean(null);
14772      * // => false
14773      */
14774     function isBoolean(value) {
14775       return value === true || value === false ||
14776         value && typeof value == 'object' && toString.call(value) == boolClass || false;
14777     }
14778
14779     /**
14780      * Checks if `value` is a date.
14781      *
14782      * @static
14783      * @memberOf _
14784      * @category Objects
14785      * @param {*} value The value to check.
14786      * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
14787      * @example
14788      *
14789      * _.isDate(new Date);
14790      * // => true
14791      */
14792     function isDate(value) {
14793       return value && typeof value == 'object' && toString.call(value) == dateClass || false;
14794     }
14795
14796     /**
14797      * Checks if `value` is a DOM element.
14798      *
14799      * @static
14800      * @memberOf _
14801      * @category Objects
14802      * @param {*} value The value to check.
14803      * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
14804      * @example
14805      *
14806      * _.isElement(document.body);
14807      * // => true
14808      */
14809     function isElement(value) {
14810       return value && typeof value == 'object' && value.nodeType === 1 &&
14811         (support.nodeClass ? toString.call(value).indexOf('Element') > -1 : isNode(value)) || false;
14812     }
14813     // fallback for environments without DOM support
14814     if (!support.dom) {
14815       isElement = function(value) {
14816         return value && typeof value == 'object' && value.nodeType === 1 &&
14817           !isPlainObject(value) || false;
14818       };
14819     }
14820
14821     /**
14822      * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
14823      * length of `0` and objects with no own enumerable properties are considered
14824      * "empty".
14825      *
14826      * @static
14827      * @memberOf _
14828      * @category Objects
14829      * @param {Array|Object|string} value The value to inspect.
14830      * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
14831      * @example
14832      *
14833      * _.isEmpty([1, 2, 3]);
14834      * // => false
14835      *
14836      * _.isEmpty({});
14837      * // => true
14838      *
14839      * _.isEmpty('');
14840      * // => true
14841      */
14842     function isEmpty(value) {
14843       var result = true;
14844       if (!value) {
14845         return result;
14846       }
14847       var className = toString.call(value),
14848           length = value.length;
14849
14850       if ((className == arrayClass || className == stringClass ||
14851           (support.argsClass ? className == argsClass : isArguments(value))) ||
14852           (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
14853         return !length;
14854       }
14855       baseForOwn(value, function() {
14856         return (result = false);
14857       });
14858       return result;
14859     }
14860
14861     /**
14862      * Performs a deep comparison between two values to determine if they are
14863      * equivalent to each other. If a callback is provided it will be executed
14864      * to compare values. If the callback returns `undefined` comparisons will
14865      * be handled by the method instead. The callback is bound to `thisArg` and
14866      * invoked with two arguments; (a, b).
14867      *
14868      * @static
14869      * @memberOf _
14870      * @category Objects
14871      * @param {*} a The value to compare.
14872      * @param {*} b The other value to compare.
14873      * @param {Function} [callback] The function to customize comparing values.
14874      * @param {*} [thisArg] The `this` binding of `callback`.
14875      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
14876      * @example
14877      *
14878      * var object = { 'name': 'fred' };
14879      * var copy = { 'name': 'fred' };
14880      *
14881      * object == copy;
14882      * // => false
14883      *
14884      * _.isEqual(object, copy);
14885      * // => true
14886      *
14887      * var words = ['hello', 'goodbye'];
14888      * var otherWords = ['hi', 'goodbye'];
14889      *
14890      * _.isEqual(words, otherWords, function(a, b) {
14891      *   var reGreet = /^(?:hello|hi)$/i,
14892      *       aGreet = _.isString(a) && reGreet.test(a),
14893      *       bGreet = _.isString(b) && reGreet.test(b);
14894      *
14895      *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
14896      * });
14897      * // => true
14898      */
14899     function isEqual(a, b, callback, thisArg) {
14900       return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
14901     }
14902
14903     /**
14904      * Checks if `value` is, or can be coerced to, a finite number.
14905      *
14906      * Note: This method is not the same as native `isFinite` which will return
14907      * `true` for booleans and empty strings. See the [ES5 spec](http://es5.github.io/#x15.1.2.5)
14908      * for more details.
14909      *
14910      * @static
14911      * @memberOf _
14912      * @category Objects
14913      * @param {*} value The value to check.
14914      * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
14915      * @example
14916      *
14917      * _.isFinite(-101);
14918      * // => true
14919      *
14920      * _.isFinite('10');
14921      * // => true
14922      *
14923      * _.isFinite(true);
14924      * // => false
14925      *
14926      * _.isFinite('');
14927      * // => false
14928      *
14929      * _.isFinite(Infinity);
14930      * // => false
14931      */
14932     function isFinite(value) {
14933       return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
14934     }
14935
14936     /**
14937      * Checks if `value` is a function.
14938      *
14939      * @static
14940      * @memberOf _
14941      * @category Objects
14942      * @param {*} value The value to check.
14943      * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
14944      * @example
14945      *
14946      * _.isFunction(_);
14947      * // => true
14948      */
14949     function isFunction(value) {
14950       return typeof value == 'function';
14951     }
14952     // fallback for older versions of Chrome and Safari
14953     if (isFunction(/x/)) {
14954       isFunction = function(value) {
14955         return typeof value == 'function' && toString.call(value) == funcClass;
14956       };
14957     }
14958
14959     /**
14960      * Checks if `value` is the language type of Object.
14961      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
14962      *
14963      * @static
14964      * @memberOf _
14965      * @category Objects
14966      * @param {*} value The value to check.
14967      * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
14968      * @example
14969      *
14970      * _.isObject({});
14971      * // => true
14972      *
14973      * _.isObject([1, 2, 3]);
14974      * // => true
14975      *
14976      * _.isObject(1);
14977      * // => false
14978      */
14979     function isObject(value) {
14980       // check if the value is the ECMAScript language type of Object
14981       // http://es5.github.io/#x8
14982       // and avoid a V8 bug
14983       // https://code.google.com/p/v8/issues/detail?id=2291
14984       var type = typeof value;
14985       return value && (type == 'function' || type == 'object') || false;
14986     }
14987
14988     /**
14989      * Checks if `value` is `NaN`.
14990      *
14991      * Note: This method is not the same as native `isNaN` which will return `true`
14992      * for `undefined` and other non-numeric values. See the [ES5 spec](http://es5.github.io/#x15.1.2.4)
14993      * for more details.
14994      *
14995      * @static
14996      * @memberOf _
14997      * @category Objects
14998      * @param {*} value The value to check.
14999      * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
15000      * @example
15001      *
15002      * _.isNaN(NaN);
15003      * // => true
15004      *
15005      * _.isNaN(new Number(NaN));
15006      * // => true
15007      *
15008      * isNaN(undefined);
15009      * // => true
15010      *
15011      * _.isNaN(undefined);
15012      * // => false
15013      */
15014     function isNaN(value) {
15015       // `NaN` as a primitive is the only value that is not equal to itself
15016       // (perform the [[Class]] check first to avoid errors with some host objects in IE)
15017       return isNumber(value) && value != +value;
15018     }
15019
15020     /**
15021      * Checks if `value` is `null`.
15022      *
15023      * @static
15024      * @memberOf _
15025      * @category Objects
15026      * @param {*} value The value to check.
15027      * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
15028      * @example
15029      *
15030      * _.isNull(null);
15031      * // => true
15032      *
15033      * _.isNull(undefined);
15034      * // => false
15035      */
15036     function isNull(value) {
15037       return value === null;
15038     }
15039
15040     /**
15041      * Checks if `value` is a number.
15042      *
15043      * Note: `NaN` is considered a number. See the [ES5 spec](http://es5.github.io/#x8.5)
15044      * for more details.
15045      *
15046      * @static
15047      * @memberOf _
15048      * @category Objects
15049      * @param {*} value The value to check.
15050      * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
15051      * @example
15052      *
15053      * _.isNumber(8.4 * 5);
15054      * // => true
15055      */
15056     function isNumber(value) {
15057       var type = typeof value;
15058       return type == 'number' ||
15059         value && type == 'object' && toString.call(value) == numberClass || false;
15060     }
15061
15062     /**
15063      * Checks if `value` is an object created by the `Object` constructor.
15064      *
15065      * @static
15066      * @memberOf _
15067      * @category Objects
15068      * @param {*} value The value to check.
15069      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
15070      * @example
15071      *
15072      * function Shape() {
15073      *   this.x = 0;
15074      *   this.y = 0;
15075      * }
15076      *
15077      * _.isPlainObject(new Shape);
15078      * // => false
15079      *
15080      * _.isPlainObject([1, 2, 3]);
15081      * // => false
15082      *
15083      * _.isPlainObject({ 'x': 0, 'y': 0 });
15084      * // => true
15085      */
15086     var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
15087       if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
15088         return false;
15089       }
15090       var valueOf = value.valueOf,
15091           objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
15092
15093       return objProto
15094         ? (value == objProto || getPrototypeOf(value) == objProto)
15095         : shimIsPlainObject(value);
15096     };
15097
15098     /**
15099      * Checks if `value` is a regular expression.
15100      *
15101      * @static
15102      * @memberOf _
15103      * @category Objects
15104      * @param {*} value The value to check.
15105      * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
15106      * @example
15107      *
15108      * _.isRegExp(/fred/);
15109      * // => true
15110      */
15111     function isRegExp(value) {
15112       var type = typeof value;
15113       return value && (type == 'function' || type == 'object') &&
15114         toString.call(value) == regexpClass || false;
15115     }
15116
15117     /**
15118      * Checks if `value` is a string.
15119      *
15120      * @static
15121      * @memberOf _
15122      * @category Objects
15123      * @param {*} value The value to check.
15124      * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
15125      * @example
15126      *
15127      * _.isString('fred');
15128      * // => true
15129      */
15130     function isString(value) {
15131       return typeof value == 'string' ||
15132         value && typeof value == 'object' && toString.call(value) == stringClass || false;
15133     }
15134
15135     /**
15136      * Checks if `value` is `undefined`.
15137      *
15138      * @static
15139      * @memberOf _
15140      * @category Objects
15141      * @param {*} value The value to check.
15142      * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
15143      * @example
15144      *
15145      * _.isUndefined(void 0);
15146      * // => true
15147      */
15148     function isUndefined(value) {
15149       return typeof value == 'undefined';
15150     }
15151
15152     /**
15153      * Creates an array composed of the own enumerable property names of an object.
15154      *
15155      * @static
15156      * @memberOf _
15157      * @category Objects
15158      * @param {Object} object The object to inspect.
15159      * @returns {Array} Returns an array of property names.
15160      * @example
15161      *
15162      * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
15163      * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
15164      */
15165     var keys = !nativeKeys ? shimKeys : function(object) {
15166       if (!isObject(object)) {
15167         return [];
15168       }
15169       if ((support.enumPrototypes && typeof object == 'function') ||
15170           (support.nonEnumArgs && object.length && isArguments(object))) {
15171         return shimKeys(object);
15172       }
15173       return nativeKeys(object);
15174     };
15175
15176     /**
15177      * Creates an object with the same keys as `object` and values generated by
15178      * running each own enumerable property of `object` through the callback.
15179      * The callback is bound to `thisArg` and invoked with three arguments;
15180      * (value, key, object).
15181      *
15182      * If a property name is provided for `callback` the created "_.pluck" style
15183      * callback will return the property value of the given element.
15184      *
15185      * If an object is provided for `callback` the created "_.where" style callback
15186      * will return `true` for elements that have the properties of the given object,
15187      * else `false`.
15188      *
15189      * @static
15190      * @memberOf _
15191      * @category Objects
15192      * @param {Object} object The object to iterate over.
15193      * @param {Function|Object|string} [callback=identity] The function called
15194      *  per iteration. If a property name or object is provided it will be used
15195      *  to create a "_.pluck" or "_.where" style callback, respectively.
15196      * @param {*} [thisArg] The `this` binding of `callback`.
15197      * @returns {Object} Returns a new object with values of the results of each `callback` execution.
15198      * @example
15199      *
15200      * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
15201      * // => { 'a': 3, 'b': 6, 'c': 9 }
15202      *
15203      * var characters = {
15204      *   'fred': { 'name': 'fred', 'age': 40 },
15205      *   'pebbles': { 'name': 'pebbles', 'age': 1 }
15206      * };
15207      *
15208      * // using "_.pluck" callback shorthand
15209      * _.mapValues(characters, 'age');
15210      * // => { 'fred': 40, 'pebbles': 1 }
15211      */
15212     function mapValues(object, callback, thisArg) {
15213       var result = {};
15214
15215       callback = lodash.createCallback(callback, thisArg, 3);
15216       baseForOwn(object, function(value, key, object) {
15217         result[key] = callback(value, key, object);
15218       });
15219       return result;
15220     }
15221
15222     /**
15223      * Recursively merges own enumerable properties of the source object(s), that
15224      * don't resolve to `undefined` into the destination object. Subsequent sources
15225      * will overwrite property assignments of previous sources. If a callback is
15226      * provided it will be executed to produce the merged values of the destination
15227      * and source properties. If the callback returns `undefined` merging will
15228      * be handled by the method instead. The callback is bound to `thisArg` and
15229      * invoked with two arguments; (objectValue, sourceValue).
15230      *
15231      * @static
15232      * @memberOf _
15233      * @category Objects
15234      * @param {Object} object The destination object.
15235      * @param {...Object} [source] The source objects.
15236      * @param {Function} [callback] The function to customize merging properties.
15237      * @param {*} [thisArg] The `this` binding of `callback`.
15238      * @returns {Object} Returns the destination object.
15239      * @example
15240      *
15241      * var names = {
15242      *   'characters': [
15243      *     { 'name': 'barney' },
15244      *     { 'name': 'fred' }
15245      *   ]
15246      * };
15247      *
15248      * var ages = {
15249      *   'characters': [
15250      *     { 'age': 36 },
15251      *     { 'age': 40 }
15252      *   ]
15253      * };
15254      *
15255      * _.merge(names, ages);
15256      * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
15257      *
15258      * var food = {
15259      *   'fruits': ['apple'],
15260      *   'vegetables': ['beet']
15261      * };
15262      *
15263      * var otherFood = {
15264      *   'fruits': ['banana'],
15265      *   'vegetables': ['carrot']
15266      * };
15267      *
15268      * _.merge(food, otherFood, function(a, b) {
15269      *   return _.isArray(a) ? a.concat(b) : undefined;
15270      * });
15271      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
15272      */
15273     function merge(object, source, guard) {
15274       if (!isObject(object)) {
15275         return object;
15276       }
15277       var args = arguments,
15278           length = args.length,
15279           type = typeof guard;
15280
15281       // enables use as a callback for functions like `_.reduce`
15282       if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
15283         length = 2;
15284       }
15285       // juggle arguments
15286       if (length > 3 && typeof args[length - 2] == 'function') {
15287         var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
15288       } else if (length > 2 && typeof args[length - 1] == 'function') {
15289         callback = args[--length];
15290       }
15291       var sources = slice(arguments, 1, length),
15292           index = -1,
15293           stackA = getArray(),
15294           stackB = getArray();
15295
15296       while (++index < length) {
15297         baseMerge(object, sources[index], callback, stackA, stackB);
15298       }
15299       releaseArray(stackA);
15300       releaseArray(stackB);
15301       return object;
15302     }
15303
15304     /**
15305      * Creates a shallow clone of `object` excluding the specified properties.
15306      * Property names may be specified as individual arguments or as arrays of
15307      * property names. If a callback is provided it will be executed for each
15308      * property of `object` omitting the properties the callback returns truey
15309      * for. The callback is bound to `thisArg` and invoked with three arguments;
15310      * (value, key, object).
15311      *
15312      * @static
15313      * @memberOf _
15314      * @category Objects
15315      * @param {Object} object The source object.
15316      * @param {Function|...string|string[]} [callback] The function called per
15317      *  iteration or property names to omit, specified as individual property
15318      *  names or arrays of property names.
15319      * @param {*} [thisArg] The `this` binding of `callback`.
15320      * @returns {Object} Returns an object without the omitted properties.
15321      * @example
15322      *
15323      * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
15324      * // => { 'name': 'fred' }
15325      *
15326      * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
15327      *   return typeof value == 'number';
15328      * });
15329      * // => { 'name': 'fred' }
15330      */
15331     function omit(object, callback, thisArg) {
15332       var result = {};
15333
15334       if (typeof callback != 'function') {
15335         var omitProps = baseFlatten(arguments, true, false, 1),
15336             length = omitProps.length;
15337
15338         while (length--) {
15339           omitProps[length] = String(omitProps[length]);
15340         }
15341         var props = [];
15342         baseForIn(object, function(value, key) {
15343           props.push(key);
15344         });
15345
15346         var index = -1;
15347         props = baseDifference(props, omitProps);
15348         length = props.length;
15349
15350         while (++index < length) {
15351           var key = props[index];
15352           result[key] = object[key];
15353         }
15354       } else {
15355         callback = lodash.createCallback(callback, thisArg, 3);
15356         baseForIn(object, function(value, key, object) {
15357           if (!callback(value, key, object)) {
15358             result[key] = value;
15359           }
15360         });
15361       }
15362       return result;
15363     }
15364
15365     /**
15366      * Creates a two dimensional array of an object's key-value pairs,
15367      * i.e. `[[key1, value1], [key2, value2]]`.
15368      *
15369      * @static
15370      * @memberOf _
15371      * @category Objects
15372      * @param {Object} object The object to inspect.
15373      * @returns {Array} Returns new array of key-value pairs.
15374      * @example
15375      *
15376      * _.pairs({ 'barney': 36, 'fred': 40 });
15377      * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
15378      */
15379     function pairs(object) {
15380       var index = -1,
15381           props = keys(object),
15382           length = props.length,
15383           result = Array(length);
15384
15385       while (++index < length) {
15386         var key = props[index];
15387         result[index] = [key, object[key]];
15388       }
15389       return result;
15390     }
15391
15392     /**
15393      * Creates a shallow clone of `object` composed of the specified properties.
15394      * Property names may be specified as individual arguments or as arrays of
15395      * property names. If a callback is provided it will be executed for each
15396      * property of `object` picking the properties the callback returns truey
15397      * for. The callback is bound to `thisArg` and invoked with three arguments;
15398      * (value, key, object).
15399      *
15400      * @static
15401      * @memberOf _
15402      * @category Objects
15403      * @param {Object} object The source object.
15404      * @param {Function|...string|string[]} [callback] The function called per
15405      *  iteration or property names to pick, specified as individual property
15406      *  names or arrays of property names.
15407      * @param {*} [thisArg] The `this` binding of `callback`.
15408      * @returns {Object} Returns an object composed of the picked properties.
15409      * @example
15410      *
15411      * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
15412      * // => { 'name': 'fred' }
15413      *
15414      * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
15415      *   return key.charAt(0) != '_';
15416      * });
15417      * // => { 'name': 'fred' }
15418      */
15419     function pick(object, callback, thisArg) {
15420       var result = {};
15421
15422       if (typeof callback != 'function') {
15423         var index = -1,
15424             props = baseFlatten(arguments, true, false, 1),
15425             length = isObject(object) ? props.length : 0;
15426
15427         while (++index < length) {
15428           var key = props[index];
15429           if (key in object) {
15430             result[key] = object[key];
15431           }
15432         }
15433       } else {
15434         callback = lodash.createCallback(callback, thisArg, 3);
15435         baseForIn(object, function(value, key, object) {
15436           if (callback(value, key, object)) {
15437             result[key] = value;
15438           }
15439         });
15440       }
15441       return result;
15442     }
15443
15444     /**
15445      * An alternative to `_.reduce`; this method transforms `object` to a new
15446      * `accumulator` object which is the result of running each of its own
15447      * enumerable properties through a callback, with each callback execution
15448      * potentially mutating the `accumulator` object. The callback is bound to
15449      * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
15450      * Callbacks may exit iteration early by explicitly returning `false`.
15451      *
15452      * @static
15453      * @memberOf _
15454      * @category Objects
15455      * @param {Array|Object} object The object to iterate over.
15456      * @param {Function} [callback=identity] The function called per iteration.
15457      * @param {*} [accumulator] The custom accumulator value.
15458      * @param {*} [thisArg] The `this` binding of `callback`.
15459      * @returns {*} Returns the accumulated value.
15460      * @example
15461      *
15462      * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8], function(result, num) {
15463      *   num *= num;
15464      *   if (num % 2) {
15465      *     return result.push(num) < 3;
15466      *   }
15467      * });
15468      * // => [1, 9, 25]
15469      *
15470      * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
15471      *   result[key] = num * 3;
15472      * });
15473      * // => { 'a': 3, 'b': 6, 'c': 9 }
15474      */
15475     function transform(object, callback, accumulator, thisArg) {
15476       var isArr = isArray(object);
15477       if (accumulator == null) {
15478         if (isArr) {
15479           accumulator = [];
15480         } else {
15481           var ctor = object && object.constructor,
15482               proto = ctor && ctor.prototype;
15483
15484           accumulator = baseCreate(proto);
15485         }
15486       }
15487       if (callback) {
15488         callback = lodash.createCallback(callback, thisArg, 4);
15489         (isArr ? baseEach : baseForOwn)(object, function(value, index, object) {
15490           return callback(accumulator, value, index, object);
15491         });
15492       }
15493       return accumulator;
15494     }
15495
15496     /**
15497      * Creates an array composed of the own enumerable property values of `object`.
15498      *
15499      * @static
15500      * @memberOf _
15501      * @category Objects
15502      * @param {Object} object The object to inspect.
15503      * @returns {Array} Returns an array of property values.
15504      * @example
15505      *
15506      * _.values({ 'one': 1, 'two': 2, 'three': 3 });
15507      * // => [1, 2, 3] (property order is not guaranteed across environments)
15508      */
15509     function values(object) {
15510       var index = -1,
15511           props = keys(object),
15512           length = props.length,
15513           result = Array(length);
15514
15515       while (++index < length) {
15516         result[index] = object[props[index]];
15517       }
15518       return result;
15519     }
15520
15521     /*--------------------------------------------------------------------------*/
15522
15523     /**
15524      * Converts the first character of `string` to upper case.
15525      *
15526      * @static
15527      * @memberOf _
15528      * @category Strings
15529      * @param {string} string The string to capitalize.
15530      * @returns {string} Returns the capitalized string.
15531      * @example
15532      *
15533      * _.capitalize('fred');
15534      * // => 'Fred'
15535      */
15536     function capitalize(string) {
15537       if (string == null) {
15538         return '';
15539       }
15540       string = String(string);
15541       return string.charAt(0).toUpperCase() + string.slice(1);
15542     }
15543
15544     /**
15545      * Converts the characters "&", "<", ">", '"', and "'" in `string` to
15546      * their corresponding HTML entities.
15547      *
15548      * Note: No other characters are escaped. To escape additional characters
15549      * use a third-party library like [_he_](http://mths.be/he).
15550      *
15551      * When working with HTML you should always quote attribute values to reduce
15552      * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping)
15553      * for more details.
15554      *
15555      * @static
15556      * @memberOf _
15557      * @category Strings
15558      * @param {string} string The string to escape.
15559      * @returns {string} Returns the escaped string.
15560      * @example
15561      *
15562      * _.escape('fred, barney, & pebbles');
15563      * // => 'fred, barney, &amp; pebbles'
15564      */
15565     function escape(string) {
15566       return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
15567     }
15568
15569     /**
15570      * A micro-templating method that handles arbitrary delimiters, preserves
15571      * whitespace, and correctly escapes quotes within interpolated code.
15572      *
15573      * Note: In the development build, `_.template` utilizes sourceURLs for easier
15574      * debugging. See [HTML5 Rocks' article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
15575      * for more details.
15576      *
15577      * For more information on precompiling templates see
15578      * [Lo-Dash's custom builds documentation](http://lodash.com/custom-builds).
15579      *
15580      * For more information on Chrome extension sandboxes see
15581      * [Chrome's extensions documentation](http://developer.chrome.com/stable/extensions/sandboxingEval.html).
15582      *
15583      * @static
15584      * @memberOf _
15585      * @category Strings
15586      * @param {string} text The template text.
15587      * @param {Object} [data] The data object used to populate the text.
15588      * @param {Object} [options] The options object.
15589      * @param {RegExp} [options.escape] The "escape" delimiter.
15590      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
15591      * @param {Object} [options.imports] An object to import into the template as local variables.
15592      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
15593      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
15594      * @param {string} [options.variable] The data object variable name.
15595      * @returns {Function|string} Returns a compiled function when no `data` object
15596      *  is given, else it returns the interpolated text.
15597      * @example
15598      *
15599      * // using the "interpolate" delimiter to create a compiled template
15600      * var compiled = _.template('hello <%= name %>');
15601      * compiled({ 'name': 'fred' });
15602      * // => 'hello fred'
15603      *
15604      * // using the "escape" delimiter to escape HTML in data property values
15605      * _.template('<b><%- value %></b>', { 'value': '<script>' });
15606      * // => '<b>&lt;script&gt;</b>'
15607      *
15608      * // using the "evaluate" delimiter to generate HTML
15609      * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
15610      * _.template(list, { 'people': ['fred', 'barney'] });
15611      * // => '<li>fred</li><li>barney</li>'
15612      *
15613      * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
15614      * _.template('hello ${ name }', { 'name': 'pebbles' });
15615      * // => 'hello pebbles'
15616      *
15617      * // using the internal `print` function in "evaluate" delimiters
15618      * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
15619      * // => 'hello barney!'
15620      *
15621      * // using a custom template delimiters
15622      * _.templateSettings = {
15623      *   'interpolate': /{{([\s\S]+?)}}/g
15624      * };
15625      *
15626      * _.template('hello {{ name }}!', { 'name': 'mustache' });
15627      * // => 'hello mustache!'
15628      *
15629      * // using the `imports` option to import jQuery
15630      * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
15631      * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
15632      * // => '<li>fred</li><li>barney</li>'
15633      *
15634      * // using the `sourceURL` option to specify a custom sourceURL for the template
15635      * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
15636      * compiled(data);
15637      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
15638      *
15639      * // using the `variable` option to ensure a with-statement isn't used in the compiled template
15640      * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
15641      * compiled.source;
15642      * // => function(data) {
15643      *   var __t, __p = '', __e = _.escape;
15644      *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
15645      *   return __p;
15646      * }
15647      *
15648      * // using the `source` property to inline compiled templates for meaningful
15649      * // line numbers in error messages and a stack trace
15650      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
15651      *   var JST = {\
15652      *     "main": ' + _.template(mainText).source + '\
15653      *   };\
15654      * ');
15655      */
15656     function template(text, data, options) {
15657       // based on John Resig's `tmpl` implementation
15658       // http://ejohn.org/blog/javascript-micro-templating/
15659       // and Laura Doktorova's doT.js
15660       // https://github.com/olado/doT
15661       var settings = lodash.templateSettings;
15662       text = String(text || '');
15663
15664       // avoid missing dependencies when `iteratorTemplate` is not defined
15665       options = iteratorTemplate ? defaults({}, options, settings) : settings;
15666
15667       var imports = iteratorTemplate && defaults({}, options.imports, settings.imports),
15668           importsKeys = iteratorTemplate ? keys(imports) : ['_'],
15669           importsValues = iteratorTemplate ? values(imports) : [lodash];
15670
15671       var isEvaluating,
15672           index = 0,
15673           interpolate = options.interpolate || reNoMatch,
15674           source = "__p += '";
15675
15676       // compile the regexp to match each delimiter
15677       var reDelimiters = RegExp(
15678         (options.escape || reNoMatch).source + '|' +
15679         interpolate.source + '|' +
15680         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
15681         (options.evaluate || reNoMatch).source + '|$'
15682       , 'g');
15683
15684       text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
15685         interpolateValue || (interpolateValue = esTemplateValue);
15686
15687         // escape characters that cannot be included in string literals
15688         source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
15689
15690         // replace delimiters with snippets
15691         if (escapeValue) {
15692           source += "' +\n__e(" + escapeValue + ") +\n'";
15693         }
15694         if (evaluateValue) {
15695           isEvaluating = true;
15696           source += "';\n" + evaluateValue + ";\n__p += '";
15697         }
15698         if (interpolateValue) {
15699           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
15700         }
15701         index = offset + match.length;
15702
15703         // the JS engine embedded in Adobe products requires returning the `match`
15704         // string in order to produce the correct `offset` value
15705         return match;
15706       });
15707
15708       source += "';\n";
15709
15710       // if `variable` is not specified, wrap a with-statement around the generated
15711       // code to add the data object to the top of the scope chain
15712       var variable = options.variable,
15713           hasVariable = variable;
15714
15715       if (!hasVariable) {
15716         variable = 'obj';
15717         source = 'with (' + variable + ') {\n' + source + '\n}\n';
15718       }
15719       // cleanup code by stripping empty strings
15720       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
15721         .replace(reEmptyStringMiddle, '$1')
15722         .replace(reEmptyStringTrailing, '$1;');
15723
15724       // frame code as the function body
15725       source = 'function(' + variable + ') {\n' +
15726         (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
15727         "var __t, __p = '', __e = _.escape" +
15728         (isEvaluating
15729           ? ', __j = Array.prototype.join;\n' +
15730             "function print() { __p += __j.call(arguments, '') }\n"
15731           : ';\n'
15732         ) +
15733         source +
15734         'return __p\n}';
15735
15736       // Use a sourceURL for easier debugging.
15737       // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
15738       var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
15739
15740       try {
15741         var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
15742       } catch(e) {
15743         e.source = source;
15744         throw e;
15745       }
15746       if (data) {
15747         return result(data);
15748       }
15749       // provide the compiled function's source by its `toString` method, in
15750       // supported environments, or the `source` property as a convenience for
15751       // inlining compiled templates during the build process
15752       result.source = source;
15753       return result;
15754     }
15755
15756     /**
15757      * Removes leading and trailing whitespace or specified characters from `string`.
15758      *
15759      * @static
15760      * @memberOf _
15761      * @category Strings
15762      * @param {string} string The string to trim.
15763      * @param {string} [chars=whitespace] The characters to trim.
15764      * @returns {string} Returns the trimmed string.
15765      * @example
15766      *
15767      * _.trim('  fred  ');
15768      * // => 'fred'
15769      *
15770      * _.trim('-_-fred-_-', '_-');
15771      * // => 'fred'
15772      */
15773     var trim = !nativeTrim ? shimTrim : function(string, chars) {
15774       if (string == null) {
15775         return '';
15776       }
15777       return chars == null ? nativeTrim.call(string) : shimTrim(string, chars);
15778     };
15779
15780     /**
15781      * Removes leading whitespace or specified characters from `string`.
15782      *
15783      * @static
15784      * @memberOf _
15785      * @category Strings
15786      * @param {string} string The string to trim.
15787      * @param {string} [chars=whitespace] The characters to trim.
15788      * @returns {string} Returns the trimmed string.
15789      * @example
15790      *
15791      * _.trimLeft('  fred  ');
15792      * // => 'fred  '
15793      *
15794      * _.trimLeft('-_-fred-_-', '_-');
15795      * // => 'fred-_-'
15796      */
15797     var trimLeft = !nativeTrimLeft ? shimTrimLeft : function(string, chars) {
15798       if (string == null) {
15799         return '';
15800       }
15801       return chars == null ? nativeTrimLeft.call(string) : shimTrimLeft(string, chars);
15802     };
15803
15804     /**
15805      * Removes trailing whitespace or specified characters from `string`.
15806      *
15807      * @static
15808      * @memberOf _
15809      * @category Strings
15810      * @param {string} string The string to trim.
15811      * @param {string} [chars=whitespace] The characters to trim.
15812      * @returns {string} Returns the trimmed string.
15813      * @example
15814      *
15815      * _.trimRight('  fred  ');
15816      * // => '  fred'
15817      *
15818      * _.trimRight('-_-fred-_-', '_-');
15819      * // => '-_-fred'
15820      */
15821     var trimRight = !nativeTrimRight ? shimTrimRight : function(string, chars) {
15822       if (string == null) {
15823         return '';
15824       }
15825       return chars == null ? nativeTrimRight.call(string) : shimTrimRight(string, chars);
15826     };
15827
15828     /**
15829      * The inverse of `_.escape`; this method converts the HTML entities
15830      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
15831      * corresponding characters.
15832      *
15833      * Note: No other HTML entities are unescaped. To unescape additional HTML
15834      * entities use a third-party library like [_he_](http://mths.be/he).
15835      *
15836      * @static
15837      * @memberOf _
15838      * @category Strings
15839      * @param {string} string The string to unescape.
15840      * @returns {string} Returns the unescaped string.
15841      * @example
15842      *
15843      * _.unescape('fred, barney &amp; pebbles');
15844      * // => 'fred, barney & pebbles'
15845      */
15846     function unescape(string) {
15847       if (string == null) {
15848         return '';
15849       }
15850       string = String(string);
15851       return string.indexOf(';') < 0 ? string : string.replace(reEscapedHtml, unescapeHtmlChar);
15852     }
15853
15854     /*--------------------------------------------------------------------------*/
15855
15856     /**
15857      * Creates a function that returns `value`.
15858      *
15859      * @static
15860      * @memberOf _
15861      * @category Utilities
15862      * @param {*} value The value to return from the new function.
15863      * @returns {Function} Returns the new function.
15864      * @example
15865      *
15866      * var object = { 'name': 'fred' };
15867      * var getter = _.constant(object);
15868      * getter() === object;
15869      * // => true
15870      */
15871     function constant(value) {
15872       return function() {
15873         return value;
15874       };
15875     }
15876
15877     /**
15878      * Produces a callback bound to an optional `thisArg`. If `func` is a property
15879      * name the created callback will return the property value for a given element.
15880      * If `func` is an object the created callback will return `true` for elements
15881      * that contain the equivalent object properties, otherwise it will return `false`.
15882      *
15883      * @static
15884      * @memberOf _
15885      * @alias callback
15886      * @category Utilities
15887      * @param {*} [func=identity] The value to convert to a callback.
15888      * @param {*} [thisArg] The `this` binding of the created callback.
15889      * @param {number} [argCount] The number of arguments the callback accepts.
15890      * @returns {Function} Returns a callback function.
15891      * @example
15892      *
15893      * var characters = [
15894      *   { 'name': 'barney', 'age': 36 },
15895      *   { 'name': 'fred',   'age': 40 }
15896      * ];
15897      *
15898      * // wrap to create custom callback shorthands
15899      * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
15900      *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
15901      *   return !match ? func(callback, thisArg) : function(object) {
15902      *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
15903      *   };
15904      * });
15905      *
15906      * _.filter(characters, 'age__gt38');
15907      * // => [{ 'name': 'fred', 'age': 40 }]
15908      */
15909     function createCallback(func, thisArg, argCount) {
15910       var type = typeof func;
15911       if (type == 'function' || func == null) {
15912         return (typeof thisArg == 'undefined' || !('prototype' in func)) &&
15913           func || baseCreateCallback(func, thisArg, argCount);
15914       }
15915       // handle "_.pluck" and "_.where" style callback shorthands
15916       return type != 'object' ? property(func) : matches(func);
15917     }
15918
15919     /**
15920      * This method returns the first argument provided to it.
15921      *
15922      * @static
15923      * @memberOf _
15924      * @category Utilities
15925      * @param {*} value Any value.
15926      * @returns {*} Returns `value`.
15927      * @example
15928      *
15929      * var object = { 'name': 'fred' };
15930      * _.identity(object) === object;
15931      * // => true
15932      */
15933     function identity(value) {
15934       return value;
15935     }
15936
15937     /**
15938      * Creates a "_.where" style function, which performs a deep comparison
15939      * between a given object and the `source` object, returning `true` if the
15940      * given object has equivalent property values, else `false`.
15941      *
15942      * @static
15943      * @memberOf _
15944      * @category Utilities
15945      * @param {Object} source The object of property values to match.
15946      * @returns {Function} Returns the new function.
15947      * @example
15948      *
15949      * var characters = [
15950      *   { 'name': 'fred',   'age': 40 },
15951      *   { 'name': 'barney', 'age': 36 }
15952      * ];
15953      *
15954      * var matchesAge = _.matches({ 'age': 36 });
15955      *
15956      * _.filter(characters, matchesAge);
15957      * // => [{ 'name': 'barney', 'age': 36 }]
15958      *
15959      * _.find(characters, matchesAge);
15960      * // => { 'name': 'barney', 'age': 36 }
15961      */
15962     function matches(source) {
15963       source || (source = {});
15964
15965       var props = keys(source),
15966           key = props[0],
15967           a = source[key];
15968
15969       // fast path the common case of providing an object with a single
15970       // property containing a primitive value
15971       if (props.length == 1 && a === a && !isObject(a)) {
15972         return function(object) {
15973           if (!hasOwnProperty.call(object, key)) {
15974             return false;
15975           }
15976           var b = object[key];
15977           return a === b && (a !== 0 || (1 / a == 1 / b));
15978         };
15979       }
15980       return function(object) {
15981         var length = props.length,
15982             result = false;
15983
15984         while (length--) {
15985           var key = props[length];
15986           if (!(result = hasOwnProperty.call(object, key) &&
15987                 baseIsEqual(object[key], source[key], null, true))) {
15988             break;
15989           }
15990         }
15991         return result;
15992       };
15993     }
15994
15995     /**
15996      * Adds function properties of a source object to the destination object.
15997      * If `object` is a function methods will be added to its prototype as well.
15998      *
15999      * @static
16000      * @memberOf _
16001      * @category Utilities
16002      * @param {Function|Object} [object=lodash] object The destination object.
16003      * @param {Object} source The object of functions to add.
16004      * @param {Object} [options] The options object.
16005      * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
16006      * @example
16007      *
16008      * function vowels(string) {
16009      *   return _.filter(string, function(v) {
16010      *     return /[aeiou]/i.test(v);
16011      *   });
16012      * }
16013      *
16014      * _.mixin({ 'vowels': vowels });
16015      * _.vowels('fred');
16016      * // => ['e']
16017      *
16018      * _('fred').vowels().value();
16019      * // => ['e']
16020      *
16021      * _.mixin({ 'vowels': vowels }, { 'chain': false });
16022      * _('fred').vowels();
16023      * // => ['e']
16024      */
16025     function mixin(object, source, options) {
16026       var chain = true,
16027           methodNames = source && functions(source);
16028
16029       if (!source || (!options && !methodNames.length)) {
16030         if (options == null) {
16031           options = source;
16032         }
16033         source = object;
16034         object = lodash;
16035         methodNames = functions(source);
16036       }
16037       if (options === false) {
16038         chain = false;
16039       } else if (isObject(options) && 'chain' in options) {
16040         chain = options.chain;
16041       }
16042       var index = -1,
16043           isFunc = isFunction(object),
16044           length = methodNames ? methodNames.length : 0;
16045
16046       while (++index < length) {
16047         var methodName = methodNames[index],
16048             func = object[methodName] = source[methodName];
16049
16050         if (isFunc) {
16051           object.prototype[methodName] = (function(func) {
16052             return function() {
16053               var chainAll = this.__chain__,
16054                   value = this.__wrapped__,
16055                   args = [value];
16056
16057               push.apply(args, arguments);
16058               var result = func.apply(object, args);
16059               if (chain || chainAll) {
16060                 if (value === result && isObject(result)) {
16061                   return this;
16062                 }
16063                 result = new object(result);
16064                 result.__chain__ = chainAll;
16065               }
16066               return result;
16067             };
16068           }(func));
16069         }
16070       }
16071     }
16072
16073     /**
16074      * Reverts the '_' variable to its previous value and returns a reference to
16075      * the `lodash` function.
16076      *
16077      * @static
16078      * @memberOf _
16079      * @category Utilities
16080      * @returns {Function} Returns the `lodash` function.
16081      * @example
16082      *
16083      * var lodash = _.noConflict();
16084      */
16085     function noConflict() {
16086       context._ = oldDash;
16087       return this;
16088     }
16089
16090     /**
16091      * A no-operation function.
16092      *
16093      * @static
16094      * @memberOf _
16095      * @category Utilities
16096      * @example
16097      *
16098      * var object = { 'name': 'fred' };
16099      * _.noop(object) === undefined;
16100      * // => true
16101      */
16102     function noop() {
16103       // no operation performed
16104     }
16105
16106     /**
16107      * Gets the number of milliseconds that have elapsed since the Unix epoch
16108      * (1 January 1970 00:00:00 UTC).
16109      *
16110      * @static
16111      * @memberOf _
16112      * @category Utilities
16113      * @example
16114      *
16115      * var stamp = _.now();
16116      * _.defer(function() { console.log(_.now() - stamp); });
16117      * // => logs the number of milliseconds it took for the deferred function to be called
16118      */
16119     var now = nativeNow || function() {
16120       return new Date().getTime();
16121     };
16122
16123     /**
16124      * Converts `value` to an integer of the specified radix. If `radix` is
16125      * `undefined` or `0` a `radix` of `10` is used unless the `value` is a
16126      * hexadecimal, in which case a `radix` of `16` is used.
16127      *
16128      * Note: This method avoids differences in native ES3 and ES5 `parseInt`
16129      * implementations. See the [ES5 spec](http://es5.github.io/#E)
16130      * for more details.
16131      *
16132      * @static
16133      * @memberOf _
16134      * @category Utilities
16135      * @param {string} value The value to parse.
16136      * @param {number} [radix] The radix used to interpret the value to parse.
16137      * @returns {number} Returns the new integer value.
16138      * @example
16139      *
16140      * _.parseInt('08');
16141      * // => 8
16142      */
16143     var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
16144       // Firefox < 21 and Opera < 15 follow ES3  for `parseInt` and
16145       // Chrome fails to trim leading <BOM> whitespace characters.
16146       // See https://code.google.com/p/v8/issues/detail?id=3109
16147       value = trim(value);
16148       return nativeParseInt(value, +radix || (reHexPrefix.test(value) ? 16 : 10));
16149     };
16150
16151     /**
16152      * Creates a "_.pluck" style function, which returns the `key` value of a
16153      * given object.
16154      *
16155      * @static
16156      * @memberOf _
16157      * @category Utilities
16158      * @param {string} key The name of the property to retrieve.
16159      * @returns {Function} Returns the new function.
16160      * @example
16161      *
16162      * var characters = [
16163      *   { 'name': 'fred',   'age': 40 },
16164      *   { 'name': 'barney', 'age': 36 }
16165      * ];
16166      *
16167      * var getName = _.property('name');
16168      *
16169      * _.map(characters, getName);
16170      * // => ['barney', 'fred']
16171      *
16172      * _.sortBy(characters, getName);
16173      * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
16174      */
16175     function property(key) {
16176       return function(object) {
16177         return object[key];
16178       };
16179     }
16180
16181     /**
16182      * Produces a random number between `min` and `max` (inclusive). If only one
16183      * argument is provided a number between `0` and the given number will be
16184      * returned. If `floating` is truey or either `min` or `max` are floats a
16185      * floating-point number will be returned instead of an integer.
16186      *
16187      * @static
16188      * @memberOf _
16189      * @category Utilities
16190      * @param {number} [min=0] The minimum possible value.
16191      * @param {number} [max=1] The maximum possible value.
16192      * @param {boolean} [floating=false] Specify returning a floating-point number.
16193      * @returns {number} Returns a random number.
16194      * @example
16195      *
16196      * _.random(0, 5);
16197      * // => an integer between 0 and 5
16198      *
16199      * _.random(5);
16200      * // => also an integer between 0 and 5
16201      *
16202      * _.random(5, true);
16203      * // => a floating-point number between 0 and 5
16204      *
16205      * _.random(1.2, 5.2);
16206      * // => a floating-point number between 1.2 and 5.2
16207      */
16208     function random(min, max, floating) {
16209       var noMin = min == null,
16210           noMax = max == null;
16211
16212       if (floating == null) {
16213         if (noMax && typeof min == 'boolean') {
16214           floating = min;
16215           min = 1;
16216         }
16217         else if (typeof max == 'boolean') {
16218           floating = max;
16219           noMax = true;
16220         }
16221       }
16222       if (noMin && noMax) {
16223         max = 1;
16224         noMax = false;
16225       }
16226       min = +min || 0;
16227       if (noMax) {
16228         max = min;
16229         min = 0;
16230       } else {
16231         max = +max || 0;
16232       }
16233       if (floating || min % 1 || max % 1) {
16234         var rand = nativeRandom();
16235         return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
16236       }
16237       return baseRandom(min, max);
16238     }
16239
16240     /**
16241      * Resolves the value of property `key` on `object`. If `key` is a function
16242      * it will be invoked with the `this` binding of `object` and its result
16243      * returned, else the property value is returned. If `object` is `null` or
16244      * `undefined` then `undefined` is returned. If a default value is provided
16245      * it will be returned if the property value resolves to `undefined`.
16246      *
16247      * @static
16248      * @memberOf _
16249      * @category Utilities
16250      * @param {Object} object The object to inspect.
16251      * @param {string} key The name of the property to resolve.
16252      * @param {*} [defaultValue] The value returned if the property value
16253      *  resolves to `undefined`.
16254      * @returns {*} Returns the resolved value.
16255      * @example
16256      *
16257      * var object = {
16258      *   'name': 'fred',
16259      *   'age': function() {
16260      *     return 40;
16261      *   }
16262      * };
16263      *
16264      * _.result(object, 'name');
16265      * // => 'fred'
16266      *
16267      * _.result(object, 'age');
16268      * // => 40
16269      *
16270      * _.result(object, 'employer', 'slate');
16271      * // => 'slate'
16272      */
16273     function result(object, key, defaultValue) {
16274       var value = object == null ? undefined : object[key];
16275       if (typeof value == 'undefined') {
16276         return defaultValue;
16277       }
16278       return isFunction(value) ? object[key]() : value;
16279     }
16280
16281     /**
16282      * Executes the callback `n` times, returning an array of the results
16283      * of each callback execution. The callback is bound to `thisArg` and invoked
16284      * with one argument; (index).
16285      *
16286      * @static
16287      * @memberOf _
16288      * @category Utilities
16289      * @param {number} n The number of times to execute the callback.
16290      * @param {Function} callback The function called per iteration.
16291      * @param {*} [thisArg] The `this` binding of `callback`.
16292      * @returns {Array} Returns an array of the results of each `callback` execution.
16293      * @example
16294      *
16295      * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
16296      * // => [3, 6, 4]
16297      *
16298      * _.times(3, function(n) { mage.castSpell(n); });
16299      * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
16300      *
16301      * _.times(3, function(n) { this.cast(n); }, mage);
16302      * // => also calls `mage.castSpell(n)` three times
16303      */
16304     function times(n, callback, thisArg) {
16305       n = (n = +n) > -1 ? n : 0;
16306       var index = -1,
16307           result = Array(n);
16308
16309       callback = baseCreateCallback(callback, thisArg, 1);
16310       while (++index < n) {
16311         result[index] = callback(index);
16312       }
16313       return result;
16314     }
16315
16316     /**
16317      * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
16318      *
16319      * @static
16320      * @memberOf _
16321      * @category Utilities
16322      * @param {string} [prefix] The value to prefix the ID with.
16323      * @returns {string} Returns the unique ID.
16324      * @example
16325      *
16326      * _.uniqueId('contact_');
16327      * // => 'contact_104'
16328      *
16329      * _.uniqueId();
16330      * // => '105'
16331      */
16332     function uniqueId(prefix) {
16333       var id = ++idCounter;
16334       return String(prefix == null ? '' : prefix) + id;
16335     }
16336
16337     /*--------------------------------------------------------------------------*/
16338
16339     // add functions that return wrapped values when chaining
16340     lodash.after = after;
16341     lodash.assign = assign;
16342     lodash.at = at;
16343     lodash.bind = bind;
16344     lodash.bindAll = bindAll;
16345     lodash.bindKey = bindKey;
16346     lodash.chain = chain;
16347     lodash.compact = compact;
16348     lodash.compose = compose;
16349     lodash.constant = constant;
16350     lodash.countBy = countBy;
16351     lodash.create = create;
16352     lodash.createCallback = createCallback;
16353     lodash.curry = curry;
16354     lodash.debounce = debounce;
16355     lodash.defaults = defaults;
16356     lodash.defer = defer;
16357     lodash.delay = delay;
16358     lodash.difference = difference;
16359     lodash.filter = filter;
16360     lodash.flatten = flatten;
16361     lodash.forEach = forEach;
16362     lodash.forEachRight = forEachRight;
16363     lodash.forIn = forIn;
16364     lodash.forInRight = forInRight;
16365     lodash.forOwn = forOwn;
16366     lodash.forOwnRight = forOwnRight;
16367     lodash.functions = functions;
16368     lodash.groupBy = groupBy;
16369     lodash.indexBy = indexBy;
16370     lodash.initial = initial;
16371     lodash.intersection = intersection;
16372     lodash.invert = invert;
16373     lodash.invoke = invoke;
16374     lodash.keys = keys;
16375     lodash.map = map;
16376     lodash.mapValues = mapValues;
16377     lodash.matches = matches;
16378     lodash.max = max;
16379     lodash.memoize = memoize;
16380     lodash.merge = merge;
16381     lodash.min = min;
16382     lodash.omit = omit;
16383     lodash.once = once;
16384     lodash.pairs = pairs;
16385     lodash.partial = partial;
16386     lodash.partialRight = partialRight;
16387     lodash.partition = partition;
16388     lodash.pick = pick;
16389     lodash.pluck = pluck;
16390     lodash.property = property;
16391     lodash.pull = pull;
16392     lodash.range = range;
16393     lodash.reject = reject;
16394     lodash.remove = remove;
16395     lodash.rest = rest;
16396     lodash.shuffle = shuffle;
16397     lodash.slice = slice;
16398     lodash.sortBy = sortBy;
16399     lodash.tap = tap;
16400     lodash.throttle = throttle;
16401     lodash.times = times;
16402     lodash.toArray = toArray;
16403     lodash.transform = transform;
16404     lodash.union = union;
16405     lodash.uniq = uniq;
16406     lodash.values = values;
16407     lodash.where = where;
16408     lodash.without = without;
16409     lodash.wrap = wrap;
16410     lodash.xor = xor;
16411     lodash.zip = zip;
16412     lodash.zipObject = zipObject;
16413
16414     // add aliases
16415     lodash.callback = createCallback;
16416     lodash.collect = map;
16417     lodash.drop = rest;
16418     lodash.each = forEach;
16419     lodash.eachRight = forEachRight;
16420     lodash.extend = assign;
16421     lodash.methods = functions;
16422     lodash.object = zipObject;
16423     lodash.select = filter;
16424     lodash.tail = rest;
16425     lodash.unique = uniq;
16426     lodash.unzip = zip;
16427
16428     // add functions to `lodash.prototype`
16429     mixin(assign({}, lodash));
16430
16431     /*--------------------------------------------------------------------------*/
16432
16433     // add functions that return unwrapped values when chaining
16434     lodash.capitalize = capitalize;
16435     lodash.clone = clone;
16436     lodash.cloneDeep = cloneDeep;
16437     lodash.contains = contains;
16438     lodash.escape = escape;
16439     lodash.every = every;
16440     lodash.find = find;
16441     lodash.findIndex = findIndex;
16442     lodash.findKey = findKey;
16443     lodash.findLast = findLast;
16444     lodash.findLastIndex = findLastIndex;
16445     lodash.findLastKey = findLastKey;
16446     lodash.has = has;
16447     lodash.identity = identity;
16448     lodash.indexOf = indexOf;
16449     lodash.isArguments = isArguments;
16450     lodash.isArray = isArray;
16451     lodash.isBoolean = isBoolean;
16452     lodash.isDate = isDate;
16453     lodash.isElement = isElement;
16454     lodash.isEmpty = isEmpty;
16455     lodash.isEqual = isEqual;
16456     lodash.isFinite = isFinite;
16457     lodash.isFunction = isFunction;
16458     lodash.isNaN = isNaN;
16459     lodash.isNull = isNull;
16460     lodash.isNumber = isNumber;
16461     lodash.isObject = isObject;
16462     lodash.isPlainObject = isPlainObject;
16463     lodash.isRegExp = isRegExp;
16464     lodash.isString = isString;
16465     lodash.isUndefined = isUndefined;
16466     lodash.lastIndexOf = lastIndexOf;
16467     lodash.mixin = mixin;
16468     lodash.noConflict = noConflict;
16469     lodash.noop = noop;
16470     lodash.now = now;
16471     lodash.parseInt = parseInt;
16472     lodash.random = random;
16473     lodash.reduce = reduce;
16474     lodash.reduceRight = reduceRight;
16475     lodash.result = result;
16476     lodash.runInContext = runInContext;
16477     lodash.size = size;
16478     lodash.some = some;
16479     lodash.sortedIndex = sortedIndex;
16480     lodash.template = template;
16481     lodash.trim = trim;
16482     lodash.trimLeft = trimLeft;
16483     lodash.trimRight = trimRight;
16484     lodash.unescape = unescape;
16485     lodash.uniqueId = uniqueId;
16486
16487     // add aliases
16488     lodash.all = every;
16489     lodash.any = some;
16490     lodash.detect = find;
16491     lodash.findWhere = find;
16492     lodash.foldl = reduce;
16493     lodash.foldr = reduceRight;
16494     lodash.include = contains;
16495     lodash.inject = reduce;
16496
16497     mixin(function() {
16498       var source = {}
16499       baseForOwn(lodash, function(func, methodName) {
16500         if (!lodash.prototype[methodName]) {
16501           source[methodName] = func;
16502         }
16503       });
16504       return source;
16505     }(), false);
16506
16507     /*--------------------------------------------------------------------------*/
16508
16509     // add functions capable of returning wrapped and unwrapped values when chaining
16510     lodash.first = first;
16511     lodash.last = last;
16512     lodash.sample = sample;
16513
16514     // add aliases
16515     lodash.take = first;
16516     lodash.head = first;
16517
16518     baseForOwn(lodash, function(func, methodName) {
16519       var callbackable = methodName !== 'sample';
16520       if (!lodash.prototype[methodName]) {
16521         lodash.prototype[methodName]= function(n, guard) {
16522           var chainAll = this.__chain__,
16523               result = func(this.__wrapped__, n, guard);
16524
16525           return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
16526             ? result
16527             : new lodashWrapper(result, chainAll);
16528         };
16529       }
16530     });
16531
16532     /*--------------------------------------------------------------------------*/
16533
16534     /**
16535      * The semantic version number.
16536      *
16537      * @static
16538      * @memberOf _
16539      * @type string
16540      */
16541     lodash.VERSION = version;
16542
16543     // add "Chaining" functions to the wrapper
16544     lodash.prototype.chain = wrapperChain;
16545     lodash.prototype.toString = wrapperToString;
16546     lodash.prototype.value = wrapperValueOf;
16547     lodash.prototype.valueOf = wrapperValueOf;
16548
16549     // add `Array` functions that return unwrapped values
16550     baseEach(['join', 'pop', 'shift'], function(methodName) {
16551       var func = arrayRef[methodName];
16552       lodash.prototype[methodName] = function() {
16553         var chainAll = this.__chain__,
16554             result = func.apply(this.__wrapped__, arguments);
16555
16556         return chainAll
16557           ? new lodashWrapper(result, chainAll)
16558           : result;
16559       };
16560     });
16561
16562     // add `Array` functions that return the existing wrapped value
16563     baseEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
16564       var func = arrayRef[methodName];
16565       lodash.prototype[methodName] = function() {
16566         func.apply(this.__wrapped__, arguments);
16567         return this;
16568       };
16569     });
16570
16571     // add `Array` functions that return new wrapped values
16572     baseEach(['concat', 'splice'], function(methodName) {
16573       var func = arrayRef[methodName];
16574       lodash.prototype[methodName] = function() {
16575         return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
16576       };
16577     });
16578
16579     // avoid array-like object bugs with `Array#shift` and `Array#splice`
16580     // in IE < 9, Firefox < 10, Narwhal, and RingoJS
16581     if (!support.spliceObjects) {
16582       baseEach(['pop', 'shift', 'splice'], function(methodName) {
16583         var func = arrayRef[methodName],
16584             isSplice = methodName == 'splice';
16585
16586         lodash.prototype[methodName] = function() {
16587           var chainAll = this.__chain__,
16588               value = this.__wrapped__,
16589               result = func.apply(value, arguments);
16590
16591           if (value.length === 0) {
16592             delete value[0];
16593           }
16594           return (chainAll || isSplice)
16595             ? new lodashWrapper(result, chainAll)
16596             : result;
16597         };
16598       });
16599     }
16600
16601     // add pseudo private property to be used and removed during the build process
16602     lodash._baseForIn = baseForIn;
16603     lodash._iteratorTemplate = iteratorTemplate;
16604     lodash._shimKeys = shimKeys;
16605
16606     return lodash;
16607   }
16608
16609   /*--------------------------------------------------------------------------*/
16610
16611   // export Lo-Dash
16612   var _ = runInContext();
16613
16614   // some AMD build optimizers like r.js check for condition patterns like the following:
16615   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
16616     // Expose Lo-Dash to the global object even when an AMD loader is present in
16617     // case Lo-Dash is loaded with a RequireJS shim config.
16618     // See http://requirejs.org/docs/api.html#config-shim
16619     root._ = _;
16620
16621     // define as an anonymous module so, through path mapping, it can be
16622     // referenced as the "underscore" module
16623     define(function() {
16624       return _;
16625     });
16626   }
16627   // check for `exports` after `define` in case a build optimizer adds an `exports` object
16628   else if (freeExports && freeModule) {
16629     // in Node.js or RingoJS
16630     if (moduleExports) {
16631       (freeModule.exports = _)._ = _;
16632     }
16633     // in Narwhal or Rhino -require
16634     else {
16635       freeExports._ = _;
16636     }
16637   }
16638   else {
16639     // in a browser or Rhino
16640     root._ = _;
16641   }
16642 }.call(this));
16643
16644 /* ===================================================
16645  * bootstrap-transition.js v2.3.2
16646  * http://twitter.github.com/bootstrap/javascript.html#transitions
16647  * ===================================================
16648  * Copyright 2012 Twitter, Inc.
16649  *
16650  * Licensed under the Apache License, Version 2.0 (the "License");
16651  * you may not use this file except in compliance with the License.
16652  * You may obtain a copy of the License at
16653  *
16654  * http://www.apache.org/licenses/LICENSE-2.0
16655  *
16656  * Unless required by applicable law or agreed to in writing, software
16657  * distributed under the License is distributed on an "AS IS" BASIS,
16658  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16659  * See the License for the specific language governing permissions and
16660  * limitations under the License.
16661  * ========================================================== */
16662
16663
16664 !function ($) {
16665
16666   "use strict"; // jshint ;_;
16667
16668
16669   /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
16670    * ======================================================= */
16671
16672   $(function () {
16673
16674     $.support.transition = (function () {
16675
16676       var transitionEnd = (function () {
16677
16678         var el = document.createElement('bootstrap')
16679           , transEndEventNames = {
16680                'WebkitTransition' : 'webkitTransitionEnd'
16681             ,  'MozTransition'    : 'transitionend'
16682             ,  'OTransition'      : 'oTransitionEnd otransitionend'
16683             ,  'transition'       : 'transitionend'
16684             }
16685           , name
16686
16687         for (name in transEndEventNames){
16688           if (el.style[name] !== undefined) {
16689             return transEndEventNames[name]
16690           }
16691         }
16692
16693       }())
16694
16695       return transitionEnd && {
16696         end: transitionEnd
16697       }
16698
16699     })()
16700
16701   })
16702
16703 }(window.jQuery);
16704 /* ==========================================================
16705  * bootstrap-alert.js v2.3.2
16706  * http://twitter.github.com/bootstrap/javascript.html#alerts
16707  * ==========================================================
16708  * Copyright 2012 Twitter, Inc.
16709  *
16710  * Licensed under the Apache License, Version 2.0 (the "License");
16711  * you may not use this file except in compliance with the License.
16712  * You may obtain a copy of the License at
16713  *
16714  * http://www.apache.org/licenses/LICENSE-2.0
16715  *
16716  * Unless required by applicable law or agreed to in writing, software
16717  * distributed under the License is distributed on an "AS IS" BASIS,
16718  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16719  * See the License for the specific language governing permissions and
16720  * limitations under the License.
16721  * ========================================================== */
16722
16723
16724 !function ($) {
16725
16726   "use strict"; // jshint ;_;
16727
16728
16729  /* ALERT CLASS DEFINITION
16730   * ====================== */
16731
16732   var dismiss = '[data-dismiss="alert"]'
16733     , Alert = function (el) {
16734         $(el).on('click', dismiss, this.close)
16735       }
16736
16737   Alert.prototype.close = function (e) {
16738     var $this = $(this)
16739       , selector = $this.attr('data-target')
16740       , $parent
16741
16742     if (!selector) {
16743       selector = $this.attr('href')
16744       selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
16745     }
16746
16747     $parent = $(selector)
16748
16749     e && e.preventDefault()
16750
16751     $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
16752
16753     $parent.trigger(e = $.Event('close'))
16754
16755     if (e.isDefaultPrevented()) return
16756
16757     $parent.removeClass('in')
16758
16759     function removeElement() {
16760       $parent
16761         .trigger('closed')
16762         .remove()
16763     }
16764
16765     $.support.transition && $parent.hasClass('fade') ?
16766       $parent.on($.support.transition.end, removeElement) :
16767       removeElement()
16768   }
16769
16770
16771  /* ALERT PLUGIN DEFINITION
16772   * ======================= */
16773
16774   var old = $.fn.alert
16775
16776   $.fn.alert = function (option) {
16777     return this.each(function () {
16778       var $this = $(this)
16779         , data = $this.data('alert')
16780       if (!data) $this.data('alert', (data = new Alert(this)))
16781       if (typeof option == 'string') data[option].call($this)
16782     })
16783   }
16784
16785   $.fn.alert.Constructor = Alert
16786
16787
16788  /* ALERT NO CONFLICT
16789   * ================= */
16790
16791   $.fn.alert.noConflict = function () {
16792     $.fn.alert = old
16793     return this
16794   }
16795
16796
16797  /* ALERT DATA-API
16798   * ============== */
16799
16800   $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
16801
16802 }(window.jQuery);
16803 /* ============================================================
16804  * bootstrap-button.js v2.3.2
16805  * http://twitter.github.com/bootstrap/javascript.html#buttons
16806  * ============================================================
16807  * Copyright 2012 Twitter, Inc.
16808  *
16809  * Licensed under the Apache License, Version 2.0 (the "License");
16810  * you may not use this file except in compliance with the License.
16811  * You may obtain a copy of the License at
16812  *
16813  * http://www.apache.org/licenses/LICENSE-2.0
16814  *
16815  * Unless required by applicable law or agreed to in writing, software
16816  * distributed under the License is distributed on an "AS IS" BASIS,
16817  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16818  * See the License for the specific language governing permissions and
16819  * limitations under the License.
16820  * ============================================================ */
16821
16822
16823 !function ($) {
16824
16825   "use strict"; // jshint ;_;
16826
16827
16828  /* BUTTON PUBLIC CLASS DEFINITION
16829   * ============================== */
16830
16831   var Button = function (element, options) {
16832     this.$element = $(element)
16833     this.options = $.extend({}, $.fn.button.defaults, options)
16834   }
16835
16836   Button.prototype.setState = function (state) {
16837     var d = 'disabled'
16838       , $el = this.$element
16839       , data = $el.data()
16840       , val = $el.is('input') ? 'val' : 'html'
16841
16842     state = state + 'Text'
16843     data.resetText || $el.data('resetText', $el[val]())
16844
16845     $el[val](data[state] || this.options[state])
16846
16847     // push to event loop to allow forms to submit
16848     setTimeout(function () {
16849       state == 'loadingText' ?
16850         $el.addClass(d).attr(d, d) :
16851         $el.removeClass(d).removeAttr(d)
16852     }, 0)
16853   }
16854
16855   Button.prototype.toggle = function () {
16856     var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
16857
16858     $parent && $parent
16859       .find('.active')
16860       .removeClass('active')
16861
16862     this.$element.toggleClass('active')
16863   }
16864
16865
16866  /* BUTTON PLUGIN DEFINITION
16867   * ======================== */
16868
16869   var old = $.fn.button
16870
16871   $.fn.button = function (option) {
16872     return this.each(function () {
16873       var $this = $(this)
16874         , data = $this.data('button')
16875         , options = typeof option == 'object' && option
16876       if (!data) $this.data('button', (data = new Button(this, options)))
16877       if (option == 'toggle') data.toggle()
16878       else if (option) data.setState(option)
16879     })
16880   }
16881
16882   $.fn.button.defaults = {
16883     loadingText: 'loading...'
16884   }
16885
16886   $.fn.button.Constructor = Button
16887
16888
16889  /* BUTTON NO CONFLICT
16890   * ================== */
16891
16892   $.fn.button.noConflict = function () {
16893     $.fn.button = old
16894     return this
16895   }
16896
16897
16898  /* BUTTON DATA-API
16899   * =============== */
16900
16901   $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
16902     var $btn = $(e.target)
16903     if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
16904     $btn.button('toggle')
16905   })
16906
16907 }(window.jQuery);
16908 /* ==========================================================
16909  * bootstrap-carousel.js v2.3.2
16910  * http://twitter.github.com/bootstrap/javascript.html#carousel
16911  * ==========================================================
16912  * Copyright 2012 Twitter, Inc.
16913  *
16914  * Licensed under the Apache License, Version 2.0 (the "License");
16915  * you may not use this file except in compliance with the License.
16916  * You may obtain a copy of the License at
16917  *
16918  * http://www.apache.org/licenses/LICENSE-2.0
16919  *
16920  * Unless required by applicable law or agreed to in writing, software
16921  * distributed under the License is distributed on an "AS IS" BASIS,
16922  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16923  * See the License for the specific language governing permissions and
16924  * limitations under the License.
16925  * ========================================================== */
16926
16927
16928 !function ($) {
16929
16930   "use strict"; // jshint ;_;
16931
16932
16933  /* CAROUSEL CLASS DEFINITION
16934   * ========================= */
16935
16936   var Carousel = function (element, options) {
16937     this.$element = $(element)
16938     this.$indicators = this.$element.find('.carousel-indicators')
16939     this.options = options
16940     this.options.pause == 'hover' && this.$element
16941       .on('mouseenter', $.proxy(this.pause, this))
16942       .on('mouseleave', $.proxy(this.cycle, this))
16943   }
16944
16945   Carousel.prototype = {
16946
16947     cycle: function (e) {
16948       if (!e) this.paused = false
16949       if (this.interval) clearInterval(this.interval);
16950       this.options.interval
16951         && !this.paused
16952         && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
16953       return this
16954     }
16955
16956   , getActiveIndex: function () {
16957       this.$active = this.$element.find('.item.active')
16958       this.$items = this.$active.parent().children()
16959       return this.$items.index(this.$active)
16960     }
16961
16962   , to: function (pos) {
16963       var activeIndex = this.getActiveIndex()
16964         , that = this
16965
16966       if (pos > (this.$items.length - 1) || pos < 0) return
16967
16968       if (this.sliding) {
16969         return this.$element.one('slid', function () {
16970           that.to(pos)
16971         })
16972       }
16973
16974       if (activeIndex == pos) {
16975         return this.pause().cycle()
16976       }
16977
16978       return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
16979     }
16980
16981   , pause: function (e) {
16982       if (!e) this.paused = true
16983       if (this.$element.find('.next, .prev').length && $.support.transition.end) {
16984         this.$element.trigger($.support.transition.end)
16985         this.cycle(true)
16986       }
16987       clearInterval(this.interval)
16988       this.interval = null
16989       return this
16990     }
16991
16992   , next: function () {
16993       if (this.sliding) return
16994       return this.slide('next')
16995     }
16996
16997   , prev: function () {
16998       if (this.sliding) return
16999       return this.slide('prev')
17000     }
17001
17002   , slide: function (type, next) {
17003       var $active = this.$element.find('.item.active')
17004         , $next = next || $active[type]()
17005         , isCycling = this.interval
17006         , direction = type == 'next' ? 'left' : 'right'
17007         , fallback  = type == 'next' ? 'first' : 'last'
17008         , that = this
17009         , e
17010
17011       this.sliding = true
17012
17013       isCycling && this.pause()
17014
17015       $next = $next.length ? $next : this.$element.find('.item')[fallback]()
17016
17017       e = $.Event('slide', {
17018         relatedTarget: $next[0]
17019       , direction: direction
17020       })
17021
17022       if ($next.hasClass('active')) return
17023
17024       if (this.$indicators.length) {
17025         this.$indicators.find('.active').removeClass('active')
17026         this.$element.one('slid', function () {
17027           var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
17028           $nextIndicator && $nextIndicator.addClass('active')
17029         })
17030       }
17031
17032       if ($.support.transition && this.$element.hasClass('slide')) {
17033         this.$element.trigger(e)
17034         if (e.isDefaultPrevented()) return
17035         $next.addClass(type)
17036         $next[0].offsetWidth // force reflow
17037         $active.addClass(direction)
17038         $next.addClass(direction)
17039         this.$element.one($.support.transition.end, function () {
17040           $next.removeClass([type, direction].join(' ')).addClass('active')
17041           $active.removeClass(['active', direction].join(' '))
17042           that.sliding = false
17043           setTimeout(function () { that.$element.trigger('slid') }, 0)
17044         })
17045       } else {
17046         this.$element.trigger(e)
17047         if (e.isDefaultPrevented()) return
17048         $active.removeClass('active')
17049         $next.addClass('active')
17050         this.sliding = false
17051         this.$element.trigger('slid')
17052       }
17053
17054       isCycling && this.cycle()
17055
17056       return this
17057     }
17058
17059   }
17060
17061
17062  /* CAROUSEL PLUGIN DEFINITION
17063   * ========================== */
17064
17065   var old = $.fn.carousel
17066
17067   $.fn.carousel = function (option) {
17068     return this.each(function () {
17069       var $this = $(this)
17070         , data = $this.data('carousel')
17071         , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
17072         , action = typeof option == 'string' ? option : options.slide
17073       if (!data) $this.data('carousel', (data = new Carousel(this, options)))
17074       if (typeof option == 'number') data.to(option)
17075       else if (action) data[action]()
17076       else if (options.interval) data.pause().cycle()
17077     })
17078   }
17079
17080   $.fn.carousel.defaults = {
17081     interval: 5000
17082   , pause: 'hover'
17083   }
17084
17085   $.fn.carousel.Constructor = Carousel
17086
17087
17088  /* CAROUSEL NO CONFLICT
17089   * ==================== */
17090
17091   $.fn.carousel.noConflict = function () {
17092     $.fn.carousel = old
17093     return this
17094   }
17095
17096  /* CAROUSEL DATA-API
17097   * ================= */
17098
17099   $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
17100     var $this = $(this), href
17101       , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
17102       , options = $.extend({}, $target.data(), $this.data())
17103       , slideIndex
17104
17105     $target.carousel(options)
17106
17107     if (slideIndex = $this.attr('data-slide-to')) {
17108       $target.data('carousel').pause().to(slideIndex).cycle()
17109     }
17110
17111     e.preventDefault()
17112   })
17113
17114 }(window.jQuery);
17115 /* =============================================================
17116  * bootstrap-collapse.js v2.3.2
17117  * http://twitter.github.com/bootstrap/javascript.html#collapse
17118  * =============================================================
17119  * Copyright 2012 Twitter, Inc.
17120  *
17121  * Licensed under the Apache License, Version 2.0 (the "License");
17122  * you may not use this file except in compliance with the License.
17123  * You may obtain a copy of the License at
17124  *
17125  * http://www.apache.org/licenses/LICENSE-2.0
17126  *
17127  * Unless required by applicable law or agreed to in writing, software
17128  * distributed under the License is distributed on an "AS IS" BASIS,
17129  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17130  * See the License for the specific language governing permissions and
17131  * limitations under the License.
17132  * ============================================================ */
17133
17134
17135 !function ($) {
17136
17137   "use strict"; // jshint ;_;
17138
17139
17140  /* COLLAPSE PUBLIC CLASS DEFINITION
17141   * ================================ */
17142
17143   var Collapse = function (element, options) {
17144     this.$element = $(element)
17145     this.options = $.extend({}, $.fn.collapse.defaults, options)
17146
17147     if (this.options.parent) {
17148       this.$parent = $(this.options.parent)
17149     }
17150
17151     this.options.toggle && this.toggle()
17152   }
17153
17154   Collapse.prototype = {
17155
17156     constructor: Collapse
17157
17158   , dimension: function () {
17159       var hasWidth = this.$element.hasClass('width')
17160       return hasWidth ? 'width' : 'height'
17161     }
17162
17163   , show: function () {
17164       var dimension
17165         , scroll
17166         , actives
17167         , hasData
17168
17169       if (this.transitioning || this.$element.hasClass('in')) return
17170
17171       dimension = this.dimension()
17172       scroll = $.camelCase(['scroll', dimension].join('-'))
17173       actives = this.$parent && this.$parent.find('> .accordion-group > .in')
17174
17175       if (actives && actives.length) {
17176         hasData = actives.data('collapse')
17177         if (hasData && hasData.transitioning) return
17178         actives.collapse('hide')
17179         hasData || actives.data('collapse', null)
17180       }
17181
17182       this.$element[dimension](0)
17183       this.transition('addClass', $.Event('show'), 'shown')
17184       $.support.transition && this.$element[dimension](this.$element[0][scroll])
17185     }
17186
17187   , hide: function () {
17188       var dimension
17189       if (this.transitioning || !this.$element.hasClass('in')) return
17190       dimension = this.dimension()
17191       this.reset(this.$element[dimension]())
17192       this.transition('removeClass', $.Event('hide'), 'hidden')
17193       this.$element[dimension](0)
17194     }
17195
17196   , reset: function (size) {
17197       var dimension = this.dimension()
17198
17199       this.$element
17200         .removeClass('collapse')
17201         [dimension](size || 'auto')
17202         [0].offsetWidth
17203
17204       this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
17205
17206       return this
17207     }
17208
17209   , transition: function (method, startEvent, completeEvent) {
17210       var that = this
17211         , complete = function () {
17212             if (startEvent.type == 'show') that.reset()
17213             that.transitioning = 0
17214             that.$element.trigger(completeEvent)
17215           }
17216
17217       this.$element.trigger(startEvent)
17218
17219       if (startEvent.isDefaultPrevented()) return
17220
17221       this.transitioning = 1
17222
17223       this.$element[method]('in')
17224
17225       $.support.transition && this.$element.hasClass('collapse') ?
17226         this.$element.one($.support.transition.end, complete) :
17227         complete()
17228     }
17229
17230   , toggle: function () {
17231       this[this.$element.hasClass('in') ? 'hide' : 'show']()
17232     }
17233
17234   }
17235
17236
17237  /* COLLAPSE PLUGIN DEFINITION
17238   * ========================== */
17239
17240   var old = $.fn.collapse
17241
17242   $.fn.collapse = function (option) {
17243     return this.each(function () {
17244       var $this = $(this)
17245         , data = $this.data('collapse')
17246         , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)
17247       if (!data) $this.data('collapse', (data = new Collapse(this, options)))
17248       if (typeof option == 'string') data[option]()
17249     })
17250   }
17251
17252   $.fn.collapse.defaults = {
17253     toggle: true
17254   }
17255
17256   $.fn.collapse.Constructor = Collapse
17257
17258
17259  /* COLLAPSE NO CONFLICT
17260   * ==================== */
17261
17262   $.fn.collapse.noConflict = function () {
17263     $.fn.collapse = old
17264     return this
17265   }
17266
17267
17268  /* COLLAPSE DATA-API
17269   * ================= */
17270
17271   $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
17272     var $this = $(this), href
17273       , target = $this.attr('data-target')
17274         || e.preventDefault()
17275         || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
17276       , option = $(target).data('collapse') ? 'toggle' : $this.data()
17277     $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
17278     $(target).collapse(option)
17279   })
17280
17281 }(window.jQuery);
17282 /* ============================================================
17283  * bootstrap-dropdown.js v2.3.2
17284  * http://twitter.github.com/bootstrap/javascript.html#dropdowns
17285  * ============================================================
17286  * Copyright 2012 Twitter, Inc.
17287  *
17288  * Licensed under the Apache License, Version 2.0 (the "License");
17289  * you may not use this file except in compliance with the License.
17290  * You may obtain a copy of the License at
17291  *
17292  * http://www.apache.org/licenses/LICENSE-2.0
17293  *
17294  * Unless required by applicable law or agreed to in writing, software
17295  * distributed under the License is distributed on an "AS IS" BASIS,
17296  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17297  * See the License for the specific language governing permissions and
17298  * limitations under the License.
17299  * ============================================================ */
17300
17301
17302 !function ($) {
17303
17304   "use strict"; // jshint ;_;
17305
17306
17307  /* DROPDOWN CLASS DEFINITION
17308   * ========================= */
17309
17310   var toggle = '[data-toggle=dropdown]'
17311     , Dropdown = function (element) {
17312         var $el = $(element).on('click.dropdown.data-api', this.toggle)
17313         $('html').on('click.dropdown.data-api', function () {
17314           $el.parent().removeClass('open')
17315         })
17316       }
17317
17318   Dropdown.prototype = {
17319
17320     constructor: Dropdown
17321
17322   , toggle: function (e) {
17323       var $this = $(this)
17324         , $parent
17325         , isActive
17326
17327       if ($this.is('.disabled, :disabled')) return
17328
17329       $parent = getParent($this)
17330
17331       isActive = $parent.hasClass('open')
17332
17333       clearMenus()
17334
17335       if (!isActive) {
17336         if ('ontouchstart' in document.documentElement) {
17337           // if mobile we we use a backdrop because click events don't delegate
17338           $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
17339         }
17340         $parent.toggleClass('open')
17341       }
17342
17343       $this.focus()
17344
17345       return false
17346     }
17347
17348   , keydown: function (e) {
17349       var $this
17350         , $items
17351         , $active
17352         , $parent
17353         , isActive
17354         , index
17355
17356       if (!/(38|40|27)/.test(e.keyCode)) return
17357
17358       $this = $(this)
17359
17360       e.preventDefault()
17361       e.stopPropagation()
17362
17363       if ($this.is('.disabled, :disabled')) return
17364
17365       $parent = getParent($this)
17366
17367       isActive = $parent.hasClass('open')
17368
17369       if (!isActive || (isActive && e.keyCode == 27)) {
17370         if (e.which == 27) $parent.find(toggle).focus()
17371         return $this.click()
17372       }
17373
17374       $items = $('[role=menu] li:not(.divider):visible a', $parent)
17375
17376       if (!$items.length) return
17377
17378       index = $items.index($items.filter(':focus'))
17379
17380       if (e.keyCode == 38 && index > 0) index--                                        // up
17381       if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
17382       if (!~index) index = 0
17383
17384       $items
17385         .eq(index)
17386         .focus()
17387     }
17388
17389   }
17390
17391   function clearMenus() {
17392     $('.dropdown-backdrop').remove()
17393     $(toggle).each(function () {
17394       getParent($(this)).removeClass('open')
17395     })
17396   }
17397
17398   function getParent($this) {
17399     var selector = $this.attr('data-target')
17400       , $parent
17401
17402     if (!selector) {
17403       selector = $this.attr('href')
17404       selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
17405     }
17406
17407     $parent = selector && $(selector)
17408
17409     if (!$parent || !$parent.length) $parent = $this.parent()
17410
17411     return $parent
17412   }
17413
17414
17415   /* DROPDOWN PLUGIN DEFINITION
17416    * ========================== */
17417
17418   var old = $.fn.dropdown
17419
17420   $.fn.dropdown = function (option) {
17421     return this.each(function () {
17422       var $this = $(this)
17423         , data = $this.data('dropdown')
17424       if (!data) $this.data('dropdown', (data = new Dropdown(this)))
17425       if (typeof option == 'string') data[option].call($this)
17426     })
17427   }
17428
17429   $.fn.dropdown.Constructor = Dropdown
17430
17431
17432  /* DROPDOWN NO CONFLICT
17433   * ==================== */
17434
17435   $.fn.dropdown.noConflict = function () {
17436     $.fn.dropdown = old
17437     return this
17438   }
17439
17440
17441   /* APPLY TO STANDARD DROPDOWN ELEMENTS
17442    * =================================== */
17443
17444   $(document)
17445     .on('click.dropdown.data-api', clearMenus)
17446     .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
17447     .on('click.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)
17448     .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
17449
17450 }(window.jQuery);
17451
17452 /* =========================================================
17453  * bootstrap-modal.js v2.3.2
17454  * http://twitter.github.com/bootstrap/javascript.html#modals
17455  * =========================================================
17456  * Copyright 2012 Twitter, Inc.
17457  *
17458  * Licensed under the Apache License, Version 2.0 (the "License");
17459  * you may not use this file except in compliance with the License.
17460  * You may obtain a copy of the License at
17461  *
17462  * http://www.apache.org/licenses/LICENSE-2.0
17463  *
17464  * Unless required by applicable law or agreed to in writing, software
17465  * distributed under the License is distributed on an "AS IS" BASIS,
17466  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17467  * See the License for the specific language governing permissions and
17468  * limitations under the License.
17469  * ========================================================= */
17470
17471
17472 !function ($) {
17473
17474   "use strict"; // jshint ;_;
17475
17476
17477  /* MODAL CLASS DEFINITION
17478   * ====================== */
17479
17480   var Modal = function (element, options) {
17481     this.options = options
17482     this.$element = $(element)
17483       .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
17484     this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
17485   }
17486
17487   Modal.prototype = {
17488
17489       constructor: Modal
17490
17491     , toggle: function () {
17492         return this[!this.isShown ? 'show' : 'hide']()
17493       }
17494
17495     , show: function () {
17496         var that = this
17497           , e = $.Event('show')
17498
17499         this.$element.trigger(e)
17500
17501         if (this.isShown || e.isDefaultPrevented()) return
17502
17503         this.isShown = true
17504
17505         this.escape()
17506
17507         this.backdrop(function () {
17508           var transition = $.support.transition && that.$element.hasClass('fade')
17509
17510           if (!that.$element.parent().length) {
17511             that.$element.appendTo(document.body) //don't move modals dom position
17512           }
17513
17514           that.$element.show()
17515
17516           if (transition) {
17517             that.$element[0].offsetWidth // force reflow
17518           }
17519
17520           that.$element
17521             .addClass('in')
17522             .attr('aria-hidden', false)
17523
17524           that.enforceFocus()
17525
17526           transition ?
17527             that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
17528             that.$element.focus().trigger('shown')
17529
17530         })
17531       }
17532
17533     , hide: function (e) {
17534         e && e.preventDefault()
17535
17536         var that = this
17537
17538         e = $.Event('hide')
17539
17540         this.$element.trigger(e)
17541
17542         if (!this.isShown || e.isDefaultPrevented()) return
17543
17544         this.isShown = false
17545
17546         this.escape()
17547
17548         $(document).off('focusin.modal')
17549
17550         this.$element
17551           .removeClass('in')
17552           .attr('aria-hidden', true)
17553
17554         $.support.transition && this.$element.hasClass('fade') ?
17555           this.hideWithTransition() :
17556           this.hideModal()
17557       }
17558
17559     , enforceFocus: function () {
17560         var that = this
17561         $(document).on('focusin.modal', function (e) {
17562           if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
17563             that.$element.focus()
17564           }
17565         })
17566       }
17567
17568     , escape: function () {
17569         var that = this
17570         if (this.isShown && this.options.keyboard) {
17571           this.$element.on('keyup.dismiss.modal', function ( e ) {
17572             e.which == 27 && that.hide()
17573           })
17574         } else if (!this.isShown) {
17575           this.$element.off('keyup.dismiss.modal')
17576         }
17577       }
17578
17579     , hideWithTransition: function () {
17580         var that = this
17581           , timeout = setTimeout(function () {
17582               that.$element.off($.support.transition.end)
17583               that.hideModal()
17584             }, 500)
17585
17586         this.$element.one($.support.transition.end, function () {
17587           clearTimeout(timeout)
17588           that.hideModal()
17589         })
17590       }
17591
17592     , hideModal: function () {
17593         var that = this
17594         this.$element.hide()
17595         this.backdrop(function () {
17596           that.removeBackdrop()
17597           that.$element.trigger('hidden')
17598         })
17599       }
17600
17601     , removeBackdrop: function () {
17602         this.$backdrop && this.$backdrop.remove()
17603         this.$backdrop = null
17604       }
17605
17606     , backdrop: function (callback) {
17607         var that = this
17608           , animate = this.$element.hasClass('fade') ? 'fade' : ''
17609
17610         if (this.isShown && this.options.backdrop) {
17611           var doAnimate = $.support.transition && animate
17612
17613           this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
17614             .appendTo(document.body)
17615
17616           this.$backdrop.click(
17617             this.options.backdrop == 'static' ?
17618               $.proxy(this.$element[0].focus, this.$element[0])
17619             : $.proxy(this.hide, this)
17620           )
17621
17622           if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
17623
17624           this.$backdrop.addClass('in')
17625
17626           if (!callback) return
17627
17628           doAnimate ?
17629             this.$backdrop.one($.support.transition.end, callback) :
17630             callback()
17631
17632         } else if (!this.isShown && this.$backdrop) {
17633           this.$backdrop.removeClass('in')
17634
17635           $.support.transition && this.$element.hasClass('fade')?
17636             this.$backdrop.one($.support.transition.end, callback) :
17637             callback()
17638
17639         } else if (callback) {
17640           callback()
17641         }
17642       }
17643   }
17644
17645
17646  /* MODAL PLUGIN DEFINITION
17647   * ======================= */
17648
17649   var old = $.fn.modal
17650
17651   $.fn.modal = function (option) {
17652     return this.each(function () {
17653       var $this = $(this)
17654         , data = $this.data('modal')
17655         , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
17656       if (!data) $this.data('modal', (data = new Modal(this, options)))
17657       if (typeof option == 'string') data[option]()
17658       else if (options.show) data.show()
17659     })
17660   }
17661
17662   $.fn.modal.defaults = {
17663       backdrop: true
17664     , keyboard: true
17665     , show: true
17666   }
17667
17668   $.fn.modal.Constructor = Modal
17669
17670
17671  /* MODAL NO CONFLICT
17672   * ================= */
17673
17674   $.fn.modal.noConflict = function () {
17675     $.fn.modal = old
17676     return this
17677   }
17678
17679
17680  /* MODAL DATA-API
17681   * ============== */
17682
17683   $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
17684     var $this = $(this)
17685       , href = $this.attr('href')
17686       , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
17687       , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
17688
17689     e.preventDefault()
17690
17691     $target
17692       .modal(option)
17693       .one('hide', function () {
17694         $this.focus()
17695       })
17696   })
17697
17698 }(window.jQuery);
17699
17700 /* ===========================================================
17701  * bootstrap-tooltip.js v2.3.2
17702  * http://twitter.github.com/bootstrap/javascript.html#tooltips
17703  * Inspired by the original jQuery.tipsy by Jason Frame
17704  * ===========================================================
17705  * Copyright 2012 Twitter, Inc.
17706  *
17707  * Licensed under the Apache License, Version 2.0 (the "License");
17708  * you may not use this file except in compliance with the License.
17709  * You may obtain a copy of the License at
17710  *
17711  * http://www.apache.org/licenses/LICENSE-2.0
17712  *
17713  * Unless required by applicable law or agreed to in writing, software
17714  * distributed under the License is distributed on an "AS IS" BASIS,
17715  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17716  * See the License for the specific language governing permissions and
17717  * limitations under the License.
17718  * ========================================================== */
17719
17720
17721 !function ($) {
17722
17723   "use strict"; // jshint ;_;
17724
17725
17726  /* TOOLTIP PUBLIC CLASS DEFINITION
17727   * =============================== */
17728
17729   var Tooltip = function (element, options) {
17730     this.init('tooltip', element, options)
17731   }
17732
17733   Tooltip.prototype = {
17734
17735     constructor: Tooltip
17736
17737   , init: function (type, element, options) {
17738       var eventIn
17739         , eventOut
17740         , triggers
17741         , trigger
17742         , i
17743
17744       this.type = type
17745       this.$element = $(element)
17746       this.options = this.getOptions(options)
17747       this.enabled = true
17748
17749       triggers = this.options.trigger.split(' ')
17750
17751       for (i = triggers.length; i--;) {
17752         trigger = triggers[i]
17753         if (trigger == 'click') {
17754           this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
17755         } else if (trigger != 'manual') {
17756           eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
17757           eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
17758           this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
17759           this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
17760         }
17761       }
17762
17763       this.options.selector ?
17764         (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
17765         this.fixTitle()
17766     }
17767
17768   , getOptions: function (options) {
17769       options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
17770
17771       if (options.delay && typeof options.delay == 'number') {
17772         options.delay = {
17773           show: options.delay
17774         , hide: options.delay
17775         }
17776       }
17777
17778       return options
17779     }
17780
17781   , enter: function (e) {
17782       var defaults = $.fn[this.type].defaults
17783         , options = {}
17784         , self
17785
17786       this._options && $.each(this._options, function (key, value) {
17787         if (defaults[key] != value) options[key] = value
17788       }, this)
17789
17790       self = $(e.currentTarget)[this.type](options).data(this.type)
17791
17792       if (!self.options.delay || !self.options.delay.show) return self.show()
17793
17794       clearTimeout(this.timeout)
17795       self.hoverState = 'in'
17796       this.timeout = setTimeout(function() {
17797         if (self.hoverState == 'in') self.show()
17798       }, self.options.delay.show)
17799     }
17800
17801   , leave: function (e) {
17802       var self = $(e.currentTarget)[this.type](this._options).data(this.type)
17803
17804       if (this.timeout) clearTimeout(this.timeout)
17805       if (!self.options.delay || !self.options.delay.hide) return self.hide()
17806
17807       self.hoverState = 'out'
17808       this.timeout = setTimeout(function() {
17809         if (self.hoverState == 'out') self.hide()
17810       }, self.options.delay.hide)
17811     }
17812
17813   , show: function () {
17814       var $tip
17815         , pos
17816         , actualWidth
17817         , actualHeight
17818         , placement
17819         , tp
17820         , e = $.Event('show')
17821
17822       if (this.hasContent() && this.enabled) {
17823         this.$element.trigger(e)
17824         if (e.isDefaultPrevented()) return
17825         $tip = this.tip()
17826         this.setContent()
17827
17828         if (this.options.animation) {
17829           $tip.addClass('fade')
17830         }
17831
17832         placement = typeof this.options.placement == 'function' ?
17833           this.options.placement.call(this, $tip[0], this.$element[0]) :
17834           this.options.placement
17835
17836         $tip
17837           .detach()
17838           .css({ top: 0, left: 0, display: 'block' })
17839
17840         this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
17841
17842         pos = this.getPosition()
17843
17844         actualWidth = $tip[0].offsetWidth
17845         actualHeight = $tip[0].offsetHeight
17846
17847         switch (placement) {
17848           case 'bottom':
17849             tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
17850             break
17851           case 'top':
17852             tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
17853             break
17854           case 'left':
17855             tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
17856             break
17857           case 'right':
17858             tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
17859             break
17860         }
17861
17862         this.applyPlacement(tp, placement)
17863         this.$element.trigger('shown')
17864       }
17865     }
17866
17867   , applyPlacement: function(offset, placement){
17868       var $tip = this.tip()
17869         , width = $tip[0].offsetWidth
17870         , height = $tip[0].offsetHeight
17871         , actualWidth
17872         , actualHeight
17873         , delta
17874         , replace
17875
17876       $tip
17877         .offset(offset)
17878         .addClass(placement)
17879         .addClass('in')
17880
17881       actualWidth = $tip[0].offsetWidth
17882       actualHeight = $tip[0].offsetHeight
17883
17884       if (placement == 'top' && actualHeight != height) {
17885         offset.top = offset.top + height - actualHeight
17886         replace = true
17887       }
17888
17889       if (placement == 'bottom' || placement == 'top') {
17890         delta = 0
17891
17892         if (offset.left < 0){
17893           delta = offset.left * -2
17894           offset.left = 0
17895           $tip.offset(offset)
17896           actualWidth = $tip[0].offsetWidth
17897           actualHeight = $tip[0].offsetHeight
17898         }
17899
17900         this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
17901       } else {
17902         this.replaceArrow(actualHeight - height, actualHeight, 'top')
17903       }
17904
17905       if (replace) $tip.offset(offset)
17906     }
17907
17908   , replaceArrow: function(delta, dimension, position){
17909       this
17910         .arrow()
17911         .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
17912     }
17913
17914   , setContent: function () {
17915       var $tip = this.tip()
17916         , title = this.getTitle()
17917
17918       $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
17919       $tip.removeClass('fade in top bottom left right')
17920     }
17921
17922   , hide: function () {
17923       var that = this
17924         , $tip = this.tip()
17925         , e = $.Event('hide')
17926
17927       this.$element.trigger(e)
17928       if (e.isDefaultPrevented()) return
17929
17930       $tip.removeClass('in')
17931
17932       function removeWithAnimation() {
17933         var timeout = setTimeout(function () {
17934           $tip.off($.support.transition.end).detach()
17935         }, 500)
17936
17937         $tip.one($.support.transition.end, function () {
17938           clearTimeout(timeout)
17939           $tip.detach()
17940         })
17941       }
17942
17943       $.support.transition && this.$tip.hasClass('fade') ?
17944         removeWithAnimation() :
17945         $tip.detach()
17946
17947       this.$element.trigger('hidden')
17948
17949       return this
17950     }
17951
17952   , fixTitle: function () {
17953       var $e = this.$element
17954       if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
17955         $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
17956       }
17957     }
17958
17959   , hasContent: function () {
17960       return this.getTitle()
17961     }
17962
17963   , getPosition: function () {
17964       var el = this.$element[0]
17965       return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
17966         width: el.offsetWidth
17967       , height: el.offsetHeight
17968       }, this.$element.offset())
17969     }
17970
17971   , getTitle: function () {
17972       var title
17973         , $e = this.$element
17974         , o = this.options
17975
17976       title = $e.attr('data-original-title')
17977         || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
17978
17979       return title
17980     }
17981
17982   , tip: function () {
17983       return this.$tip = this.$tip || $(this.options.template)
17984     }
17985
17986   , arrow: function(){
17987       return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
17988     }
17989
17990   , validate: function () {
17991       if (!this.$element[0].parentNode) {
17992         this.hide()
17993         this.$element = null
17994         this.options = null
17995       }
17996     }
17997
17998   , enable: function () {
17999       this.enabled = true
18000     }
18001
18002   , disable: function () {
18003       this.enabled = false
18004     }
18005
18006   , toggleEnabled: function () {
18007       this.enabled = !this.enabled
18008     }
18009
18010   , toggle: function (e) {
18011       var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
18012       self.tip().hasClass('in') ? self.hide() : self.show()
18013     }
18014
18015   , destroy: function () {
18016       this.hide().$element.off('.' + this.type).removeData(this.type)
18017     }
18018
18019   }
18020
18021
18022  /* TOOLTIP PLUGIN DEFINITION
18023   * ========================= */
18024
18025   var old = $.fn.tooltip
18026
18027   $.fn.tooltip = function ( option ) {
18028     return this.each(function () {
18029       var $this = $(this)
18030         , data = $this.data('tooltip')
18031         , options = typeof option == 'object' && option
18032       if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
18033       if (typeof option == 'string') data[option]()
18034     })
18035   }
18036
18037   $.fn.tooltip.Constructor = Tooltip
18038
18039   $.fn.tooltip.defaults = {
18040     animation: true
18041   , placement: 'top'
18042   , selector: false
18043   , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
18044   , trigger: 'hover focus'
18045   , title: ''
18046   , delay: 0
18047   , html: false
18048   , container: false
18049   }
18050
18051
18052  /* TOOLTIP NO CONFLICT
18053   * =================== */
18054
18055   $.fn.tooltip.noConflict = function () {
18056     $.fn.tooltip = old
18057     return this
18058   }
18059
18060 }(window.jQuery);
18061
18062 /* ===========================================================
18063  * bootstrap-popover.js v2.3.2
18064  * http://twitter.github.com/bootstrap/javascript.html#popovers
18065  * ===========================================================
18066  * Copyright 2012 Twitter, Inc.
18067  *
18068  * Licensed under the Apache License, Version 2.0 (the "License");
18069  * you may not use this file except in compliance with the License.
18070  * You may obtain a copy of the License at
18071  *
18072  * http://www.apache.org/licenses/LICENSE-2.0
18073  *
18074  * Unless required by applicable law or agreed to in writing, software
18075  * distributed under the License is distributed on an "AS IS" BASIS,
18076  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18077  * See the License for the specific language governing permissions and
18078  * limitations under the License.
18079  * =========================================================== */
18080
18081
18082 !function ($) {
18083
18084   "use strict"; // jshint ;_;
18085
18086
18087  /* POPOVER PUBLIC CLASS DEFINITION
18088   * =============================== */
18089
18090   var Popover = function (element, options) {
18091     this.init('popover', element, options)
18092   }
18093
18094
18095   /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
18096      ========================================== */
18097
18098   Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
18099
18100     constructor: Popover
18101
18102   , setContent: function () {
18103       var $tip = this.tip()
18104         , title = this.getTitle()
18105         , content = this.getContent()
18106
18107       $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
18108       $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
18109
18110       $tip.removeClass('fade top bottom left right in')
18111     }
18112
18113   , hasContent: function () {
18114       return this.getTitle() || this.getContent()
18115     }
18116
18117   , getContent: function () {
18118       var content
18119         , $e = this.$element
18120         , o = this.options
18121
18122       content = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)
18123         || $e.attr('data-content')
18124
18125       return content
18126     }
18127
18128   , tip: function () {
18129       if (!this.$tip) {
18130         this.$tip = $(this.options.template)
18131       }
18132       return this.$tip
18133     }
18134
18135   , destroy: function () {
18136       this.hide().$element.off('.' + this.type).removeData(this.type)
18137     }
18138
18139   })
18140
18141
18142  /* POPOVER PLUGIN DEFINITION
18143   * ======================= */
18144
18145   var old = $.fn.popover
18146
18147   $.fn.popover = function (option) {
18148     return this.each(function () {
18149       var $this = $(this)
18150         , data = $this.data('popover')
18151         , options = typeof option == 'object' && option
18152       if (!data) $this.data('popover', (data = new Popover(this, options)))
18153       if (typeof option == 'string') data[option]()
18154     })
18155   }
18156
18157   $.fn.popover.Constructor = Popover
18158
18159   $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
18160     placement: 'right'
18161   , trigger: 'click'
18162   , content: ''
18163   , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
18164   })
18165
18166
18167  /* POPOVER NO CONFLICT
18168   * =================== */
18169
18170   $.fn.popover.noConflict = function () {
18171     $.fn.popover = old
18172     return this
18173   }
18174
18175 }(window.jQuery);
18176
18177 /* =============================================================
18178  * bootstrap-scrollspy.js v2.3.2
18179  * http://twitter.github.com/bootstrap/javascript.html#scrollspy
18180  * =============================================================
18181  * Copyright 2012 Twitter, Inc.
18182  *
18183  * Licensed under the Apache License, Version 2.0 (the "License");
18184  * you may not use this file except in compliance with the License.
18185  * You may obtain a copy of the License at
18186  *
18187  * http://www.apache.org/licenses/LICENSE-2.0
18188  *
18189  * Unless required by applicable law or agreed to in writing, software
18190  * distributed under the License is distributed on an "AS IS" BASIS,
18191  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18192  * See the License for the specific language governing permissions and
18193  * limitations under the License.
18194  * ============================================================== */
18195
18196
18197 !function ($) {
18198
18199   "use strict"; // jshint ;_;
18200
18201
18202  /* SCROLLSPY CLASS DEFINITION
18203   * ========================== */
18204
18205   function ScrollSpy(element, options) {
18206     var process = $.proxy(this.process, this)
18207       , $element = $(element).is('body') ? $(window) : $(element)
18208       , href
18209     this.options = $.extend({}, $.fn.scrollspy.defaults, options)
18210     this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
18211     this.selector = (this.options.target
18212       || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
18213       || '') + ' .nav li > a'
18214     this.$body = $('body')
18215     this.refresh()
18216     this.process()
18217   }
18218
18219   ScrollSpy.prototype = {
18220
18221       constructor: ScrollSpy
18222
18223     , refresh: function () {
18224         var self = this
18225           , $targets
18226
18227         this.offsets = $([])
18228         this.targets = $([])
18229
18230         $targets = this.$body
18231           .find(this.selector)
18232           .map(function () {
18233             var $el = $(this)
18234               , href = $el.data('target') || $el.attr('href')
18235               , $href = /^#\w/.test(href) && $(href)
18236             return ( $href
18237               && $href.length
18238               && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
18239           })
18240           .sort(function (a, b) { return a[0] - b[0] })
18241           .each(function () {
18242             self.offsets.push(this[0])
18243             self.targets.push(this[1])
18244           })
18245       }
18246
18247     , process: function () {
18248         var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
18249           , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
18250           , maxScroll = scrollHeight - this.$scrollElement.height()
18251           , offsets = this.offsets
18252           , targets = this.targets
18253           , activeTarget = this.activeTarget
18254           , i
18255
18256         if (scrollTop >= maxScroll) {
18257           return activeTarget != (i = targets.last()[0])
18258             && this.activate ( i )
18259         }
18260
18261         for (i = offsets.length; i--;) {
18262           activeTarget != targets[i]
18263             && scrollTop >= offsets[i]
18264             && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
18265             && this.activate( targets[i] )
18266         }
18267       }
18268
18269     , activate: function (target) {
18270         var active
18271           , selector
18272
18273         this.activeTarget = target
18274
18275         $(this.selector)
18276           .parent('.active')
18277           .removeClass('active')
18278
18279         selector = this.selector
18280           + '[data-target="' + target + '"],'
18281           + this.selector + '[href="' + target + '"]'
18282
18283         active = $(selector)
18284           .parent('li')
18285           .addClass('active')
18286
18287         if (active.parent('.dropdown-menu').length)  {
18288           active = active.closest('li.dropdown').addClass('active')
18289         }
18290
18291         active.trigger('activate')
18292       }
18293
18294   }
18295
18296
18297  /* SCROLLSPY PLUGIN DEFINITION
18298   * =========================== */
18299
18300   var old = $.fn.scrollspy
18301
18302   $.fn.scrollspy = function (option) {
18303     return this.each(function () {
18304       var $this = $(this)
18305         , data = $this.data('scrollspy')
18306         , options = typeof option == 'object' && option
18307       if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
18308       if (typeof option == 'string') data[option]()
18309     })
18310   }
18311
18312   $.fn.scrollspy.Constructor = ScrollSpy
18313
18314   $.fn.scrollspy.defaults = {
18315     offset: 10
18316   }
18317
18318
18319  /* SCROLLSPY NO CONFLICT
18320   * ===================== */
18321
18322   $.fn.scrollspy.noConflict = function () {
18323     $.fn.scrollspy = old
18324     return this
18325   }
18326
18327
18328  /* SCROLLSPY DATA-API
18329   * ================== */
18330
18331   $(window).on('load', function () {
18332     $('[data-spy="scroll"]').each(function () {
18333       var $spy = $(this)
18334       $spy.scrollspy($spy.data())
18335     })
18336   })
18337
18338 }(window.jQuery);
18339 /* ========================================================
18340  * bootstrap-tab.js v2.3.2
18341  * http://twitter.github.com/bootstrap/javascript.html#tabs
18342  * ========================================================
18343  * Copyright 2012 Twitter, Inc.
18344  *
18345  * Licensed under the Apache License, Version 2.0 (the "License");
18346  * you may not use this file except in compliance with the License.
18347  * You may obtain a copy of the License at
18348  *
18349  * http://www.apache.org/licenses/LICENSE-2.0
18350  *
18351  * Unless required by applicable law or agreed to in writing, software
18352  * distributed under the License is distributed on an "AS IS" BASIS,
18353  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18354  * See the License for the specific language governing permissions and
18355  * limitations under the License.
18356  * ======================================================== */
18357
18358
18359 !function ($) {
18360
18361   "use strict"; // jshint ;_;
18362
18363
18364  /* TAB CLASS DEFINITION
18365   * ==================== */
18366
18367   var Tab = function (element) {
18368     this.element = $(element)
18369   }
18370
18371   Tab.prototype = {
18372
18373     constructor: Tab
18374
18375   , show: function () {
18376       var $this = this.element
18377         , $ul = $this.closest('ul:not(.dropdown-menu)')
18378         , selector = $this.attr('data-target')
18379         , previous
18380         , $target
18381         , e
18382
18383       if (!selector) {
18384         selector = $this.attr('href')
18385         selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
18386       }
18387
18388       if ( $this.parent('li').hasClass('active') ) return
18389
18390       previous = $ul.find('.active:last a')[0]
18391
18392       e = $.Event('show', {
18393         relatedTarget: previous
18394       })
18395
18396       $this.trigger(e)
18397
18398       if (e.isDefaultPrevented()) return
18399
18400       $target = $(selector)
18401
18402       this.activate($this.parent('li'), $ul)
18403       this.activate($target, $target.parent(), function () {
18404         $this.trigger({
18405           type: 'shown'
18406         , relatedTarget: previous
18407         })
18408       })
18409     }
18410
18411   , activate: function ( element, container, callback) {
18412       var $active = container.find('> .active')
18413         , transition = callback
18414             && $.support.transition
18415             && $active.hasClass('fade')
18416
18417       function next() {
18418         $active
18419           .removeClass('active')
18420           .find('> .dropdown-menu > .active')
18421           .removeClass('active')
18422
18423         element.addClass('active')
18424
18425         if (transition) {
18426           element[0].offsetWidth // reflow for transition
18427           element.addClass('in')
18428         } else {
18429           element.removeClass('fade')
18430         }
18431
18432         if ( element.parent('.dropdown-menu') ) {
18433           element.closest('li.dropdown').addClass('active')
18434         }
18435
18436         callback && callback()
18437       }
18438
18439       transition ?
18440         $active.one($.support.transition.end, next) :
18441         next()
18442
18443       $active.removeClass('in')
18444     }
18445   }
18446
18447
18448  /* TAB PLUGIN DEFINITION
18449   * ===================== */
18450
18451   var old = $.fn.tab
18452
18453   $.fn.tab = function ( option ) {
18454     return this.each(function () {
18455       var $this = $(this)
18456         , data = $this.data('tab')
18457       if (!data) $this.data('tab', (data = new Tab(this)))
18458       if (typeof option == 'string') data[option]()
18459     })
18460   }
18461
18462   $.fn.tab.Constructor = Tab
18463
18464
18465  /* TAB NO CONFLICT
18466   * =============== */
18467
18468   $.fn.tab.noConflict = function () {
18469     $.fn.tab = old
18470     return this
18471   }
18472
18473
18474  /* TAB DATA-API
18475   * ============ */
18476
18477   $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
18478     e.preventDefault()
18479     $(this).tab('show')
18480   })
18481
18482 }(window.jQuery);
18483 /* =============================================================
18484  * bootstrap-typeahead.js v2.3.2
18485  * http://twitter.github.com/bootstrap/javascript.html#typeahead
18486  * =============================================================
18487  * Copyright 2012 Twitter, Inc.
18488  *
18489  * Licensed under the Apache License, Version 2.0 (the "License");
18490  * you may not use this file except in compliance with the License.
18491  * You may obtain a copy of the License at
18492  *
18493  * http://www.apache.org/licenses/LICENSE-2.0
18494  *
18495  * Unless required by applicable law or agreed to in writing, software
18496  * distributed under the License is distributed on an "AS IS" BASIS,
18497  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18498  * See the License for the specific language governing permissions and
18499  * limitations under the License.
18500  * ============================================================ */
18501
18502
18503 !function($){
18504
18505   "use strict"; // jshint ;_;
18506
18507
18508  /* TYPEAHEAD PUBLIC CLASS DEFINITION
18509   * ================================= */
18510
18511   var Typeahead = function (element, options) {
18512     this.$element = $(element)
18513     this.options = $.extend({}, $.fn.typeahead.defaults, options)
18514     this.matcher = this.options.matcher || this.matcher
18515     this.sorter = this.options.sorter || this.sorter
18516     this.highlighter = this.options.highlighter || this.highlighter
18517     this.updater = this.options.updater || this.updater
18518     this.source = this.options.source
18519     this.$menu = $(this.options.menu)
18520     this.shown = false
18521     this.listen()
18522   }
18523
18524   Typeahead.prototype = {
18525
18526     constructor: Typeahead
18527
18528   , select: function () {
18529       var val = this.$menu.find('.active').attr('data-value')
18530       this.$element
18531         .val(this.updater(val))
18532         .change()
18533       return this.hide()
18534     }
18535
18536   , updater: function (item) {
18537       return item
18538     }
18539
18540   , show: function () {
18541       var pos = $.extend({}, this.$element.position(), {
18542         height: this.$element[0].offsetHeight
18543       })
18544
18545       this.$menu
18546         .insertAfter(this.$element)
18547         .css({
18548           top: pos.top + pos.height
18549         , left: pos.left
18550         })
18551         .show()
18552
18553       this.shown = true
18554       return this
18555     }
18556
18557   , hide: function () {
18558       this.$menu.hide()
18559       this.shown = false
18560       return this
18561     }
18562
18563   , lookup: function (event) {
18564       var items
18565
18566       this.query = this.$element.val()
18567
18568       if (!this.query || this.query.length < this.options.minLength) {
18569         return this.shown ? this.hide() : this
18570       }
18571
18572       items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
18573
18574       return items ? this.process(items) : this
18575     }
18576
18577   , process: function (items) {
18578       var that = this
18579
18580       items = $.grep(items, function (item) {
18581         return that.matcher(item)
18582       })
18583
18584       items = this.sorter(items)
18585
18586       if (!items.length) {
18587         return this.shown ? this.hide() : this
18588       }
18589
18590       return this.render(items.slice(0, this.options.items)).show()
18591     }
18592
18593   , matcher: function (item) {
18594       return ~item.toLowerCase().indexOf(this.query.toLowerCase())
18595     }
18596
18597   , sorter: function (items) {
18598       var beginswith = []
18599         , caseSensitive = []
18600         , caseInsensitive = []
18601         , item
18602
18603       while (item = items.shift()) {
18604         if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
18605         else if (~item.indexOf(this.query)) caseSensitive.push(item)
18606         else caseInsensitive.push(item)
18607       }
18608
18609       return beginswith.concat(caseSensitive, caseInsensitive)
18610     }
18611
18612   , highlighter: function (item) {
18613       var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
18614       return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
18615         return '<strong>' + match + '</strong>'
18616       })
18617     }
18618
18619   , render: function (items) {
18620       var that = this
18621
18622       items = $(items).map(function (i, item) {
18623         i = $(that.options.item).attr('data-value', item)
18624         i.find('a').html(that.highlighter(item))
18625         return i[0]
18626       })
18627
18628       items.first().addClass('active')
18629       this.$menu.html(items)
18630       return this
18631     }
18632
18633   , next: function (event) {
18634       var active = this.$menu.find('.active').removeClass('active')
18635         , next = active.next()
18636
18637       if (!next.length) {
18638         next = $(this.$menu.find('li')[0])
18639       }
18640
18641       next.addClass('active')
18642     }
18643
18644   , prev: function (event) {
18645       var active = this.$menu.find('.active').removeClass('active')
18646         , prev = active.prev()
18647
18648       if (!prev.length) {
18649         prev = this.$menu.find('li').last()
18650       }
18651
18652       prev.addClass('active')
18653     }
18654
18655   , listen: function () {
18656       this.$element
18657         .on('focus',    $.proxy(this.focus, this))
18658         .on('blur',     $.proxy(this.blur, this))
18659         .on('keypress', $.proxy(this.keypress, this))
18660         .on('keyup',    $.proxy(this.keyup, this))
18661
18662       if (this.eventSupported('keydown')) {
18663         this.$element.on('keydown', $.proxy(this.keydown, this))
18664       }
18665
18666       this.$menu
18667         .on('click', $.proxy(this.click, this))
18668         .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
18669         .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
18670     }
18671
18672   , eventSupported: function(eventName) {
18673       var isSupported = eventName in this.$element
18674       if (!isSupported) {
18675         this.$element.setAttribute(eventName, 'return;')
18676         isSupported = typeof this.$element[eventName] === 'function'
18677       }
18678       return isSupported
18679     }
18680
18681   , move: function (e) {
18682       if (!this.shown) return
18683
18684       switch(e.keyCode) {
18685         case 9: // tab
18686         case 13: // enter
18687         case 27: // escape
18688           e.preventDefault()
18689           break
18690
18691         case 38: // up arrow
18692           e.preventDefault()
18693           this.prev()
18694           break
18695
18696         case 40: // down arrow
18697           e.preventDefault()
18698           this.next()
18699           break
18700       }
18701
18702       e.stopPropagation()
18703     }
18704
18705   , keydown: function (e) {
18706       this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
18707       this.move(e)
18708     }
18709
18710   , keypress: function (e) {
18711       if (this.suppressKeyPressRepeat) return
18712       this.move(e)
18713     }
18714
18715   , keyup: function (e) {
18716       switch(e.keyCode) {
18717         case 40: // down arrow
18718         case 38: // up arrow
18719         case 16: // shift
18720         case 17: // ctrl
18721         case 18: // alt
18722           break
18723
18724         case 9: // tab
18725         case 13: // enter
18726           if (!this.shown) return
18727           this.select()
18728           break
18729
18730         case 27: // escape
18731           if (!this.shown) return
18732           this.hide()
18733           break
18734
18735         default:
18736           this.lookup()
18737       }
18738
18739       e.stopPropagation()
18740       e.preventDefault()
18741   }
18742
18743   , focus: function (e) {
18744       this.focused = true
18745     }
18746
18747   , blur: function (e) {
18748       this.focused = false
18749       if (!this.mousedover && this.shown) this.hide()
18750     }
18751
18752   , click: function (e) {
18753       e.stopPropagation()
18754       e.preventDefault()
18755       this.select()
18756       this.$element.focus()
18757     }
18758
18759   , mouseenter: function (e) {
18760       this.mousedover = true
18761       this.$menu.find('.active').removeClass('active')
18762       $(e.currentTarget).addClass('active')
18763     }
18764
18765   , mouseleave: function (e) {
18766       this.mousedover = false
18767       if (!this.focused && this.shown) this.hide()
18768     }
18769
18770   }
18771
18772
18773   /* TYPEAHEAD PLUGIN DEFINITION
18774    * =========================== */
18775
18776   var old = $.fn.typeahead
18777
18778   $.fn.typeahead = function (option) {
18779     return this.each(function () {
18780       var $this = $(this)
18781         , data = $this.data('typeahead')
18782         , options = typeof option == 'object' && option
18783       if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
18784       if (typeof option == 'string') data[option]()
18785     })
18786   }
18787
18788   $.fn.typeahead.defaults = {
18789     source: []
18790   , items: 8
18791   , menu: '<ul class="typeahead dropdown-menu"></ul>'
18792   , item: '<li><a href="#"></a></li>'
18793   , minLength: 1
18794   }
18795
18796   $.fn.typeahead.Constructor = Typeahead
18797
18798
18799  /* TYPEAHEAD NO CONFLICT
18800   * =================== */
18801
18802   $.fn.typeahead.noConflict = function () {
18803     $.fn.typeahead = old
18804     return this
18805   }
18806
18807
18808  /* TYPEAHEAD DATA-API
18809   * ================== */
18810
18811   $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
18812     var $this = $(this)
18813     if ($this.data('typeahead')) return
18814     $this.typeahead($this.data())
18815   })
18816
18817 }(window.jQuery);
18818
18819 /* ==========================================================
18820  * bootstrap-affix.js v2.3.2
18821  * http://twitter.github.com/bootstrap/javascript.html#affix
18822  * ==========================================================
18823  * Copyright 2012 Twitter, Inc.
18824  *
18825  * Licensed under the Apache License, Version 2.0 (the "License");
18826  * you may not use this file except in compliance with the License.
18827  * You may obtain a copy of the License at
18828  *
18829  * http://www.apache.org/licenses/LICENSE-2.0
18830  *
18831  * Unless required by applicable law or agreed to in writing, software
18832  * distributed under the License is distributed on an "AS IS" BASIS,
18833  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18834  * See the License for the specific language governing permissions and
18835  * limitations under the License.
18836  * ========================================================== */
18837
18838
18839 !function ($) {
18840
18841   "use strict"; // jshint ;_;
18842
18843
18844  /* AFFIX CLASS DEFINITION
18845   * ====================== */
18846
18847   var Affix = function (element, options) {
18848     this.options = $.extend({}, $.fn.affix.defaults, options)
18849     this.$window = $(window)
18850       .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
18851       .on('click.affix.data-api',  $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
18852     this.$element = $(element)
18853     this.checkPosition()
18854   }
18855
18856   Affix.prototype.checkPosition = function () {
18857     if (!this.$element.is(':visible')) return
18858
18859     var scrollHeight = $(document).height()
18860       , scrollTop = this.$window.scrollTop()
18861       , position = this.$element.offset()
18862       , offset = this.options.offset
18863       , offsetBottom = offset.bottom
18864       , offsetTop = offset.top
18865       , reset = 'affix affix-top affix-bottom'
18866       , affix
18867
18868     if (typeof offset != 'object') offsetBottom = offsetTop = offset
18869     if (typeof offsetTop == 'function') offsetTop = offset.top()
18870     if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
18871
18872     affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
18873       false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
18874       'bottom' : offsetTop != null && scrollTop <= offsetTop ?
18875       'top'    : false
18876
18877     if (this.affixed === affix) return
18878
18879     this.affixed = affix
18880     this.unpin = affix == 'bottom' ? position.top - scrollTop : null
18881
18882     this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
18883   }
18884
18885
18886  /* AFFIX PLUGIN DEFINITION
18887   * ======================= */
18888
18889   var old = $.fn.affix
18890
18891   $.fn.affix = function (option) {
18892     return this.each(function () {
18893       var $this = $(this)
18894         , data = $this.data('affix')
18895         , options = typeof option == 'object' && option
18896       if (!data) $this.data('affix', (data = new Affix(this, options)))
18897       if (typeof option == 'string') data[option]()
18898     })
18899   }
18900
18901   $.fn.affix.Constructor = Affix
18902
18903   $.fn.affix.defaults = {
18904     offset: 0
18905   }
18906
18907
18908  /* AFFIX NO CONFLICT
18909   * ================= */
18910
18911   $.fn.affix.noConflict = function () {
18912     $.fn.affix = old
18913     return this
18914   }
18915
18916
18917  /* AFFIX DATA-API
18918   * ============== */
18919
18920   $(window).on('load', function () {
18921     $('[data-spy="affix"]').each(function () {
18922       var $spy = $(this)
18923         , data = $spy.data()
18924
18925       data.offset = data.offset || {}
18926
18927       data.offsetBottom && (data.offset.bottom = data.offsetBottom)
18928       data.offsetTop && (data.offset.top = data.offsetTop)
18929
18930       $spy.affix(data)
18931     })
18932   })
18933
18934
18935 }(window.jQuery);
18936 /*
18937  * Copyright (c) 2012, Intel Corporation.
18938  *
18939  * This program is licensed under the terms and conditions of the
18940  * Apache License, version 2.0.  The full text of the Apache License is at
18941  * http://www.apache.org/licenses/LICENSE-2.0
18942  *
18943  */
18944
18945 /*****************************************************************************
18946 * Class name: Vehicle
18947 * Description:
18948 *    A javascript implementation of the IVI vehicle API that communicates
18949 *    to the automotive message broker through a websocket
18950 * Optional constructor arguments:
18951 *    sCB: success callback, called when socket is connected, argument is
18952 *         success message string
18953 *    eCB: error callback, called on socket close or error, argument is error
18954 *         message string
18955 *    url: the URL to use for the websocket, in the form "ws://host:port/script"
18956 *    protocol: the protocol to use for the websocket, default is "http-only"
18957 *
18958 * [Public Member functions]
18959 *  Function name: getSupportedEventTypes(type, writeable, successCB, errorCB)
18960 *    Description:
18961 *        Retrieves a list of vehicle events for the requested type
18962 *    Required arguments:
18963 *        type: target event or group to query (use empty string for all events)
18964 *        writeable: if true, return only writeable events, otherwise get all
18965 *        successCB: success callback, gets called with a string list of names
18966 *              for all the events and event groups that are children of the
18967 *              target. e.g. "vehicle_info" returns all events/groups with the
18968 *              vehicle_info prefix. If the target is an event group, it's
18969 *              omitted from the returned list
18970 *        errorCB: error callback, called with error message string
18971 *
18972 *  Function name: get(eventlist, successCB, errorCB)
18973 *    Description:
18974 *        Retrieves a list of event/value pairs for a target list of event names
18975 *    Required arguments:
18976 *        eventlist[]: list of events to read (use empty string for all events)
18977 *        successCB: success callback, gets called with the event/value pair list
18978 *                   for all requested events. The list is the in the
18979 *                   form of data[n].name/data[n].value
18980 *        errorCB: error callback, called with error message string
18981 *
18982 *  Function name: set(eventlist, valuelist, successCB, errorCB)
18983 *    Description:
18984 *        Sets a gourp of event's values (triggers error on read-only events)
18985 *    Required arguments:
18986 *        eventlist: target events to set
18987 *        valuelist: target event values
18988 *        successCB: success callback, gets called with the eventlist
18989 *                   that was successfully set
18990 *        errorCB: error callback, called with error message string
18991 *
18992 *  Function name: subscribe(eventlist, successCB, errorCB)
18993 *    Description:
18994 *        Subscribe to a list of events so you can listen to value changes, they
18995 *        can be monitored with document.addEventListener(eventname, callback, false);
18996 *        The Event object passed to the callback has two parameters, e.name and
18997 *        e.value. Events are sent to the handler individually.
18998 *    Required arguments:
18999 *        eventlist: target events to listen to
19000 *        successCB: success callback, gets called with the eventlist
19001 *                   that was successfully subscribed
19002 *        errorCB: error callback, called with the eventlist that failed to subscribe
19003 *
19004 *  Function name: unsubscribe(eventlist, successCB, errorCB)
19005 *    Description:
19006 *        Unsubscribe to a list of events to let the server know you're not listening,
19007 *        they should stop being sent from the server if no other clients are using them,
19008 *        but will at least stop being triggered in your app.
19009 *    Required arguments:
19010 *        eventlist: target events to stop listening to
19011 *        successCB: success callback, gets called with the eventlist
19012 *                   that was successfully unsubscribed
19013 *        errorCB: error callback, called with the eventlist that failed to unsubscribe
19014 *
19015 ******************************************************************************/
19016
19017 (function (win) {
19018     function Vehicle(sCB, eCB, url, protocol)
19019     {
19020         /* store a copy of Vehicle this for reference in callbacks */
19021         var self = this;
19022
19023         this.iSuccessCB = sCB;
19024         this.iErrorCB = eCB;
19025
19026         /* variables for call management, supports up to 100 simultaneously */
19027         this.methodIdx = 0;
19028         this.methodCalls = [];
19029         for(var i = 0; i < 100; i++)
19030         {
19031             this.methodCalls[i] = null;
19032         }
19033
19034         /* number of connection retries to attempt if the socket closes */
19035         this.retries = 5;
19036         this.connected = false;
19037
19038         /* timeout for method calls in milliseconds */
19039         this.timeouttime = 5000;
19040
19041         /* default values for WebSocket */
19042         this.socketUrl = "ws://localhost:23000/vehicle";
19043         this.socketProtocol = "http-only";
19044
19045         /* override the websocket address if parameters are given */
19046         if(url !== undefined) this.socketUrl = url;
19047         if(protocol !== undefined) this.socketProtocol = protocol;
19048
19049         this.VehicleMethodCall = function(id, name, successCB, errorCB)
19050         {
19051             var me = this;
19052             this.successCB = successCB;
19053             this.errorCB = errorCB;
19054             this.transactionid = id;
19055             this.name = name;
19056             this.done = false;
19057             this.start = function()
19058             {
19059                 me.timeout = setTimeout(function(){
19060                     if(me.errorCB !== undefined)
19061                     {
19062                         me.errorCB("\""+me.name+"\" method timed out after "+self.timeouttime+"ms");
19063                     }
19064                     me.finish();
19065                 }, self.timeouttime);
19066             }
19067             this.finish = function()
19068             {
19069                 if(me.timeout !== undefined)
19070                 {
19071                     clearTimeout(me.timeout);
19072                 }
19073                 me.done = true;
19074             }
19075         }
19076
19077         function init() {
19078             if ("WebSocket" in win)
19079             {
19080                 if(self.socketProtocol.length > 0)
19081                 {
19082                     self.socket = new WebSocket(self.socketUrl, self.socketProtocol);
19083                 }
19084                 else
19085                 {
19086                     self.socket = new WebSocket(self.socketUrl);
19087                 }
19088                 self.socket.onopen = function()
19089                 {
19090                     self.connected = true;
19091                     self.iSuccessCB((self.retries < 5)?"(RECONNECTED)":"");
19092                     self.retries = 5;
19093                 };
19094                 self.socket.onclose = function()
19095                 {
19096                     self.connected = false;
19097                     self.iErrorCB("socket closed "+((self.retries > 0)?"retrying in 5 seconds ...":""));
19098                     if(self.retries > 0)
19099                     {
19100                         setTimeout(function(){
19101                             self.retries--;
19102                             init();
19103                         }, 5000);
19104                     }
19105                 };
19106                 self.socket.onerror = function(e)
19107                 {
19108                     self.iErrorCB(e.data);
19109                 };
19110                 self.socket.onmessage = function (e)
19111                 {
19112                     self.receive(e.data);
19113                 };
19114             }
19115             else
19116             {
19117                 console.log("This browser doesn't appear to support websockets!");
19118             }
19119         }
19120         init();
19121     }
19122
19123     Vehicle.prototype.generateTransactionId = function()
19124     {
19125         var i, val = [];
19126         for(i = 0; i < 8; i++)
19127         {
19128            var num = Math.floor((Math.random()+1)*65536);
19129            val[i] = num.toString(16).substring(1);
19130         }
19131         var uuid = val[0]+val[1]+"-"+
19132                    val[2]+"-"+val[3]+"-"+val[4]+"-"+
19133                    val[5]+val[6]+val[7];
19134         return uuid;
19135     }
19136
19137     Vehicle.prototype.send = function(obj, successCB, errorCB)
19138     {
19139         if(!this.connected)
19140         {
19141             if(errorCB !== undefined)
19142             {
19143                 errorCB("\""+obj.name+"\" method failed because socket is closed");
19144             }
19145             return;
19146         }
19147         var i = this.methodIdx;
19148         this.methodIdx = (this.methodIdx + 1)%100;
19149         this.methodCalls[i] = new this.VehicleMethodCall(obj.transactionid,
19150             obj.name, successCB, errorCB);
19151         this.socket.send(JSON.stringify(obj));
19152         this.methodCalls[i].start();
19153     }
19154
19155
19156     Vehicle.prototype.getSupportedEventTypes = function(type, writeable, successCB, errorCB)
19157     {
19158         var obj = {
19159             "type" : "method",
19160             "name" : "getSupportedEventTypes",
19161             "writeable" : writeable,
19162             "transactionid" : this.generateTransactionId(),
19163             "data" : type
19164         };
19165         this.send(obj, successCB, errorCB);
19166     }
19167
19168     Vehicle.prototype.get = function(namelist, successCB, errorCB)
19169     {
19170         if(namelist.length <= 0)
19171         {
19172             return;
19173         }
19174
19175         var obj = {
19176             "type" : "method",
19177             "name": "get",
19178             "transactionid" : this.generateTransactionId(),
19179             "data" : namelist
19180         };
19181         this.send(obj, successCB, errorCB);
19182     }
19183
19184     Vehicle.prototype.getHistory = function(namelist, beginDate, endDate, successCB, errorCB)
19185     {
19186         if(namelist.length <= 0)
19187         {
19188             return;
19189         }
19190
19191         var dataobj = {
19192             "property" : namelist,
19193             "timeBegin" : (beginDate.getTime() / 1000).toString(),
19194             "timeEnd" : (endDate.getTime() / 1000).toString(),
19195             "sequenceBegin" : "-1",
19196             "sequenceEnd" : "-1"
19197         }
19198
19199         var obj = {
19200             "type" : "method",
19201             "name": "getRanged",
19202             "transactionid" : this.generateTransactionId(),
19203             "data" : dataobj
19204         };
19205         this.send(obj, successCB, errorCB);
19206     }
19207
19208     Vehicle.prototype.set = function(namelist, valuelist, successCB, errorCB)
19209     {
19210         if((namelist.length != valuelist.length)||(namelist.length <= 0))
19211         {
19212             return;
19213         }
19214
19215         var obj = {
19216             "type" : "method",
19217             "name": "set",
19218             "transactionid" : this.generateTransactionId(),
19219             "data" : []
19220         };
19221         var list = [];
19222         for(var i = 0; i < namelist.length; i++)
19223         {
19224             var val = {"property" : namelist[i], "value" : valuelist[i]};
19225             list[list.length] = val;
19226         }
19227         obj.data = list;
19228         this.send(obj, successCB, errorCB);
19229     }
19230
19231     Vehicle.prototype.subscribe = function(namelist, successCB, errorCB)
19232     {
19233         var obj = {
19234             "type" : "method",
19235             "name": "subscribe",
19236             "transactionid" : this.generateTransactionId(),
19237             "data" : namelist
19238         };
19239         this.send(obj, successCB, errorCB);
19240     }
19241
19242     Vehicle.prototype.unsubscribe = function(namelist, successCB, errorCB)
19243     {
19244         var obj = {
19245             "type" : "method",
19246             "name": "unsubscribe",
19247             "transactionid" : this.generateTransactionId(),
19248             "data" : namelist
19249         };
19250         this.send(obj, successCB, errorCB);
19251     }
19252
19253     Vehicle.prototype.sendEvent = function(name, value)
19254     {
19255         var evt = document.createEvent("Event");
19256         evt.initEvent(name, true, true);
19257         evt.name = name;
19258         evt.value = value;
19259         document.dispatchEvent(evt);
19260         console.log(evt);
19261     }
19262
19263     Vehicle.prototype.receive = function(msg)
19264     {
19265         var self = this;
19266         var event;
19267         try {
19268             event = JSON.parse(msg);
19269         }
19270         catch(e) {
19271             self.iErrorCB("GARBAGE MESSAGE: "+msg);
19272             return;
19273         }
19274
19275         if((event === undefined)||(event.type === undefined)||
19276            (event.name === undefined))
19277         {
19278             self.iErrorCB("BADLY FORMED MESSAGE: "+msg);
19279             return;
19280         }
19281         else
19282         {
19283             if(event.type === "methodReply")
19284             {
19285                 var calls = this.methodCalls;
19286                 for(var i = 0; i < calls.length; i++)
19287                 {
19288                     var call = calls[i];
19289                     if(call&&(!call.done)&&(call.transactionid === event.transactionid))
19290                     {
19291                         call.finish();
19292                         if(event.error !== undefined)
19293                         {
19294                             call.errorCB(event.error);
19295                         }
19296                         if(event.data !== undefined && call.successCB !== undefined)
19297                         {
19298                             call.successCB(event.data);
19299                         }
19300                         return;
19301                     }
19302                 }
19303             }
19304             else if(event.type === "valuechanged")
19305             {
19306                 self.sendEvent(event.name, event.data);
19307             }
19308         }
19309     }
19310
19311     win.Vehicle = Vehicle;
19312 })(window);
19313
19314 /*
19315  * Copyright (c) 2012, Intel Corporation.
19316  *
19317  * This program is licensed under the terms and conditions of the
19318  * Apache License, version 2.0.  The full text of the Apache License is at
19319  * http://www.apache.org/licenses/LICENSE-2.0
19320  *
19321  */
19322
19323 (function($, _, undefined) {
19324         'use strict';
19325
19326     $.cowhide = $.cowhide || {}
19327     $.extend($.cowhide, {
19328         version: '0.0.1',
19329         options: {
19330           monitorFrameworkRestrictions: false,
19331           connectToAMB: false
19332         },
19333         themeEngineOptions: {
19334             path: 'css',
19335             initial: 'default',
19336             minified: false
19337         },
19338
19339         // List of registered widgets
19340         registeredWidgets: [],
19341
19342         drivingMode: false,
19343         nightMode: false,
19344         currentTheme: 'default',
19345
19346         vehicle: null,
19347
19348         GUID: function() {
19349             var S4 = function () {
19350                 return Math.floor(
19351                     Math.random() * 0x10000 /* 65536 */
19352                     ).toString(16);
19353             };
19354
19355             return (
19356                 S4() + S4() + "-" +
19357                 S4() + "-" +
19358                 S4() + "-" +
19359                 S4() + "-" +
19360                 S4() + S4() + S4()
19361                 );
19362         },
19363
19364         // Registers a widget
19365         register: function(widget) {
19366             var self = this;
19367             var guids = _.map(self.registeredWidgets, function(w) {
19368                 return w.guid;
19369             });
19370
19371             if (_.indexOf(guids, widget.guid) == -1) {
19372                 self.registeredWidgets.push(widget);
19373             }
19374
19375             /* TODO: core should ask `page` what a page looks like. */
19376             if(!(widget.$element[0].tagName == 'DIV' && widget.$element.hasClass('page'))) {
19377                 var $page = widget.$element.parent().closest('div.page');
19378                 if ($page.length === 0) {
19379                     $.cowhide.fatal("#30: every widget must be within a div with class='page'.", this.$element);
19380                 } else {
19381                     $page.ch_page('register', widget);
19382                 }
19383             }
19384         },
19385
19386         // TODO: use `backdrop` from Bootstrap's modal
19387         backdrop: function (callback) {
19388             var $backdrop = $('<div class="modal-backdrop theme-change-backdrop fade" />');
19389
19390             $backdrop.appendTo(document.body);
19391             $backdrop[0].offsetWidth; // force reflow
19392             $backdrop.addClass('in');
19393
19394             return $backdrop;
19395         },
19396
19397         initThemeEngine: function(options) {
19398             $.extend(this.themeEngineOptions, options);
19399             this.currentTheme = this.themeEngineOptions.initial;
19400
19401             var $link = $('link#cowhide-theme');
19402             if ($link.length === 0) {
19403                 this.fatal("#40: could not find <link> with id 'cowhide-theme'.");
19404             }
19405         },
19406
19407         setTheme: function(name, nightMode) {
19408             if (name === this.currentTheme && nightMode == this.nightMode) {
19409                 return;
19410             }
19411
19412             var $link = $('link#cowhide-theme');
19413             var theme =
19414                 this.themeEngineOptions.path +
19415                 '/cowhide-' +
19416                 name || 'default';
19417
19418             if (nightMode === true || (nightMode === undefined && this.nightMode === true)) {
19419                 theme += '-night';
19420             }
19421
19422             if (this.themeEngineOptions.minified) {
19423                 theme += '.min';
19424             }
19425
19426             theme += '.css';
19427
19428             var $backdrop = this.backdrop();
19429             setTimeout(function() {
19430                 $link.attr('href', theme);
19431                 $backdrop.remove();
19432             }, 200);
19433
19434             this.currentTheme = name;
19435             if (nightMode !== undefined) {
19436                 this.nightMode = nightMode;
19437             }
19438         },
19439
19440         setNightMode: function(value) {
19441           if (this.nightMode == value)
19442             return;
19443
19444           this.setTheme(this.currentTheme, !this.nightMode);
19445         },
19446
19447         toggleNightMode: function() {
19448             this.setNightMode(!this.nightMode);
19449         },
19450
19451         toggleDrivingMode: function() {
19452             this.setDrivingMode(!this.drivingMode);
19453         },
19454
19455         setDrivingMode: function(value) {
19456             var self = this;
19457
19458             if (self.drivingMode == value)
19459                 return;
19460
19461             self.drivingMode = value;
19462             _.each(this.registeredWidgets, function(w) {
19463                 if (w.setDrivingMode)
19464                     w.setDrivingMode(self.drivingMode);
19465             });
19466         },
19467
19468
19469         listenToVehicle: function() {
19470             var self = this;
19471
19472             self.vehicle = new window.Vehicle(
19473                 function() {
19474                     $(document).on("DrivingMode", function(e) {
19475                         self.setDrivingMode(e.originalEvent.value == 1);
19476                     });
19477
19478                     $(document).on("NightMode", function(e) {
19479                         self.setNightMode(e.originalEvent.value);
19480                     });
19481                 },
19482                 function() {
19483                     self.fatal("There was a problem connecting to AMB's web socket.");
19484                 }
19485             );
19486         },
19487
19488         verifyFrameworkRestrictions: function() {
19489             _.each(this.registeredWidgets, function(w) {
19490                 w.verifyMinFontSize();
19491                 w.verifyMaxFontSize();
19492                 w.verifyMinWidth();
19493             });
19494         },
19495
19496         fatal: function(msg, $element) {
19497             var output = "";
19498
19499             output += "[Cowhide] Fatal error";
19500             if ($element !== undefined) {
19501                 output += " (offending widget: ";
19502                 var id = $element.attr('id');
19503                 var classes = $element.attr('class');
19504
19505                 if (id)
19506                     output += "#(" + id + ")";
19507                 if (classes)
19508                     output += ".(" + classes + ")";
19509
19510                 output += ")";
19511             }
19512
19513             output += ": " + msg;
19514             throw new Error(output);
19515         }
19516     });
19517
19518     $(function() {
19519         if ($.cowhide.options.connectToAMB) {
19520           $.cowhide.listenToVehicle();
19521         }
19522
19523         if ($.cowhide.options.monitorFrameworkRestrictions) {
19524           setInterval(function() {
19525               $.cowhide.verifyFrameworkRestrictions();
19526           }, 1000);
19527         }
19528     });
19529 })(window.jQuery, window._);
19530
19531 /*
19532  * Copyright (c) 2012, Intel Corporation.
19533  *
19534  * This program is licensed under the terms and conditions of the
19535  * Apache License, version 2.0.  The full text of the Apache License is at
19536  * http://www.apache.org/licenses/LICENSE-2.0
19537  *
19538  */
19539
19540 (function($, undefined) {
19541         'use strict';
19542
19543     var ChWidget = function(element, options) {
19544         this.$element = $(element);
19545         this.options = $.extend({}, $.fn.ch_widget.defaults);
19546         this.drivingMode = false;
19547     };
19548
19549     ChWidget.prototype = $.extend({}, {
19550         register: function() {
19551             this.guid = $.cowhide.GUID();
19552             $.cowhide.register(this);
19553         },
19554
19555         verifyMinWidth: function() {
19556             if (this.$element.width() < this.options.minWidth && this.options.minWidth > 0)
19557               $.cowhide.fatal("#10: this widget has a minimum allowed width of " +
19558                               this.options.minWidth + "px", this.$element);
19559         },
19560
19561         verifyMinFontSize: function() {
19562             if (this.options.minFontSize > 0) {
19563                 var current = this.$element.css('font-size');
19564                 if (parseFloat(current) < this.options.minFontSize) {
19565                     $.cowhide.fatal("#20: this widget has a minimum allowed font-size of " +
19566                                     this.options.minFontSize + "px", this.$element);
19567                 }
19568             }
19569         },
19570
19571         verifyMaxFontSize: function() {
19572             if (this.options.maxFontSize > 0) {
19573                 var current = this.$element.css('font-size');
19574                 if (parseFloat(current) > this.options.maxFontSize) {
19575                     $.cowhide.fatal("#21: this widget has a maximum allowed font-size of " +
19576                                     this.options.maxFontSize + "px", this.$element);
19577                 }
19578             }
19579         },
19580
19581         setDrivingMode: function(drivingMode) {
19582             if (this.$element.data('ignore-driving-mode') === undefined &&
19583                 this.options.disableWhenDriving)
19584             {
19585                 var wasDisabled = this.$element.attr('disabled') == 'disabled';
19586                 var d = 'disabled';
19587
19588                 if (!drivingMode && !this.drivingMode && wasDisabled)
19589                     // If
19590                     //   we're not entering driving mode, and
19591                     //   we weren't already in driving mode, and
19592                     //   the widget wasn't already disabled, perhaps for
19593                     //   other reasons.
19594                     return;
19595
19596                 if (drivingMode) {
19597                     this.$element.attr(d, d);
19598                     this.$element.disabled = true;
19599                     this.$element.addClass(d);
19600
19601                     if (this.onDrivingModeEnter)
19602                         this.onDrivingModeEnter();
19603
19604                     this.drivingMode = true;
19605                 } else if (this.drivingMode) {
19606                     this.$element.removeAttr(d);
19607                     this.$element.disabled = false;
19608                     this.$element.removeClass(d);
19609
19610                     if (this.onDrivingModeExit)
19611                         this.onDrivingModeExit();
19612
19613                     this.drivingMode = false;
19614                 }
19615             }
19616         },
19617
19618         onDrivingModeEnter: undefined,
19619         onDrivingModeExit: undefined
19620      });
19621
19622     $.fn.ch_widget = function() {}
19623     $.fn.ch_widget.defaults = {
19624         minWidth: 0,
19625         minFontSize: 0,
19626         maxFontSize: 0,
19627         disableWhenDriving: false
19628     };
19629     $.fn.ch_widget.Constructor = ChWidget;
19630 })(window.jQuery);
19631
19632 /*
19633  * Copyright (c) 2012, Intel Corporation.
19634  *
19635  * This program is licensed under the terms and conditions of the
19636  * Apache License, version 2.0.  The full text of the Apache License is at
19637  * http://www.apache.org/licenses/LICENSE-2.0
19638  *
19639  */
19640
19641 (function($, undefined) {
19642     'use strict';
19643
19644     var ChButton = function(element, options) {
19645         $.fn.ch_widget.Constructor(element, options);
19646         this.$element = $(element);
19647         this.options = $.extend(
19648             options,
19649             $.fn.ch_widget.defaults,
19650             {
19651                 minFontSize: 12,
19652                 maxFontSize: 24,
19653                 disableWhenDriving: true
19654             });
19655
19656         if (this.options.fixedWidth) {
19657             this.$element.css({width: this.options.fixedWidth});
19658         }
19659
19660         if (this.options.marquee) {
19661             this.enableMarquee();
19662         }
19663     };
19664
19665     ChButton.prototype = $.extend(
19666         {},
19667         $.fn.ch_widget.Constructor.prototype,
19668         {
19669             constructor: ChButton,
19670
19671             disableMarquee: function() {
19672                 var $marquee = this.$element.find('marquee');
19673                 if($marquee.length > 0) {
19674                     var text = $marquee.text();
19675                     $marquee.remove();
19676                     this.$element.text(text);
19677                 }
19678             },
19679
19680             enableMarquee: function() {
19681                 if (this.options.marquee && (
19682                     this.$element[0].tagName == 'A' ||
19683                     this.$element[0].tagName == 'BUTTON'))
19684                 {
19685                     var text = this.$element.text()
19686
19687                     var $marquee = $('<marquee/>');
19688                     $marquee.attr('behavior', 'alternate')
19689                     $marquee.attr('scrollamount', 1)
19690                     $marquee.attr('width', this.$element.width());
19691                     $marquee.text(text);
19692
19693                     this.$element.html($marquee);
19694                 }
19695             },
19696
19697             onDrivingModeEnter: function() {
19698                 this.disableMarquee();
19699             },
19700
19701             onDrivingModeExit: function() {
19702                 this.enableMarquee();
19703             }
19704         }
19705     );
19706
19707
19708     /* CHBUTTON PLUGIN DEFINITION
19709      * ========================== */
19710
19711     var old = $.fn.ch_button;
19712
19713     $.fn.ch_button = function(option) {
19714         return this.each(function() {
19715             var $this = $(this),
19716                 data = $this.data('ch_button'),
19717                 options = typeof option == 'object' && option;
19718
19719             if ($this.data('marquee')) {
19720                 options = $.extend(options, {marquee: true});
19721             }
19722             if ($this.data('fixed-width')) {
19723                 options = $.extend(options, {fixedWidth: $this.data('fixed-width')})
19724             }
19725             if (!data) {
19726                 $this.data('ch_button', (data = new ChButton(this, options)));
19727                 data.register();
19728             }
19729
19730             $this.button(option);
19731         });
19732     };
19733
19734     $.fn.ch_button.Constructor = ChButton;
19735
19736
19737     /* CHBUTTON NO CONFLICT
19738      * ==================== */
19739
19740     $.fn.ch_button.noConflict = function() {
19741         $.fn.ch_button = old;
19742         return this;
19743     };
19744
19745
19746     /* CHBUTTON DATA-API
19747      * ================= */
19748
19749     $(function() {
19750         $('.btn, button, input[type=button]').ch_button();
19751     })
19752 })(window.jQuery);
19753
19754 /*
19755  * Copyright (c) 2012, Intel Corporation.
19756  *
19757  * This program is licensed under the terms and conditions of the
19758  * Apache License, version 2.0.  The full text of the Apache License is at
19759  * http://www.apache.org/licenses/LICENSE-2.0
19760  *
19761  */
19762
19763 (function($, undefined) {
19764     'use strict';
19765
19766     var ChSeatSelector = function(element, options) {
19767         $.fn.ch_widget.Constructor(element, options);
19768         this.$element = $(element);
19769         this.options = $.extend({}, $.fn.ch_widget.defaults);
19770     };
19771
19772     ChSeatSelector.prototype = $.extend(
19773         {},
19774         $.fn.ch_widget.Constructor.prototype,
19775         {
19776             constructor: ChSeatSelector,
19777             removeSelection: function() {
19778                 var $t = this.$element.find('table');
19779                 $t.removeClass('front-left');
19780                 $t.removeClass('front-right');
19781                 $t.removeClass('rear-left');
19782                 $t.removeClass('rear-right');
19783             },
19784             frontLeft: function() {
19785                 this.removeSelection();
19786                 this.$element.find('table').addClass('front-left');
19787             },
19788
19789             frontRight: function() {
19790                 this.removeSelection();
19791                 this.$element.find('table').addClass('front-right');
19792             },
19793
19794             rearLeft: function() {
19795                 this.removeSelection();
19796                 this.$element.find('table').addClass('rear-left');
19797             },
19798
19799             rearRight: function() {
19800                 this.removeSelection();
19801                 this.$element.find('table').addClass('rear-right');
19802             }
19803         }
19804     );
19805
19806     $.fn.ch_seat_selector = function(option) {
19807         return this.each(function() {
19808             var $this = $(this),
19809                 data = $this.data('ch_seat_selector'),
19810                 options = typeof option == 'object' && option;
19811
19812             if (!data) {
19813                 $this.data('ch_seat_selector', (data = new ChSeatSelector(this, options)));
19814                 data.register();
19815                 var template = [
19816                     '<table>',
19817                     '    <tr>',
19818                     '        <td class="front-left"></td>',
19819                     '        <td class="front-right"></td>',
19820                     '    </tr>',
19821                     '    <tr>',
19822                     '        <td class="rear-left"></td>',
19823                     '        <td class="rear-right"></td>',
19824                     '    </tr>',
19825                     '</table>'].join('\n');
19826                 $this.html(template);
19827             } else {
19828                 if (option == 'frontLeft')
19829                     data.frontLeft();
19830                 else if (option == 'frontRight')
19831                     data.frontRight();
19832                 else if (option == 'rearLeft')
19833                     data.rearLeft();
19834                 else if (option == 'rearRight')
19835                     data.rearRight();
19836                 else if (option == 'removeSelection')
19837                     data.removeSelection();
19838             }
19839         });
19840     };
19841
19842     $.fn.ch_seat_selector.Constructor = ChSeatSelector;
19843
19844     /* CHSEATSELECTOR DATA-API
19845      * ================= */
19846     $(function() {
19847         $('.ch-seat-selector').ch_seat_selector();
19848     })
19849 })(window.jQuery);
19850
19851 /*
19852  * Copyright (c) 2012, Intel Corporation.
19853  *
19854  * This program is licensed under the terms and conditions of the
19855  * Apache License, version 2.0.  The full text of the Apache License is at
19856  * http://www.apache.org/licenses/LICENSE-2.0
19857  *
19858  */
19859
19860 (function($, undefined) {
19861     'use strict';
19862
19863     var ChSlider = function(element, options) {
19864         $.fn.ch_widget.Constructor(element, options);
19865         this.$element = $(element);
19866         this.options = $.extend({}, $.fn.ch_widget.defaults);
19867     };
19868
19869     ChSlider.prototype = $.extend(
19870         {},
19871         $.fn.ch_widget.Constructor.prototype,
19872         {
19873             constructor: ChSlider
19874         }
19875     );
19876
19877     $.fn.ch_slider = function(option) {
19878         return this.each(function() {
19879             var $this = $(this),
19880                 data = $this.data('ch_slider'),
19881                 options = typeof option == 'object' && option;
19882
19883             if ($this.attr('data-height')) {
19884                 options = $.extend(options, {height: $this.attr('data-height')});
19885             }
19886             if (!data) {
19887                 $this.data('ch_slider', (data = new ChSlider(this, options)));
19888                 data.register();
19889             }
19890
19891             $this.slider(options);
19892         });
19893     };
19894
19895     $.fn.ch_button.Constructor = ChSlider;
19896
19897     /* CHSLIDER DATA-API
19898      * ================= */
19899     $(function() {
19900         $('.ch-slider').ch_slider();
19901         $('.ch-slider-vertical').ch_slider({
19902             orientation: 'vertical'
19903         });
19904     })
19905 })(window.jQuery);
19906
19907 /*
19908  * Copyright (c) 2012, Intel Corporation.
19909  *
19910  * This program is licensed under the terms and conditions of the
19911  * Apache License, version 2.0.  The full text of the Apache License is at
19912  * http://www.apache.org/licenses/LICENSE-2.0
19913  *
19914  */
19915
19916 (function($, undefined) {
19917     'use strict';
19918
19919     var ChTextInput = function(element, options) {
19920         $.fn.ch_widget.Constructor(element, options);
19921         this.$element = $(element);
19922         this.options = $.extend(
19923             {},
19924             $.fn.ch_widget.defaults,
19925             {
19926                 disableWhenDriving: true
19927             });
19928     };
19929
19930     ChTextInput.prototype = $.extend(
19931         {},
19932         $.fn.ch_widget.Constructor.prototype,
19933         {
19934             constructor: ChTextInput
19935         }
19936     );
19937
19938     $.fn.ch_text_input = function(option) {
19939         return this.each(function() {
19940             var $this = $(this),
19941                 data = $this.data('ch_text_input'),
19942                 options = typeof option == 'object' && option;
19943
19944             if (!data) {
19945                 $this.data('ch_text_input', (data = new ChTextInput(this, options)));
19946                 data.register();
19947             }
19948         });
19949     };
19950
19951     $.fn.ch_text_input.Constructor = ChTextInput;
19952
19953     /* CHBUTTON DATA-API
19954      * ================= */
19955     $(function() {
19956         $('input[type=text]').ch_text_input();
19957     })
19958 })(window.jQuery);
19959
19960 /*
19961  * Copyright (c) 2012, Intel Corporation.
19962  *
19963  * This program is licensed under the terms and conditions of the
19964  * Apache License, version 2.0.  The full text of the Apache License is at
19965  * http://www.apache.org/licenses/LICENSE-2.0
19966  *
19967  */
19968
19969 (function($, undefined) {
19970     'use strict';
19971
19972     var ChRadioInput = function(element, options) {
19973         $.fn.ch_widget.Constructor(element, options);
19974         this.$element = $(element);
19975         this.options = $.extend(
19976             {},
19977             $.fn.ch_widget.defaults,
19978             {
19979                 disableWhenDriving: true
19980             });
19981     };
19982
19983     ChRadioInput.prototype = $.extend(
19984         {},
19985         $.fn.ch_widget.Constructor.prototype,
19986         {
19987             constructor: ChRadioInput
19988         }
19989     );
19990
19991     /* CHRADIOINPUT PLUGIN DEFINITION
19992      * ============================== */
19993
19994     var old = $.fn.ch_radio_input;
19995
19996     $.fn.ch_radio_input = function(option) {
19997         return this.each(function() {
19998             var $this = $(this),
19999                 data = $this.data('ch_radio_input'),
20000                 options = typeof option == 'object' && option;
20001
20002             if (!data) {
20003                 $this.data('ch_radio_input', (data = new ChRadioInput(this, options)));
20004                 data.register();
20005             }
20006         });
20007     };
20008
20009     $.fn.ch_radio_input.Constructor = ChRadioInput;
20010
20011
20012     /* CHRADIOINPUT NO CONFLICT
20013      * ======================== */
20014
20015     $.fn.ch_radio_input.noConflict = function() {
20016         $.fn.ch_radio_input = old;
20017         return this;
20018     };
20019
20020
20021     /* CHRADIOINPUT DATA-API
20022      * ===================== */
20023
20024     $(function() {
20025         $('input[type=radio]').ch_radio_input();
20026     })
20027 })(window.jQuery);
20028
20029 /*
20030  * Copyright (c) 2012, Intel Corporation.
20031  *
20032  * This program is licensed under the terms and conditions of the
20033  * Apache License, version 2.0.  The full text of the Apache License is at
20034  * http://www.apache.org/licenses/LICENSE-2.0
20035  *
20036  */
20037
20038 (function($, undefined) {
20039     'use strict';
20040
20041     var ChCheckboxInput = function(element, options) {
20042         $.fn.ch_widget.Constructor(element, options);
20043         this.$element = $(element);
20044         this.options = $.extend(
20045             {},
20046             $.fn.ch_widget.defaults,
20047             {
20048                 disableWhenDriving: true
20049             });
20050     };
20051
20052     ChCheckboxInput.prototype = $.extend(
20053         {},
20054         $.fn.ch_widget.Constructor.prototype,
20055         {
20056             constructor: ChCheckboxInput
20057         }
20058     );
20059
20060
20061     /* CHCHECKBOXINPUT PLUGIN DEFINITION
20062      * ================================= */
20063
20064     var old = $.fn.ch_checkbox_input;
20065
20066     $.fn.ch_checkbox_input = function(option) {
20067         return this.each(function() {
20068             var $this = $(this),
20069                 data = $this.data('ch_checkbox_input'),
20070                 options = typeof option == 'object' && option;
20071
20072             if (!data) {
20073                 $this.data('ch_checkbox_input', (data = new ChCheckboxInput(this, options)));
20074                 data.register();
20075             }
20076         });
20077     };
20078
20079     $.fn.ch_checkbox_input.Constructor = ChCheckboxInput;
20080
20081
20082     /* CHCHECKBOXINPUT NO CONFLICT
20083      * =========================== */
20084
20085     $.fn.ch_checkbox_input.noConflict = function() {
20086         $.fn.ch_checkbox_input = old;
20087         return this;
20088     };
20089
20090
20091     /* CHCHECKBOXINPUT DATA-API
20092      * ================= */
20093
20094     $(function() {
20095         $('input[type=checkbox]').ch_checkbox_input();
20096     })
20097 })(window.jQuery);
20098
20099 /*
20100  * Copyright (c) 2012, Intel Corporation.
20101  *
20102  * This program is licensed under the terms and conditions of the
20103  * Apache License, version 2.0.  The full text of the Apache License is at
20104  * http://www.apache.org/licenses/LICENSE-2.0
20105  *
20106  */
20107
20108 (function($, undefined) {
20109     'use strict';
20110
20111     var ChSelect = function(element, options) {
20112         $.fn.ch_widget.Constructor(element, options);
20113         this.$element = $(element);
20114         this.options = $.extend(
20115             {},
20116             $.fn.ch_widget.defaults,
20117             {
20118                 disableWhenDriving: true
20119             });
20120     };
20121
20122     ChSelect.prototype = $.extend(
20123         {},
20124         $.fn.ch_widget.Constructor.prototype,
20125         {
20126             constructor: ChSelect
20127         }
20128     );
20129
20130
20131     /* CHSELECT PLUGIN DEFINITION
20132      * ========================== */
20133
20134     var old = $.fn.ch_select;
20135
20136     $.fn.ch_select = function(option) {
20137         return this.each(function() {
20138             var $this = $(this),
20139                 data = $this.data('ch_select'),
20140                 options = typeof option == 'object' && option;
20141
20142             if (!data) {
20143                 $this.data('ch_select', (data = new ChSelect(this, options)));
20144                 data.register();
20145             }
20146         });
20147     };
20148
20149     $.fn.ch_select.Constructor = ChSelect;
20150
20151
20152     /* CHSELECT NO CONFLICT
20153      * ==================== */
20154
20155     $.fn.ch_select.noConflict = function() {
20156         $.fn.ch_select = old;
20157         return this;
20158     };
20159
20160
20161     /* CHBUTTON DATA-API
20162      * ================= */
20163
20164     $(function() {
20165         $('select').ch_select();
20166     })
20167 })(window.jQuery);
20168
20169 /*
20170  * Copyright (c) 2012, Intel Corporation.
20171  *
20172  * This program is licensed under the terms and conditions of the
20173  * Apache License, version 2.0.  The full text of the Apache License is at
20174  * http://www.apache.org/licenses/LICENSE-2.0
20175  *
20176  */
20177
20178 (function($, undefined) {
20179     'use strict';
20180
20181     var ChPage = function(element, options) {
20182         $.fn.ch_widget.Constructor(element, options);
20183         this.$element = $(element);
20184         this.options = $.extend(
20185             options,
20186             $.fn.ch_widget.defaults,
20187             {
20188                 maxWidgets: 0
20189             });
20190
20191         var $parent_page = this.$element.parent().closest('div.page');
20192         if ($parent_page.length !== 0) {
20193             $.cowhide.fatal('#31: pages cannot be nested.');
20194         }
20195     };
20196
20197     ChPage.prototype = $.extend(
20198         {},
20199         $.fn.ch_widget.Constructor.prototype,
20200         {
20201             constructor: ChPage,
20202
20203             registeredWidgets: 0,
20204             registerWidget: function(widget) {
20205                 this.registeredWidgets++;
20206                 if (this.options.maxWidgets > 0 &&
20207                     this.registeredWidgets > this.options.maxWidgets)
20208                 {
20209                     $.cowhide.fatal("#32: a page cannot have more than " +
20210                                     this.options.maxWidgets +
20211                                     " widgets.");
20212                 }
20213             },
20214
20215             setMaxWidgets: function(value) {
20216               this.options.maxWidgets = value;
20217             }
20218         }
20219     );
20220
20221
20222     /* CHPAGE PLUGIN DEFINITION
20223      * ======================== */
20224
20225     $.fn.ch_page = function(option, value) {
20226         return this.each(function() {
20227             var $this = $(this),
20228                 data = $this.data('ch_page'),
20229                 options = typeof option == 'object' && option;
20230
20231             if (!data) {
20232                 $this.data('ch_page', (data = new ChPage(this, options)));
20233                 data.register();
20234             }
20235
20236             if(option == 'register') {
20237                 data.registerWidget(value);
20238             }
20239
20240             if(option == 'setMaxWidgets') {
20241               data.setMaxWidgets(value);
20242             }
20243         });
20244     };
20245
20246     $.fn.ch_page.Constructor = ChPage;
20247
20248
20249     /* CHPAGE DATA-API
20250      * ================= */
20251
20252     $(function() {
20253         $('div.page').ch_page();
20254     })
20255 })(window.jQuery);
20256
20257 /*
20258  * Copyright (c) 2012, Intel Corporation.
20259  *
20260  * This program is licensed under the terms and conditions of the
20261  * Apache License, version 2.0.  The full text of the Apache License is at
20262  * http://www.apache.org/licenses/LICENSE-2.0
20263  *
20264  */
20265
20266 (function($, undefined) {
20267     'use strict';
20268
20269     var ChHeader = function(element, options) {
20270         $.fn.ch_widget.Constructor(element, options);
20271         this.$element = $(element);
20272         this.options = $.extend({}, options);
20273     };
20274
20275     ChHeader.prototype = $.extend(
20276         {},
20277         $.fn.ch_widget.Constructor.prototype,
20278         {
20279             constructor: ChHeader,
20280
20281             show: function() {
20282                 var $this = this.$element,
20283                     $h = $('<h1/>').text(this.$element.text());
20284
20285                $this.html($h);
20286
20287                if (this.options.show_back_button) {
20288                     var $back = $('<button/>').addClass('btn');
20289                     var $icon = $('<i/>').addClass('icon-backward');
20290
20291                     $back.html($icon);
20292
20293                     $this.append($back);
20294
20295                     $back.click(function(e) {
20296                         e.preventDefault();
20297                         $this.trigger($.Event('back'));
20298                     });
20299                 }
20300             }
20301         }
20302     );
20303
20304
20305     /* CHHEADER PLUGIN DEFINITION
20306      * ========================== */
20307
20308     var old = $.fn.ch_header;
20309
20310     $.fn.ch_header = function(option) {
20311         return this.each(function() {
20312             var $this = $(this),
20313                 data = $this.data('ch_header'),
20314                 options = typeof option == 'object' && option;
20315
20316             if ($this.data('show-back-button')) {
20317                 options = $.extend(options, {show_back_button: true});
20318             }
20319
20320             if (!data) {
20321                 $this.data('ch_header', (data = new ChHeader(this, options)));
20322                 data.register();
20323             }
20324
20325             if (typeof option == 'string')
20326                 data[option]();
20327         });
20328     };
20329
20330     $.fn.ch_button.Constructor = ChHeader;
20331
20332
20333     /* CHHEADER NO CONFLICT
20334      * ==================== */
20335
20336     $.fn.ch_header.noConflict = function() {
20337         $.fn.ch_header = old;
20338         return this;
20339     };
20340
20341
20342     /* CHHEADER DATA-API
20343      * ================= */
20344
20345     $(function() {
20346         $('.ch-header').ch_header('show');
20347     })
20348 })(window.jQuery);
20349
20350 /* vi: set et sw=4 ts=4 si: */
20351 (function($, undefined) {
20352     'use strict';
20353
20354     var ChSimpleScrollable = function(element, options) {
20355         $.fn.ch_widget.Constructor(element, options);
20356         this.$element = $(element);
20357         this.options = $.extend(
20358             options,
20359             $.fn.ch_widget.defaults,
20360             {
20361             });
20362     };
20363
20364     ChSimpleScrollable.prototype = $.extend(
20365         {},
20366         $.fn.ch_widget.Constructor.prototype,
20367         {
20368             constructor: ChSimpleScrollable,
20369
20370             enable: function() {
20371                 var self = this,
20372                     $this = self.$element,
20373                     $up = $('<div/>').addClass('ch-simple-scrollable-up'),
20374                     $dn = $('<div/>').addClass('ch-simple-scrollable-dn'),
20375                     $child =  $this.find('ul, ol, div, p'),
20376                     scrollAmount;
20377
20378                 $child.addClass('ch-simple-scrollable-content');
20379                 $child.height($child.parent().height() - 160);
20380                 scrollAmount = $child.height() - 40;
20381
20382
20383                 $up.css({top: $child.offset().top});
20384
20385                 $up.html('<a href="#"><i class="icon-chevron-up"></i></a>');
20386                 $dn.html('<a href="#"><i class="icon-chevron-down"></i></a>');
20387
20388                 $dn.click(function() {
20389                     $child.animate({
20390                         scrollTop: $child.scrollTop() + scrollAmount
20391                     }, 200);
20392                 });
20393
20394                 $up.click(function() {
20395                     $child.animate({
20396                         scrollTop: $child.scrollTop() - scrollAmount
20397                     }, 200);
20398                 });
20399
20400
20401                 $up.insertBefore($child);
20402                 $dn.insertAfter($child);
20403             }
20404         }
20405     );
20406
20407
20408     /* CHSIMPLESCROLLABLE PLUGIN DEFINITION
20409      * ==================================== */
20410
20411     var old = $.fn.ch_simple_scrollable;
20412
20413     $.fn.ch_simple_scrollable = function(option) {
20414         return this.each(function() {
20415             var $this = $(this),
20416                 data = $this.data('ch_simple_scrollable'),
20417                 options = typeof option == 'object' && option;
20418
20419             if (!data) {
20420                 $this.data('ch_simple_scrollable', (data = new ChSimpleScrollable(this, options)));
20421                 data.register();
20422             }
20423
20424             if(typeof option == 'string')
20425                 data[option]();
20426         });
20427     };
20428
20429     $.fn.ch_simple_scrollable.Constructor = ChSimpleScrollable;
20430
20431
20432     /* CHSIMPLESCROLLABLE NO CONFLICT
20433      * ============================== */
20434
20435     $.fn.ch_simple_scrollable.noConflict = function() {
20436         $.fn.ch_simple_scrollable = old;
20437         return this;
20438     };
20439
20440
20441     /* CHSIMPLESCROLLABLE DATA-API
20442      * =========================== */
20443
20444     $(function() {
20445         $('div.ch-simple-scrollable').ch_simple_scrollable('enable');
20446     })
20447 })(window.jQuery);