vendor: 4,409 bytes, lines 1-181
1/*! 2 * jQuery JavaScript Library v1.12.4 3 * http://jquery.com/ 4 * 5 * Includes Sizzle.js 6 * http://sizzlejs.com/ 7 * 8 * Copyright jQuery Foundation and other contributors 9 * Released under the MIT license 10 * http://jquery.org/license 11 * 12 * Date: 2016-05-20T17:17Z 13 */ 14 15 16(function( global, factory ) { 17 18 if ( typeof module === "object" && typeof module.exports === "object" ) { 19 // For CommonJS and CommonJS-like environments where a proper `window` 20 // is present, execute the factory and get jQuery. 21 // For environments that do not have a `window` with a `document` 22 // (such as Node.js), expose a factory as module.exports. 23 // This accentuates the need for the creation of a real `window`. 24 // e.g. var jQuery = require("jquery")(window); 25 // See ticket #14549 for more info. 26 module.exports = global.document ? 27 factory( global, true ) : 28 function( w ) { 29 if ( !w.document ) { 30 throw new Error( "jQuery requires a window with a document" ); 31 } 32 return factory( w ); 33 }; 34 } else { 35 factory( global ); 36 } 37 38// Pass this if window is not defined yet 39}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 40 41// Support: Firefox 18+ 42// Can't be in strict mode, several libs including ASP.NET trace 43// the stack via arguments.caller.callee and Firefox dies if 44// you try to trace through "use strict" call chains. (#13335) 45//"use strict"; 46var deletedIds = []; 47 48var document = window.document; 49 50var slice = deletedIds.slice; 51 52var concat = deletedIds.concat; 53 54var push = deletedIds.push; 55 56var indexOf = deletedIds.indexOf; 57 58var class2type = {}; 59 60var toString = class2type.toString; 61 62var hasOwn = class2type.hasOwnProperty; 63 64var support = {}; 65 66 67 68var 69 version = "1.12.4", 70 71 // Define a local copy of jQuery 72 jQuery = function( selector, context ) { 73 74 // The jQuery object is actually just the init constructor 'enhanced' 75 // Need init if jQuery is called (just allow error to be thrown if not included) 76 return new jQuery.fn.init( selector, context ); 77 }, 78 79 // Support: Android<4.1, IE<9 80 // Make sure we trim BOM and NBSP 81 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, 82 83 // Matches dashed string for camelizing 84 rmsPrefix = /^-ms-/, 85 rdashAlpha = /-([\da-z])/gi, 86 87 // Used by jQuery.camelCase as callback to replace() 88 fcamelCase = function( all, letter ) { 89 return letter.toUpperCase(); 90 }; 91 92jQuery.fn = jQuery.prototype = { 93 94 // The current version of jQuery being used 95 jquery: version, 96 97 constructor: jQuery, 98 99 // Start with an empty selector 100 selector: "", 101 102 // The default length of a jQuery object is 0 103 length: 0, 104 105 toArray: function() { 106 return slice.call( this ); 107 }, 108 109 // Get the Nth element in the matched element set OR 110 // Get the whole matched element set as a clean array 111 get: function( num ) { 112 return num != null ? 113 114 // Return just the one element from the set 115 ( num < 0 ? this[ num + this.length ] : this[ num ] ) : 116 117 // Return all the elements in a clean array 118 slice.call( this ); 119 }, 120 121 // Take an array of elements and push it onto the stack 122 // (returning the new matched element set) 123 pushStack: function( elems ) { 124 125 // Build a new jQuery matched element set 126 var ret = jQuery.merge( this.constructor(), elems ); 127 128 // Add the old object onto the stack (as a reference) 129 ret.prevObject = this; 130 ret.context = this.context; 131 132 // Return the newly-formed element set 133 return ret; 134 }, 135 136 // Execute a callback for every element in the matched set. 137 each: function( callback ) { 138 return jQuery.each( this, callback ); 139 }, 140 141 map: function( callback ) { 142 return this.pushStack( jQuery.map( this, function( elem, i ) { 143 return callback.call( elem, i, elem ); 144 } ) ); 145 }, 146 147 slice: function() { 148 return this.pushStack( slice.apply( this, arguments ) ); 149 }, 150 151 first: function() { 152 return this.eq( 0 ); 153 }, 154 155 last: function() { 156 return this.eq( -1 ); 157 }, 158 159 eq: function( i ) { 160 var len = this.length, 161 j = +i + ( i < 0 ? len : 0 ); 162 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 163 }, 164 165 end: function() { 166 return this.prevObject || this.constructor(); 167 }, 168 169 // For internal use only. 170 // Behaves like an Array's method, not like a jQuery method. 171 push: push, 172 sort: deletedIds.sort, 173 splice: deletedIds.splice 174}; 175 176jQuery.extend = jQuery.fn.extend = function() { 177 var src, copyIsArray, copy, name, options, clone, 178 target = arguments[ 0 ] || {}, 179 i = 1, 180 length = arguments.length, 181 deep = false;
182 183 // Handle a deep copy situation 184 if ( typeof target === "boolean" ) { 185 deep = target; 186 187 // skip the boolean and the target 188 target = arguments[ i ] || {}; 189 i++; 190 } 191 192 // Handle case when target is a string or something (possible in deep copy) 193 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { 194 target = {}; 195 } 196 197 // extend jQuery itself if only one argument is passed 198 if ( i === length ) { 199 target = this; 200 i--; 201 } 202 203 for ( ; i < length; i++ ) { 204 205 // Only deal with non-null/undefined values 206 if ( ( options = arguments[ i ] ) != null ) { 207 208 // Extend the base object 209 for ( name in options ) { 210 src = target[ name ]; 211 copy = options[ name ]; 212 213 // Prevent never-ending loop 214 if ( target === copy ) { 215 continue; 216 } 217 218 // Recurse if we're merging plain objects or arrays 219 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 220 ( copyIsArray = jQuery.isArray( copy ) ) ) ) { 221 222 if ( copyIsArray ) { 223 copyIsArray = false; 224 clone = src && jQuery.isArray( src ) ? src : []; 225 226 } else { 227 clone = src && jQuery.isPlainObject( src ) ? src : {}; 228 } 229 230 // Never move original objects, clone them 231 target[ name ] = jQuery.extend( deep, clone, copy ); 232 233 // Don't bring in undefined values 234 } else if ( copy !== undefined ) { 235 target[ name ] = copy; 236 } 237 } 238 } 239 } 240 241 // Return the modified object 242 return target; 243}; 244 245jQuery.extend( { 246 247 // Unique for each copy of jQuery on the page 248 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 249 250 // Assume jQuery is ready without the ready module 251 isReady: true, 252 253 error: function( msg ) { 254 throw new Error( msg ); 255 }, 256 257 noop: function() {}, 258 259 // See test/unit/core.js for details concerning isFunction. 260 // Since version 1.3, DOM methods and functions like alert 261 // aren't supported. They return false on IE (#2968). 262 isFunction: function( obj ) { 263 return jQuery.type( obj ) === "function"; 264 }, 265 266 isArray: Array.isArray || function( obj ) { 267 return jQuery.type( obj ) === "array"; 268 }, 269 270 isWindow: function( obj ) { 271 /* jshint eqeqeq: false */ 272 return obj != null && obj == obj.window; 273 }, 274 275 isNumeric: function( obj ) { 276 277 // parseFloat NaNs numeric-cast false positives (null|true|false|"") 278 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 279 // subtraction forces infinities to NaN 280 // adding 1 corrects loss of precision from parseFloat (#15100) 281 var realStringObj = obj && obj.toString(); 282 return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; 283 }, 284 285 isEmptyObject: function( obj ) { 286 var name; 287 for ( name in obj ) { 288 return false; 289 } 290 return true; 291 }, 292 293 isPlainObject: function( obj ) { 294 var key; 295 296 // Must be an Object. 297 // Because of IE, we also have to check the presence of the constructor property. 298 // Make sure that DOM nodes and window objects don't pass through, as well 299 if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 300 return false; 301 } 302 303 try { 304 305 // Not own constructor property must be Object 306 if ( obj.constructor && 307 !hasOwn.call( obj, "constructor" ) && 308 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { 309 return false; 310 } 311 } catch ( e ) { 312 313 // IE8,9 Will throw exceptions on certain host objects #9897 314 return false; 315 } 316 317 // Support: IE<9 318 // Handle iteration over inherited properties before own properties. 319 if ( !support.ownFirst ) { 320 for ( key in obj ) { 321 return hasOwn.call( obj, key ); 322 } 323 } 324 325 // Own properties are enumerated firstly, so to speed up, 326 // if last one is own, then all properties are own. 327 for ( key in obj ) {} 328 329 return key === undefined || hasOwn.call( obj, key ); 330 }, 331 332 type: function( obj ) { 333 if ( obj == null ) { 334 return obj + ""; 335 } 336 return typeof obj === "object" || typeof obj === "function" ? 337 class2type[ toString.call( obj ) ] || "object" : 338 typeof obj; 339 }, 340 341 // Workarounds based on findings by Jim Driscoll 342 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 343 globalEval: function( data ) { 344 if ( data && jQuery.trim( data ) ) { 345 346 // We use execScript on Internet Explorer 347 // We use an anonymous function so that context is window 348 // rather than jQuery in Firefox 349 ( window.execScript || function( data ) { 350 window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation 351 } )( data ); 352 } 353 }, 354 355 // Convert dashed to camelCase; used by the css and data modules 356 // Microsoft forgot to hump their vendor prefix (#9572) 357 camelCase: function( string ) { 358 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 359 }, 360
361 nodeName: function( elem, name ) { 362 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 363 }, 364 365 each: function( obj, callback ) { 366 var length, i = 0; 367 368 if ( isArrayLike( obj ) ) { 369 length = obj.length; 370 for ( ; i < length; i++ ) { 371 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 372 break; 373 } 374 } 375 } else { 376 for ( i in obj ) { 377 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 378 break; 379 } 380 } 381 } 382 383 return obj; 384 }, 385 386 // Support: Android<4.1, IE<9 387 trim: function( text ) { 388 return text == null ? 389 "" : 390 ( text + "" ).replace( rtrim, "" ); 391 }, 392 393 // results is for internal usage only 394 makeArray: function( arr, results ) { 395 var ret = results || []; 396 397 if ( arr != null ) { 398 if ( isArrayLike( Object( arr ) ) ) { 399 jQuery.merge( ret, 400 typeof arr === "string" ? 401 [ arr ] : arr 402 ); 403 } else { 404 push.call( ret, arr ); 405 } 406 } 407 408 return ret; 409 }, 410 411 inArray: function( elem, arr, i ) { 412 var len; 413 414 if ( arr ) { 415 if ( indexOf ) { 416 return indexOf.call( arr, elem, i ); 417 } 418 419 len = arr.length; 420 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; 421 422 for ( ; i < len; i++ ) { 423 424 // Skip accessing in sparse arrays 425 if ( i in arr && arr[ i ] === elem ) { 426 return i; 427 } 428 } 429 } 430 431 return -1; 432 }, 433 434 merge: function( first, second ) { 435 var len = +second.length, 436 j = 0, 437 i = first.length; 438 439 while ( j < len ) { 440 first[ i++ ] = second[ j++ ]; 441 } 442 443 // Support: IE<9 444 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) 445 if ( len !== len ) { 446 while ( second[ j ] !== undefined ) { 447 first[ i++ ] = second[ j++ ]; 448 } 449 } 450 451 first.length = i; 452 453 return first; 454 }, 455 456 grep: function( elems, callback, invert ) { 457 var callbackInverse, 458 matches = [], 459 i = 0, 460 length = elems.length, 461 callbackExpect = !invert; 462 463 // Go through the array, only saving the items 464 // that pass the validator function 465 for ( ; i < length; i++ ) { 466 callbackInverse = !callback( elems[ i ], i ); 467 if ( callbackInverse !== callbackExpect ) { 468 matches.push( elems[ i ] ); 469 } 470 } 471 472 return matches; 473 }, 474 475 // arg is for internal usage only 476 map: function( elems, callback, arg ) { 477 var length, value, 478 i = 0, 479 ret = []; 480 481 // Go through the array, translating each of the items to their new values 482 if ( isArrayLike( elems ) ) { 483 length = elems.length; 484 for ( ; i < length; i++ ) { 485 value = callback( elems[ i ], i, arg ); 486 487 if ( value != null ) { 488 ret.push( value ); 489 } 490 } 491 492 // Go through every key on the object, 493 } else { 494 for ( i in elems ) { 495 value = callback( elems[ i ], i, arg ); 496 497 if ( value != null ) { 498 ret.push( value ); 499 } 500 } 501 } 502 503 // Flatten any nested arrays 504 return concat.apply( [], ret ); 505 }, 506 507 // A global GUID counter for objects 508 guid: 1, 509 510 // Bind a function to a context, optionally partially applying any 511 // arguments. 512 proxy: function( fn, context ) { 513 var args, proxy, tmp; 514 515 if ( typeof context === "string" ) { 516 tmp = fn[ context ]; 517 context = fn; 518 fn = tmp; 519 } 520 521 // Quick check to determine if target is callable, in the spec 522 // this throws a TypeError, but we will just return undefined. 523 if ( !jQuery.isFunction( fn ) ) { 524 return undefined; 525 } 526 527 // Simulated bind 528 args = slice.call( arguments, 2 ); 529 proxy = function() { 530 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 531 }; 532 533 // Set the guid of unique handler to the same of original handler, so it can be removed 534 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 535 536 return proxy; 537 }, 538 539 now: function() { 540 return +( new Date() ); 541 }, 542 543 // jQuery.support is not used in Core but other projects attach their 544 // properties to it so it needs to exist. 545 support: support 546} ); 547 548// JSHint would error on this code due to the Symbol not being defined in ES5. 549// Defining this global in .jshintrc would create a danger of using the global 550// unguarded in another place, it seems safer to just disable JSHint for these 551// three lines. 552/* jshint ignore: start */ 553if ( typeof Symbol === "function" ) { 554 jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; 555} 556/* jshint ignore: end */ 557 558// Populate the class2type map 559jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 560function( i, name ) { 561 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 562} ); 563 564function isArrayLike( obj ) { 565 566 // Support: iOS 8.2 (not reproducible in simulator) 567 // `in` check used to prevent JIT error (gh-2145) 568 // hasOwn isn't used here due to false negatives 569 // regarding Nodelist length in IE 570 var length = !!obj && "length" in obj && obj.length, 571 type = jQuery.type( obj ); 572 573 if ( type === "function" || jQuery.isWindow( obj ) ) { 574 return false;
vendor: 26,428 bytes, lines 575-1499
575 } 576 577 return type === "array" || length === 0 || 578 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 579} 580var Sizzle = 581/*! 582 * Sizzle CSS Selector Engine v2.2.1 583 * http://sizzlejs.com/ 584 * 585 * Copyright jQuery Foundation and other contributors 586 * Released under the MIT license 587 * http://jquery.org/license 588 * 589 * Date: 2015-10-17 590 */ 591(function( window ) { 592 593var i, 594 support, 595 Expr, 596 getText, 597 isXML, 598 tokenize, 599 compile, 600 select, 601 outermostContext, 602 sortInput, 603 hasDuplicate, 604 605 // Local document vars 606 setDocument, 607 document, 608 docElem, 609 documentIsHTML, 610 rbuggyQSA, 611 rbuggyMatches, 612 matches, 613 contains, 614 615 // Instance-specific data 616 expando = "sizzle" + 1 * new Date(), 617 preferredDoc = window.document, 618 dirruns = 0, 619 done = 0, 620 classCache = createCache(), 621 tokenCache = createCache(), 622 compilerCache = createCache(), 623 sortOrder = function( a, b ) { 624 if ( a === b ) { 625 hasDuplicate = true; 626 } 627 return 0; 628 }, 629 630 // General-purpose constants 631 MAX_NEGATIVE = 1 << 31, 632 633 // Instance methods 634 hasOwn = ({}).hasOwnProperty, 635 arr = [], 636 pop = arr.pop, 637 push_native = arr.push, 638 push = arr.push, 639 slice = arr.slice, 640 // Use a stripped-down indexOf as it's faster than native 641 // http://jsperf.com/thor-indexof-vs-for/5 642 indexOf = function( list, elem ) { 643 var i = 0, 644 len = list.length; 645 for ( ; i < len; i++ ) { 646 if ( list[i] === elem ) { 647 return i; 648 } 649 } 650 return -1; 651 }, 652 653 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 654 655 // Regular expressions 656 657 // http://www.w3.org/TR/css3-selectors/#whitespace 658 whitespace = "[\\x20\\t\\r\\n\\f]", 659 660 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 661 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", 662 663 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 664 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 665 // Operator (capture 2) 666 "*([*^$|!~]?=)" + whitespace + 667 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 668 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 669 "*\\]", 670 671 pseudos = ":(" + identifier + ")(?:\\((" + 672 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 673 // 1. quoted (capture 3; capture 4 or capture 5) 674 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 675 // 2. simple (capture 6) 676 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 677 // 3. anything else (capture 2) 678 ".*" + 679 ")\\)|)", 680 681 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 682 rwhitespace = new RegExp( whitespace + "+", "g" ), 683 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 684 685 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 686 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 687 688 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), 689 690 rpseudo = new RegExp( pseudos ), 691 ridentifier = new RegExp( "^" + identifier + "$" ), 692 693 matchExpr = { 694 "ID": new RegExp( "^#(" + identifier + ")" ), 695 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 696 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 697 "ATTR": new RegExp( "^" + attributes ), 698 "PSEUDO": new RegExp( "^" + pseudos ), 699 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 700 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 701 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 702 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 703 // For use in libraries implementing .is() 704 // We use this for POS matching in `select` 705 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 706 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 707 }, 708 709 rinputs = /^(?:input|select|textarea|button)$/i, 710 rheader = /^h\d$/i, 711 712 rnative = /^[^{]+\{\s*\[native \w/, 713 714 // Easily-parseable/retrievable ID or TAG or CLASS selectors 715 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 716 717 rsibling = /[+~]/, 718 rescape = /'|\\/g, 719 720 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 721 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 722 funescape = function( _, escaped, escapedWhitespace ) { 723 var high = "0x" + escaped - 0x10000; 724 // NaN means non-codepoint 725 // Support: Firefox<24 726 // Workaround erroneous numeric interpretation of +"0x" 727 return high !== high || escapedWhitespace ? 728 escaped : 729 high < 0 ? 730 // BMP codepoint 731 String.fromCharCode( high + 0x10000 ) : 732 // Supplemental Plane codepoint (surrogate pair) 733 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 734 }, 735 736 // Used for iframes 737 // See setDocument() 738 // Removing the function wrapper causes a "Permission Denied" 739 // error in IE 740 unloadHandler = function() { 741 setDocument(); 742 }; 743 744// Optimize for push.apply( _, NodeList ) 745try { 746 push.apply( 747 (arr = slice.call( preferredDoc.childNodes )), 748 preferredDoc.childNodes 749 ); 750 // Support: Android<4.0 751 // Detect silently failing push.apply 752 arr[ preferredDoc.childNodes.length ].nodeType; 753} catch ( e ) { 754 push = { apply: arr.length ? 755 756 // Leverage slice if possible 757 function( target, els ) { 758 push_native.apply( target, slice.call(els) ); 759 } : 760 761 // Support: IE<9 762 // Otherwise append directly 763 function( target, els ) { 764 var j = target.length, 765 i = 0; 766 // Can't trust NodeList.length 767 while ( (target[j++] = els[i++]) ) {} 768 target.length = j - 1; 769 } 770 }; 771} 772 773function Sizzle( selector, context, results, seed ) { 774 var m, i, elem, nid, nidselect, match, groups, newSelector, 775 newContext = context && context.ownerDocument, 776 777 // nodeType defaults to 9, since context defaults to document 778 nodeType = context ? context.nodeType : 9; 779 780 results = results || []; 781 782 // Return early from calls with invalid selector or context 783 if ( typeof selector !== "string" || !selector || 784 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 785 786 return results; 787 } 788 789 // Try to shortcut find operations (as opposed to filters) in HTML documents 790 if ( !seed ) { 791 792 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 793 setDocument( context ); 794 } 795 context = context || document; 796 797 if ( documentIsHTML ) { 798 799 // If the selector is sufficiently simple, try using a "get*By*" DOM method 800 // (excepting DocumentFragment context, where the methods don't exist) 801 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 802 803 // ID selector 804 if ( (m = match[1]) ) { 805 806 // Document context 807 if ( nodeType === 9 ) { 808 if ( (elem = context.getElementById( m )) ) { 809 810 // Support: IE, Opera, Webkit 811 // TODO: identify versions 812 // getElementById can match elements by name instead of ID 813 if ( elem.id === m ) { 814 results.push( elem ); 815 return results; 816 } 817 } else { 818 return results; 819 } 820 821 // Element context 822 } else { 823 824 // Support: IE, Opera, Webkit 825 // TODO: identify versions 826 // getElementById can match elements by name instead of ID 827 if ( newContext && (elem = newContext.getElementById( m )) && 828 contains( context, elem ) && 829 elem.id === m ) { 830 831 results.push( elem ); 832 return results; 833 } 834 } 835 836 // Type selector 837 } else if ( match[2] ) { 838 push.apply( results, context.getElementsByTagName( selector ) ); 839 return results; 840 841 // Class selector 842 } else if ( (m = match[3]) && support.getElementsByClassName && 843 context.getElementsByClassName ) { 844 845 push.apply( results, context.getElementsByClassName( m ) ); 846 return results; 847 } 848 } 849 850 // Take advantage of querySelectorAll 851 if ( support.qsa && 852 !compilerCache[ selector + " " ] && 853 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { 854 855 if ( nodeType !== 1 ) { 856 newContext = context; 857 newSelector = selector; 858 859 // qSA looks outside Element context, which is not what we want 860 // Thanks to Andrew Dupont for this workaround technique 861 // Support: IE <=8 862 // Exclude object elements 863 } else if ( context.nodeName.toLowerCase() !== "object" ) { 864 865 // Capture the context ID, setting it first if necessary 866 if ( (nid = context.getAttribute( "id" )) ) { 867 nid = nid.replace( rescape, "\\$&" ); 868 } else { 869 context.setAttribute( "id", (nid = expando) ); 870 } 871 872 // Prefix every selector in the list 873 groups = tokenize( selector ); 874 i = groups.length; 875 nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; 876 while ( i-- ) { 877 groups[i] = nidselect + " " + toSelector( groups[i] ); 878 } 879 newSelector = groups.join( "," ); 880 881 // Expand context for sibling selectors 882 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 883 context; 884 } 885 886 if ( newSelector ) { 887 try { 888 push.apply( results, 889 newContext.querySelectorAll( newSelector ) 890 ); 891 return results; 892 } catch ( qsaError ) { 893 } finally { 894 if ( nid === expando ) { 895 context.removeAttribute( "id" ); 896 } 897 } 898 } 899 } 900 } 901 } 902 903 // All others 904 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 905} 906 907/** 908 * Create key-value caches of limited size 909 * @returns {function(string, object)} Returns the Object data after storing it on itself with 910 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 911 * deleting the oldest entry 912 */ 913function createCache() { 914 var keys = []; 915 916 function cache( key, value ) { 917 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 918 if ( keys.push( key + " " ) > Expr.cacheLength ) { 919 // Only keep the most recent entries 920 delete cache[ keys.shift() ]; 921 } 922 return (cache[ key + " " ] = value); 923 } 924 return cache; 925} 926 927/** 928 * Mark a function for special use by Sizzle 929 * @param {Function} fn The function to mark 930 */ 931function markFunction( fn ) { 932 fn[ expando ] = true; 933 return fn; 934} 935 936/** 937 * Support testing using an element 938 * @param {Function} fn Passed the created div and expects a boolean result 939 */ 940function assert( fn ) { 941 var div = document.createElement("div"); 942 943 try { 944 return !!fn( div ); 945 } catch (e) { 946 return false; 947 } finally { 948 // Remove from its parent by default 949 if ( div.parentNode ) { 950 div.parentNode.removeChild( div ); 951 } 952 // release memory in IE 953 div = null; 954 } 955} 956 957/** 958 * Adds the same handler for all of the specified attrs 959 * @param {String} attrs Pipe-separated list of attributes 960 * @param {Function} handler The method that will be applied 961 */ 962function addHandle( attrs, handler ) { 963 var arr = attrs.split("|"), 964 i = arr.length; 965 966 while ( i-- ) { 967 Expr.attrHandle[ arr[i] ] = handler; 968 } 969} 970 971/** 972 * Checks document order of two siblings 973 * @param {Element} a 974 * @param {Element} b 975 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 976 */ 977function siblingCheck( a, b ) { 978 var cur = b && a, 979 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 980 ( ~b.sourceIndex || MAX_NEGATIVE ) - 981 ( ~a.sourceIndex || MAX_NEGATIVE ); 982 983 // Use IE sourceIndex if available on both nodes 984 if ( diff ) { 985 return diff; 986 } 987 988 // Check if b follows a 989 if ( cur ) { 990 while ( (cur = cur.nextSibling) ) { 991 if ( cur === b ) { 992 return -1; 993 } 994 } 995 } 996 997 return a ? 1 : -1; 998} 999 1000/** 1001 * Returns a function to use in pseudos for input types 1002 * @param {String} type 1003 */ 1004function createInputPseudo( type ) { 1005 return function( elem ) { 1006 var name = elem.nodeName.toLowerCase(); 1007 return name === "input" && elem.type === type; 1008 }; 1009} 1010 1011/** 1012 * Returns a function to use in pseudos for buttons 1013 * @param {String} type 1014 */ 1015function createButtonPseudo( type ) { 1016 return function( elem ) { 1017 var name = elem.nodeName.toLowerCase(); 1018 return (name === "input" || name === "button") && elem.type === type; 1019 }; 1020} 1021 1022/** 1023 * Returns a function to use in pseudos for positionals 1024 * @param {Function} fn 1025 */ 1026function createPositionalPseudo( fn ) { 1027 return markFunction(function( argument ) { 1028 argument = +argument; 1029 return markFunction(function( seed, matches ) { 1030 var j, 1031 matchIndexes = fn( [], seed.length, argument ), 1032 i = matchIndexes.length; 1033 1034 // Match elements found at the specified indexes 1035 while ( i-- ) { 1036 if ( seed[ (j = matchIndexes[i]) ] ) { 1037 seed[j] = !(matches[j] = seed[j]); 1038 } 1039 } 1040 }); 1041 }); 1042} 1043 1044/** 1045 * Checks a node for validity as a Sizzle context 1046 * @param {Element|Object=} context 1047 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1048 */ 1049function testContext( context ) { 1050 return context && typeof context.getElementsByTagName !== "undefined" && context; 1051} 1052 1053// Expose support vars for convenience 1054support = Sizzle.support = {}; 1055 1056/** 1057 * Detects XML nodes 1058 * @param {Element|Object} elem An element or a document 1059 * @returns {Boolean} True iff elem is a non-HTML XML node 1060 */ 1061isXML = Sizzle.isXML = function( elem ) { 1062 // documentElement is verified for cases where it doesn't yet exist 1063 // (such as loading iframes in IE - #4833) 1064 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 1065 return documentElement ? documentElement.nodeName !== "HTML" : false; 1066}; 1067 1068/** 1069 * Sets document-related variables once based on the current document 1070 * @param {Element|Object} [doc] An element or document object to use to set the document 1071 * @returns {Object} Returns the current document 1072 */ 1073setDocument = Sizzle.setDocument = function( node ) { 1074 var hasCompare, parent, 1075 doc = node ? node.ownerDocument || node : preferredDoc; 1076 1077 // Return early if doc is invalid or already selected 1078 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 1079 return document; 1080 } 1081 1082 // Update global variables 1083 document = doc; 1084 docElem = document.documentElement; 1085 documentIsHTML = !isXML( document ); 1086 1087 // Support: IE 9-11, Edge 1088 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 1089 if ( (parent = document.defaultView) && parent.top !== parent ) { 1090 // Support: IE 11 1091 if ( parent.addEventListener ) { 1092 parent.addEventListener( "unload", unloadHandler, false ); 1093 1094 // Support: IE 9 - 10 only 1095 } else if ( parent.attachEvent ) { 1096 parent.attachEvent( "onunload", unloadHandler ); 1097 } 1098 } 1099 1100 /* Attributes 1101 ---------------------------------------------------------------------- */ 1102 1103 // Support: IE<8 1104 // Verify that getAttribute really returns attributes and not properties 1105 // (excepting IE8 booleans) 1106 support.attributes = assert(function( div ) { 1107 div.className = "i"; 1108 return !div.getAttribute("className"); 1109 }); 1110 1111 /* getElement(s)By* 1112 ---------------------------------------------------------------------- */ 1113 1114 // Check if getElementsByTagName("*") returns only elements 1115 support.getElementsByTagName = assert(function( div ) { 1116 div.appendChild( document.createComment("") ); 1117 return !div.getElementsByTagName("*").length; 1118 }); 1119 1120 // Support: IE<9 1121 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 1122 1123 // Support: IE<10 1124 // Check if getElementById returns elements by name 1125 // The broken getElementById methods don't pick up programatically-set names, 1126 // so use a roundabout getElementsByName test 1127 support.getById = assert(function( div ) { 1128 docElem.appendChild( div ).id = expando; 1129 return !document.getElementsByName || !document.getElementsByName( expando ).length; 1130 }); 1131 1132 // ID find and filter 1133 if ( support.getById ) { 1134 Expr.find["ID"] = function( id, context ) { 1135 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1136 var m = context.getElementById( id ); 1137 return m ? [ m ] : []; 1138 } 1139 }; 1140 Expr.filter["ID"] = function( id ) { 1141 var attrId = id.replace( runescape, funescape ); 1142 return function( elem ) { 1143 return elem.getAttribute("id") === attrId; 1144 }; 1145 }; 1146 } else { 1147 // Support: IE6/7 1148 // getElementById is not reliable as a find shortcut 1149 delete Expr.find["ID"]; 1150 1151 Expr.filter["ID"] = function( id ) { 1152 var attrId = id.replace( runescape, funescape ); 1153 return function( elem ) { 1154 var node = typeof elem.getAttributeNode !== "undefined" && 1155 elem.getAttributeNode("id"); 1156 return node && node.value === attrId; 1157 }; 1158 }; 1159 } 1160 1161 // Tag 1162 Expr.find["TAG"] = support.getElementsByTagName ? 1163 function( tag, context ) { 1164 if ( typeof context.getElementsByTagName !== "undefined" ) { 1165 return context.getElementsByTagName( tag ); 1166 1167 // DocumentFragment nodes don't have gEBTN 1168 } else if ( support.qsa ) { 1169 return context.querySelectorAll( tag ); 1170 } 1171 } : 1172 1173 function( tag, context ) { 1174 var elem, 1175 tmp = [], 1176 i = 0, 1177 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1178 results = context.getElementsByTagName( tag ); 1179 1180 // Filter out possible comments 1181 if ( tag === "*" ) { 1182 while ( (elem = results[i++]) ) { 1183 if ( elem.nodeType === 1 ) { 1184 tmp.push( elem ); 1185 } 1186 } 1187 1188 return tmp; 1189 } 1190 return results; 1191 }; 1192 1193 // Class 1194 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 1195 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1196 return context.getElementsByClassName( className ); 1197 } 1198 }; 1199 1200 /* QSA/matchesSelector 1201 ---------------------------------------------------------------------- */ 1202 1203 // QSA and matchesSelector support 1204 1205 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1206 rbuggyMatches = []; 1207 1208 // qSa(:focus) reports false when true (Chrome 21) 1209 // We allow this because of a bug in IE8/9 that throws an error 1210 // whenever `document.activeElement` is accessed on an iframe 1211 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1212 // See http://bugs.jquery.com/ticket/13378 1213 rbuggyQSA = []; 1214 1215 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { 1216 // Build QSA regex 1217 // Regex strategy adopted from Diego Perini 1218 assert(function( div ) { 1219 // Select is set to empty string on purpose 1220 // This is to test IE's treatment of not explicitly 1221 // setting a boolean content attribute, 1222 // since its presence should be enough 1223 // http://bugs.jquery.com/ticket/12359 1224 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + 1225 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 1226 "<option selected=''></option></select>"; 1227 1228 // Support: IE8, Opera 11-12.16 1229 // Nothing should be selected when empty strings follow ^= or $= or *= 1230 // The test attribute must be unknown in Opera but "safe" for WinRT 1231 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1232 if ( div.querySelectorAll("[msallowcapture^='']").length ) { 1233 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 1234 } 1235 1236 // Support: IE8 1237 // Boolean attributes and "value" are not treated correctly 1238 if ( !div.querySelectorAll("[selected]").length ) { 1239 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1240 } 1241 1242 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 1243 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1244 rbuggyQSA.push("~="); 1245 } 1246 1247 // Webkit/Opera - :checked should return selected option elements 1248 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1249 // IE8 throws error here and will not see later tests 1250 if ( !div.querySelectorAll(":checked").length ) { 1251 rbuggyQSA.push(":checked"); 1252 } 1253 1254 // Support: Safari 8+, iOS 8+ 1255 // https://bugs.webkit.org/show_bug.cgi?id=136851 1256 // In-page `selector#id sibing-combinator selector` fails 1257 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { 1258 rbuggyQSA.push(".#.+[+~]"); 1259 } 1260 }); 1261 1262 assert(function( div ) { 1263 // Support: Windows 8 Native Apps 1264 // The type and name attributes are restricted during .innerHTML assignment 1265 var input = document.createElement("input"); 1266 input.setAttribute( "type", "hidden" ); 1267 div.appendChild( input ).setAttribute( "name", "D" ); 1268 1269 // Support: IE8 1270 // Enforce case-sensitivity of name attribute 1271 if ( div.querySelectorAll("[name=d]").length ) { 1272 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 1273 } 1274 1275 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1276 // IE8 throws error here and will not see later tests 1277 if ( !div.querySelectorAll(":enabled").length ) { 1278 rbuggyQSA.push( ":enabled", ":disabled" ); 1279 } 1280 1281 // Opera 10-11 does not throw on post-comma invalid pseudos 1282 div.querySelectorAll("*,:x"); 1283 rbuggyQSA.push(",.*:"); 1284 }); 1285 } 1286 1287 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 1288 docElem.webkitMatchesSelector || 1289 docElem.mozMatchesSelector || 1290 docElem.oMatchesSelector || 1291 docElem.msMatchesSelector) )) ) { 1292 1293 assert(function( div ) { 1294 // Check to see if it's possible to do matchesSelector 1295 // on a disconnected node (IE 9) 1296 support.disconnectedMatch = matches.call( div, "div" ); 1297 1298 // This should fail with an exception 1299 // Gecko does not error, returns false instead 1300 matches.call( div, "[s!='']:x" ); 1301 rbuggyMatches.push( "!=", pseudos ); 1302 }); 1303 } 1304 1305 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 1306 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 1307 1308 /* Contains 1309 ---------------------------------------------------------------------- */ 1310 hasCompare = rnative.test( docElem.compareDocumentPosition ); 1311 1312 // Element contains another 1313 // Purposefully self-exclusive 1314 // As in, an element does not contain itself 1315 contains = hasCompare || rnative.test( docElem.contains ) ? 1316 function( a, b ) { 1317 var adown = a.nodeType === 9 ? a.documentElement : a, 1318 bup = b && b.parentNode; 1319 return a === bup || !!( bup && bup.nodeType === 1 && ( 1320 adown.contains ? 1321 adown.contains( bup ) : 1322 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1323 )); 1324 } : 1325 function( a, b ) { 1326 if ( b ) { 1327 while ( (b = b.parentNode) ) { 1328 if ( b === a ) { 1329 return true; 1330 } 1331 } 1332 } 1333 return false; 1334 }; 1335 1336 /* Sorting 1337 ---------------------------------------------------------------------- */ 1338 1339 // Document order sorting 1340 sortOrder = hasCompare ? 1341 function( a, b ) { 1342 1343 // Flag for duplicate removal 1344 if ( a === b ) { 1345 hasDuplicate = true; 1346 return 0; 1347 } 1348 1349 // Sort on method existence if only one input has compareDocumentPosition 1350 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1351 if ( compare ) { 1352 return compare; 1353 } 1354 1355 // Calculate position if both inputs belong to the same document 1356 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 1357 a.compareDocumentPosition( b ) : 1358 1359 // Otherwise we know they are disconnected 1360 1; 1361 1362 // Disconnected nodes 1363 if ( compare & 1 || 1364 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 1365 1366 // Choose the first element that is related to our preferred document 1367 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 1368 return -1; 1369 } 1370 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 1371 return 1; 1372 } 1373 1374 // Maintain original order 1375 return sortInput ? 1376 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1377 0; 1378 } 1379 1380 return compare & 4 ? -1 : 1; 1381 } : 1382 function( a, b ) { 1383 // Exit early if the nodes are identical 1384 if ( a === b ) { 1385 hasDuplicate = true; 1386 return 0; 1387 } 1388 1389 var cur, 1390 i = 0, 1391 aup = a.parentNode, 1392 bup = b.parentNode, 1393 ap = [ a ], 1394 bp = [ b ]; 1395 1396 // Parentless nodes are either documents or disconnected 1397 if ( !aup || !bup ) { 1398 return a === document ? -1 : 1399 b === document ? 1 : 1400 aup ? -1 : 1401 bup ? 1 : 1402 sortInput ? 1403 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1404 0; 1405 1406 // If the nodes are siblings, we can do a quick check 1407 } else if ( aup === bup ) { 1408 return siblingCheck( a, b ); 1409 } 1410 1411 // Otherwise we need full lists of their ancestors for comparison 1412 cur = a; 1413 while ( (cur = cur.parentNode) ) { 1414 ap.unshift( cur ); 1415 } 1416 cur = b; 1417 while ( (cur = cur.parentNode) ) { 1418 bp.unshift( cur ); 1419 } 1420 1421 // Walk down the tree looking for a discrepancy 1422 while ( ap[i] === bp[i] ) { 1423 i++; 1424 } 1425 1426 return i ? 1427 // Do a sibling check if the nodes have a common ancestor 1428 siblingCheck( ap[i], bp[i] ) : 1429 1430 // Otherwise nodes in our document sort first 1431 ap[i] === preferredDoc ? -1 : 1432 bp[i] === preferredDoc ? 1 : 1433 0; 1434 }; 1435 1436 return document; 1437}; 1438 1439Sizzle.matches = function( expr, elements ) { 1440 return Sizzle( expr, null, null, elements ); 1441}; 1442 1443Sizzle.matchesSelector = function( elem, expr ) { 1444 // Set document vars if needed 1445 if ( ( elem.ownerDocument || elem ) !== document ) { 1446 setDocument( elem ); 1447 } 1448 1449 // Make sure that attribute selectors are quoted 1450 expr = expr.replace( rattributeQuotes, "='$1']" ); 1451 1452 if ( support.matchesSelector && documentIsHTML && 1453 !compilerCache[ expr + " " ] && 1454 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 1455 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1456 1457 try { 1458 var ret = matches.call( elem, expr ); 1459 1460 // IE 9's matchesSelector returns false on disconnected nodes 1461 if ( ret || support.disconnectedMatch || 1462 // As well, disconnected nodes are said to be in a document 1463 // fragment in IE 9 1464 elem.document && elem.document.nodeType !== 11 ) { 1465 return ret; 1466 } 1467 } catch (e) {} 1468 } 1469 1470 return Sizzle( expr, document, null, [ elem ] ).length > 0; 1471}; 1472 1473Sizzle.contains = function( context, elem ) { 1474 // Set document vars if needed 1475 if ( ( context.ownerDocument || context ) !== document ) { 1476 setDocument( context ); 1477 } 1478 return contains( context, elem ); 1479}; 1480 1481Sizzle.attr = function( elem, name ) { 1482 // Set document vars if needed 1483 if ( ( elem.ownerDocument || elem ) !== document ) { 1484 setDocument( elem ); 1485 } 1486 1487 var fn = Expr.attrHandle[ name.toLowerCase() ], 1488 // Don't get fooled by Object.prototype properties (jQuery #13807) 1489 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1490 fn( elem, name, !documentIsHTML ) : 1491 undefined; 1492 1493 return val !== undefined ? 1494 val : 1495 support.attributes || !documentIsHTML ? 1496 elem.getAttribute( name ) : 1497 (val = elem.getAttributeNode(name)) && val.specified ? 1498 val.value : 1499 null
vendor: 13,569 bytes, lines 1499-1969
1499; 1500}; 1501 1502Sizzle.error = function( msg ) { 1503 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1504}; 1505 1506/** 1507 * Document sorting and removing duplicates 1508 * @param {ArrayLike} results 1509 */ 1510Sizzle.uniqueSort = function( results ) { 1511 var elem, 1512 duplicates = [], 1513 j = 0, 1514 i = 0; 1515 1516 // Unless we *know* we can detect duplicates, assume their presence 1517 hasDuplicate = !support.detectDuplicates; 1518 sortInput = !support.sortStable && results.slice( 0 ); 1519 results.sort( sortOrder ); 1520 1521 if ( hasDuplicate ) { 1522 while ( (elem = results[i++]) ) { 1523 if ( elem === results[ i ] ) { 1524 j = duplicates.push( i ); 1525 } 1526 } 1527 while ( j-- ) { 1528 results.splice( duplicates[ j ], 1 ); 1529 } 1530 } 1531 1532 // Clear input after sorting to release objects 1533 // See https://github.com/jquery/sizzle/pull/225 1534 sortInput = null; 1535 1536 return results; 1537}; 1538 1539/** 1540 * Utility function for retrieving the text value of an array of DOM nodes 1541 * @param {Array|Element} elem 1542 */ 1543getText = Sizzle.getText = function( elem ) { 1544 var node, 1545 ret = "", 1546 i = 0, 1547 nodeType = elem.nodeType; 1548 1549 if ( !nodeType ) { 1550 // If no nodeType, this is expected to be an array 1551 while ( (node = elem[i++]) ) { 1552 // Do not traverse comment nodes 1553 ret += getText( node ); 1554 } 1555 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 1556 // Use textContent for elements 1557 // innerText usage removed for consistency of new lines (jQuery #11153) 1558 if ( typeof elem.textContent === "string" ) { 1559 return elem.textContent; 1560 } else { 1561 // Traverse its children 1562 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1563 ret += getText( elem ); 1564 } 1565 } 1566 } else if ( nodeType === 3 || nodeType === 4 ) { 1567 return elem.nodeValue; 1568 } 1569 // Do not include comment or processing instruction nodes 1570 1571 return ret; 1572}; 1573 1574Expr = Sizzle.selectors = { 1575 1576 // Can be adjusted by the user 1577 cacheLength: 50, 1578 1579 createPseudo: markFunction, 1580 1581 match: matchExpr, 1582 1583 attrHandle: {}, 1584 1585 find: {}, 1586 1587 relative: { 1588 ">": { dir: "parentNode", first: true }, 1589 " ": { dir: "parentNode" }, 1590 "+": { dir: "previousSibling", first: true }, 1591 "~": { dir: "previousSibling" } 1592 }, 1593 1594 preFilter: { 1595 "ATTR": function( match ) { 1596 match[1] = match[1].replace( runescape, funescape ); 1597 1598 // Move the given value to match[3] whether quoted or unquoted 1599 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 1600 1601 if ( match[2] === "~=" ) { 1602 match[3] = " " + match[3] + " "; 1603 } 1604 1605 return match.slice( 0, 4 ); 1606 }, 1607 1608 "CHILD": function( match ) { 1609 /* matches from matchExpr["CHILD"] 1610 1 type (only|nth|...) 1611 2 what (child|of-type) 1612 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1613 4 xn-component of xn+y argument ([+-]?\d*n|) 1614 5 sign of xn-component 1615 6 x of xn-component 1616 7 sign of y-component 1617 8 y of y-component 1618 */ 1619 match[1] = match[1].toLowerCase(); 1620 1621 if ( match[1].slice( 0, 3 ) === "nth" ) { 1622 // nth-* requires argument 1623 if ( !match[3] ) { 1624 Sizzle.error( match[0] ); 1625 } 1626 1627 // numeric x and y parameters for Expr.filter.CHILD 1628 // remember that false/true cast respectively to 0/1 1629 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 1630 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 1631 1632 // other types prohibit arguments 1633 } else if ( match[3] ) { 1634 Sizzle.error( match[0] ); 1635 } 1636 1637 return match; 1638 }, 1639 1640 "PSEUDO": function( match ) { 1641 var excess, 1642 unquoted = !match[6] && match[2]; 1643 1644 if ( matchExpr["CHILD"].test( match[0] ) ) { 1645 return null; 1646 } 1647 1648 // Accept quoted arguments as-is 1649 if ( match[3] ) { 1650 match[2] = match[4] || match[5] || ""; 1651 1652 // Strip excess characters from unquoted arguments 1653 } else if ( unquoted && rpseudo.test( unquoted ) && 1654 // Get excess from tokenize (recursively) 1655 (excess = tokenize( unquoted, true )) && 1656 // advance to the next closing parenthesis 1657 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 1658 1659 // excess is a negative index 1660 match[0] = match[0].slice( 0, excess ); 1661 match[2] = unquoted.slice( 0, excess ); 1662 } 1663 1664 // Return only captures needed by the pseudo filter method (type and argument) 1665 return match.slice( 0, 3 ); 1666 } 1667 }, 1668 1669 filter: { 1670 1671 "TAG": function( nodeNameSelector ) { 1672 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1673 return nodeNameSelector === "*" ? 1674 function() { return true; } : 1675 function( elem ) { 1676 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1677 }; 1678 }, 1679 1680 "CLASS": function( className ) { 1681 var pattern = classCache[ className + " " ]; 1682 1683 return pattern || 1684 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 1685 classCache( className, function( elem ) { 1686 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 1687 }); 1688 }, 1689 1690 "ATTR": function( name, operator, check ) { 1691 return function( elem ) { 1692 var result = Sizzle.attr( elem, name ); 1693 1694 if ( result == null ) { 1695 return operator === "!="; 1696 } 1697 if ( !operator ) { 1698 return true; 1699 } 1700 1701 result += ""; 1702 1703 return operator === "=" ? result === check : 1704 operator === "!=" ? result !== check : 1705 operator === "^=" ? check && result.indexOf( check ) === 0 : 1706 operator === "*=" ? check && result.indexOf( check ) > -1 : 1707 operator === "$=" ? check && result.slice( -check.length ) === check : 1708 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 1709 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 1710 false; 1711 }; 1712 }, 1713 1714 "CHILD": function( type, what, argument, first, last ) { 1715 var simple = type.slice( 0, 3 ) !== "nth", 1716 forward = type.slice( -4 ) !== "last", 1717 ofType = what === "of-type"; 1718 1719 return first === 1 && last === 0 ? 1720 1721 // Shortcut for :nth-*(n) 1722 function( elem ) { 1723 return !!elem.parentNode; 1724 } : 1725 1726 function( elem, context, xml ) { 1727 var cache, uniqueCache, outerCache, node, nodeIndex, start, 1728 dir = simple !== forward ? "nextSibling" : "previousSibling", 1729 parent = elem.parentNode, 1730 name = ofType && elem.nodeName.toLowerCase(), 1731 useCache = !xml && !ofType, 1732 diff = false; 1733 1734 if ( parent ) { 1735 1736 // :(first|last|only)-(child|of-type) 1737 if ( simple ) { 1738 while ( dir ) { 1739 node = elem; 1740 while ( (node = node[ dir ]) ) { 1741 if ( ofType ? 1742 node.nodeName.toLowerCase() === name : 1743 node.nodeType === 1 ) { 1744 1745 return false; 1746 } 1747 } 1748 // Reverse direction for :only-* (if we haven't yet done so) 1749 start = dir = type === "only" && !start && "nextSibling"; 1750 } 1751 return true; 1752 } 1753 1754 start = [ forward ? parent.firstChild : parent.lastChild ]; 1755 1756 // non-xml :nth-child(...) stores cache data on `parent` 1757 if ( forward && useCache ) { 1758 1759 // Seek `elem` from a previously-cached index 1760 1761 // ...in a gzip-friendly way 1762 node = parent; 1763 outerCache = node[ expando ] || (node[ expando ] = {}); 1764 1765 // Support: IE <9 only 1766 // Defend against cloned attroperties (jQuery gh-1709) 1767 uniqueCache = outerCache[ node.uniqueID ] || 1768 (outerCache[ node.uniqueID ] = {}); 1769 1770 cache = uniqueCache[ type ] || []; 1771 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1772 diff = nodeIndex && cache[ 2 ]; 1773 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1774 1775 while ( (node = ++nodeIndex && node && node[ dir ] || 1776 1777 // Fallback to seeking `elem` from the start 1778 (diff = nodeIndex = 0) || start.pop()) ) { 1779 1780 // When found, cache indexes on `parent` and break 1781 if ( node.nodeType === 1 && ++diff && node === elem ) { 1782 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 1783 break; 1784 } 1785 } 1786 1787 } else { 1788 // Use previously-cached element index if available 1789 if ( useCache ) { 1790 // ...in a gzip-friendly way 1791 node = elem; 1792 outerCache = node[ expando ] || (node[ expando ] = {}); 1793 1794 // Support: IE <9 only 1795 // Defend against cloned attroperties (jQuery gh-1709) 1796 uniqueCache = outerCache[ node.uniqueID ] || 1797 (outerCache[ node.uniqueID ] = {}); 1798 1799 cache = uniqueCache[ type ] || []; 1800 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1801 diff = nodeIndex; 1802 } 1803 1804 // xml :nth-child(...) 1805 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1806 if ( diff === false ) { 1807 // Use the same loop as above to seek `elem` from the start 1808 while ( (node = ++nodeIndex && node && node[ dir ] || 1809 (diff = nodeIndex = 0) || start.pop()) ) { 1810 1811 if ( ( ofType ? 1812 node.nodeName.toLowerCase() === name : 1813 node.nodeType === 1 ) && 1814 ++diff ) { 1815 1816 // Cache the index of each encountered element 1817 if ( useCache ) { 1818 outerCache = node[ expando ] || (node[ expando ] = {}); 1819 1820 // Support: IE <9 only 1821 // Defend against cloned attroperties (jQuery gh-1709) 1822 uniqueCache = outerCache[ node.uniqueID ] || 1823 (outerCache[ node.uniqueID ] = {}); 1824 1825 uniqueCache[ type ] = [ dirruns, diff ]; 1826 } 1827 1828 if ( node === elem ) { 1829 break; 1830 } 1831 } 1832 } 1833 } 1834 } 1835 1836 // Incorporate the offset, then check against cycle size 1837 diff -= last; 1838 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1839 } 1840 }; 1841 }, 1842 1843 "PSEUDO": function( pseudo, argument ) { 1844 // pseudo-class names are case-insensitive 1845 // http://www.w3.org/TR/selectors/#pseudo-classes 1846 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1847 // Remember that setFilters inherits from pseudos 1848 var args, 1849 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1850 Sizzle.error( "unsupported pseudo: " + pseudo ); 1851 1852 // The user may use createPseudo to indicate that 1853 // arguments are needed to create the filter function 1854 // just as Sizzle does 1855 if ( fn[ expando ] ) { 1856 return fn( argument ); 1857 } 1858 1859 // But maintain support for old signatures 1860 if ( fn.length > 1 ) { 1861 args = [ pseudo, pseudo, "", argument ]; 1862 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1863 markFunction(function( seed, matches ) { 1864 var idx, 1865 matched = fn( seed, argument ), 1866 i = matched.length; 1867 while ( i-- ) { 1868 idx = indexOf( seed, matched[i] ); 1869 seed[ idx ] = !( matches[ idx ] = matched[i] ); 1870 } 1871 }) : 1872 function( elem ) { 1873 return fn( elem, 0, args ); 1874 }; 1875 } 1876 1877 return fn; 1878 } 1879 }, 1880 1881 pseudos: { 1882 // Potentially complex pseudos 1883 "not": markFunction(function( selector ) { 1884 // Trim the selector passed to compile 1885 // to avoid treating leading and trailing 1886 // spaces as combinators 1887 var input = [], 1888 results = [], 1889 matcher = compile( selector.replace( rtrim, "$1" ) ); 1890 1891 return matcher[ expando ] ? 1892 markFunction(function( seed, matches, context, xml ) { 1893 var elem, 1894 unmatched = matcher( seed, null, xml, [] ), 1895 i = seed.length; 1896 1897 // Match elements unmatched by `matcher` 1898 while ( i-- ) { 1899 if ( (elem = unmatched[i]) ) { 1900 seed[i] = !(matches[i] = elem); 1901 } 1902 } 1903 }) : 1904 function( elem, context, xml ) { 1905 input[0] = elem; 1906 matcher( input, null, xml, results ); 1907 // Don't keep the element (issue #299) 1908 input[0] = null; 1909 return !results.pop(); 1910 }; 1911 }), 1912 1913 "has": markFunction(function( selector ) { 1914 return function( elem ) { 1915 return Sizzle( selector, elem ).length > 0; 1916 }; 1917 }), 1918 1919 "contains": markFunction(function( text ) { 1920 text = text.replace( runescape, funescape ); 1921 return function( elem ) { 1922 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 1923 }; 1924 }), 1925 1926 // "Whether an element is represented by a :lang() selector 1927 // is based solely on the element's language value 1928 // being equal to the identifier C, 1929 // or beginning with the identifier C immediately followed by "-". 1930 // The matching of C against the element's language value is performed case-insensitively. 1931 // The identifier C does not have to be a valid language name." 1932 // http://www.w3.org/TR/selectors/#lang-pseudo 1933 "lang": markFunction( function( lang ) { 1934 // lang value must be a valid identifier 1935 if ( !ridentifier.test(lang || "") ) { 1936 Sizzle.error( "unsupported lang: " + lang ); 1937 } 1938 lang = lang.replace( runescape, funescape ).toLowerCase(); 1939 return function( elem ) { 1940 var elemLang; 1941 do { 1942 if ( (elemLang = documentIsHTML ? 1943 elem.lang : 1944 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 1945 1946 elemLang = elemLang.toLowerCase(); 1947 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1948 } 1949 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 1950 return false; 1951 }; 1952 }), 1953 1954 // Miscellaneous 1955 "target": function( elem ) { 1956 var hash = window.location && window.location.hash; 1957 return hash && hash.slice( 1 ) === elem.id; 1958 }, 1959 1960 "root": function( elem ) { 1961 return elem === docElem; 1962 }, 1963 1964 "focus": function( elem ) { 1965 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 1966 }, 1967 1968 // Boolean properties 1969 "enabled":
vendor: 6,738 bytes, lines 1969-2220
1969function( elem ) { 1970 return elem.disabled === false; 1971 }, 1972 1973 "disabled": function( elem ) { 1974 return elem.disabled === true; 1975 }, 1976 1977 "checked": function( elem ) { 1978 // In CSS3, :checked should return both checked and selected elements 1979 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1980 var nodeName = elem.nodeName.toLowerCase(); 1981 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 1982 }, 1983 1984 "selected": function( elem ) { 1985 // Accessing this property makes selected-by-default 1986 // options in Safari work properly 1987 if ( elem.parentNode ) { 1988 elem.parentNode.selectedIndex; 1989 } 1990 1991 return elem.selected === true; 1992 }, 1993 1994 // Contents 1995 "empty": function( elem ) { 1996 // http://www.w3.org/TR/selectors/#empty-pseudo 1997 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1998 // but not by others (comment: 8; processing instruction: 7; etc.) 1999 // nodeType < 6 works because attributes (2) do not appear as children 2000 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 2001 if ( elem.nodeType < 6 ) { 2002 return false; 2003 } 2004 } 2005 return true; 2006 }, 2007 2008 "parent": function( elem ) { 2009 return !Expr.pseudos["empty"]( elem ); 2010 }, 2011 2012 // Element/input types 2013 "header": function( elem ) { 2014 return rheader.test( elem.nodeName ); 2015 }, 2016 2017 "input": function( elem ) { 2018 return rinputs.test( elem.nodeName ); 2019 }, 2020 2021 "button": function( elem ) { 2022 var name = elem.nodeName.toLowerCase(); 2023 return name === "input" && elem.type === "button" || name === "button"; 2024 }, 2025 2026 "text": function( elem ) { 2027 var attr; 2028 return elem.nodeName.toLowerCase() === "input" && 2029 elem.type === "text" && 2030 2031 // Support: IE<8 2032 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 2033 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 2034 }, 2035 2036 // Position-in-collection 2037 "first": createPositionalPseudo(function() { 2038 return [ 0 ]; 2039 }), 2040 2041 "last": createPositionalPseudo(function( matchIndexes, length ) { 2042 return [ length - 1 ]; 2043 }), 2044 2045 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 2046 return [ argument < 0 ? argument + length : argument ]; 2047 }), 2048 2049 "even": createPositionalPseudo(function( matchIndexes, length ) { 2050 var i = 0; 2051 for ( ; i < length; i += 2 ) { 2052 matchIndexes.push( i ); 2053 } 2054 return matchIndexes; 2055 }), 2056 2057 "odd": createPositionalPseudo(function( matchIndexes, length ) { 2058 var i = 1; 2059 for ( ; i < length; i += 2 ) { 2060 matchIndexes.push( i ); 2061 } 2062 return matchIndexes; 2063 }), 2064 2065 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2066 var i = argument < 0 ? argument + length : argument; 2067 for ( ; --i >= 0; ) { 2068 matchIndexes.push( i ); 2069 } 2070 return matchIndexes; 2071 }), 2072 2073 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2074 var i = argument < 0 ? argument + length : argument; 2075 for ( ; ++i < length; ) { 2076 matchIndexes.push( i ); 2077 } 2078 return matchIndexes; 2079 }) 2080 } 2081}; 2082 2083Expr.pseudos["nth"] = Expr.pseudos["eq"]; 2084 2085// Add button/input type pseudos 2086for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2087 Expr.pseudos[ i ] = createInputPseudo( i ); 2088} 2089for ( i in { submit: true, reset: true } ) { 2090 Expr.pseudos[ i ] = createButtonPseudo( i ); 2091} 2092 2093// Easy API for creating new setFilters 2094function setFilters() {} 2095setFilters.prototype = Expr.filters = Expr.pseudos; 2096Expr.setFilters = new setFilters(); 2097 2098tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 2099 var matched, match, tokens, type, 2100 soFar, groups, preFilters, 2101 cached = tokenCache[ selector + " " ]; 2102 2103 if ( cached ) { 2104 return parseOnly ? 0 : cached.slice( 0 ); 2105 } 2106 2107 soFar = selector; 2108 groups = []; 2109 preFilters = Expr.preFilter; 2110 2111 while ( soFar ) { 2112 2113 // Comma and first run 2114 if ( !matched || (match = rcomma.exec( soFar )) ) { 2115 if ( match ) { 2116 // Don't consume trailing commas as valid 2117 soFar = soFar.slice( match[0].length ) || soFar; 2118 } 2119 groups.push( (tokens = []) ); 2120 } 2121 2122 matched = false; 2123 2124 // Combinators 2125 if ( (match = rcombinators.exec( soFar )) ) { 2126 matched = match.shift(); 2127 tokens.push({ 2128 value: matched, 2129 // Cast descendant combinators to space 2130 type: match[0].replace( rtrim, " " ) 2131 }); 2132 soFar = soFar.slice( matched.length ); 2133 } 2134 2135 // Filters 2136 for ( type in Expr.filter ) { 2137 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 2138 (match = preFilters[ type ]( match ))) ) { 2139 matched = match.shift(); 2140 tokens.push({ 2141 value: matched, 2142 type: type, 2143 matches: match 2144 }); 2145 soFar = soFar.slice( matched.length ); 2146 } 2147 } 2148 2149 if ( !matched ) { 2150 break; 2151 } 2152 } 2153 2154 // Return the length of the invalid excess 2155 // if we're just parsing 2156 // Otherwise, throw an error or return tokens 2157 return parseOnly ? 2158 soFar.length : 2159 soFar ? 2160 Sizzle.error( selector ) : 2161 // Cache the tokens 2162 tokenCache( selector, groups ).slice( 0 ); 2163}; 2164 2165function toSelector( tokens ) { 2166 var i = 0, 2167 len = tokens.length, 2168 selector = ""; 2169 for ( ; i < len; i++ ) { 2170 selector += tokens[i].value; 2171 } 2172 return selector; 2173} 2174 2175function addCombinator( matcher, combinator, base ) { 2176 var dir = combinator.dir, 2177 checkNonElements = base && dir === "parentNode", 2178 doneName = done++; 2179 2180 return combinator.first ? 2181 // Check against closest ancestor/preceding element 2182 function( elem, context, xml ) { 2183 while ( (elem = elem[ dir ]) ) { 2184 if ( elem.nodeType === 1 || checkNonElements ) { 2185 return matcher( elem, context, xml ); 2186 } 2187 } 2188 } : 2189 2190 // Check against all ancestor/preceding elements 2191 function( elem, context, xml ) { 2192 var oldCache, uniqueCache, outerCache, 2193 newCache = [ dirruns, doneName ]; 2194 2195 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2196 if ( xml ) { 2197 while ( (elem = elem[ dir ]) ) { 2198 if ( elem.nodeType === 1 || checkNonElements ) { 2199 if ( matcher( elem, context, xml ) ) { 2200 return true; 2201 } 2202 } 2203 } 2204 } else { 2205 while ( (elem = elem[ dir ]) ) { 2206 if ( elem.nodeType === 1 || checkNonElements ) { 2207 outerCache = elem[ expando ] || (elem[ expando ] = {}); 2208 2209 // Support: IE <9 only 2210 // Defend against cloned attroperties (jQuery gh-1709) 2211 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); 2212 2213 if ( (oldCache = uniqueCache[ dir ]) && 2214 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2215 2216 // Assign to newCache so results back-propagate to previous elements 2217 return (newCache[ 2 ] = oldCache[ 2 ]); 2218 } else { 2219 // Reuse newcache so results back-propagate to previous elements 2220 uniqueCache[ dir
vendor: 12,959 bytes, lines 2220-2663
2220 ] = newCache; 2221 2222 // A match means we're done; a fail means we have to keep checking 2223 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 2224 return true; 2225 } 2226 } 2227 } 2228 } 2229 } 2230 }; 2231} 2232 2233function elementMatcher( matchers ) { 2234 return matchers.length > 1 ? 2235 function( elem, context, xml ) { 2236 var i = matchers.length; 2237 while ( i-- ) { 2238 if ( !matchers[i]( elem, context, xml ) ) { 2239 return false; 2240 } 2241 } 2242 return true; 2243 } : 2244 matchers[0]; 2245} 2246 2247function multipleContexts( selector, contexts, results ) { 2248 var i = 0, 2249 len = contexts.length; 2250 for ( ; i < len; i++ ) { 2251 Sizzle( selector, contexts[i], results ); 2252 } 2253 return results; 2254} 2255 2256function condense( unmatched, map, filter, context, xml ) { 2257 var elem, 2258 newUnmatched = [], 2259 i = 0, 2260 len = unmatched.length, 2261 mapped = map != null; 2262 2263 for ( ; i < len; i++ ) { 2264 if ( (elem = unmatched[i]) ) { 2265 if ( !filter || filter( elem, context, xml ) ) { 2266 newUnmatched.push( elem ); 2267 if ( mapped ) { 2268 map.push( i ); 2269 } 2270 } 2271 } 2272 } 2273 2274 return newUnmatched; 2275} 2276 2277function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2278 if ( postFilter && !postFilter[ expando ] ) { 2279 postFilter = setMatcher( postFilter ); 2280 } 2281 if ( postFinder && !postFinder[ expando ] ) { 2282 postFinder = setMatcher( postFinder, postSelector ); 2283 } 2284 return markFunction(function( seed, results, context, xml ) { 2285 var temp, i, elem, 2286 preMap = [], 2287 postMap = [], 2288 preexisting = results.length, 2289 2290 // Get initial elements from seed or context 2291 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 2292 2293 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2294 matcherIn = preFilter && ( seed || !selector ) ? 2295 condense( elems, preMap, preFilter, context, xml ) : 2296 elems, 2297 2298 matcherOut = matcher ? 2299 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2300 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2301 2302 // ...intermediate processing is necessary 2303 [] : 2304 2305 // ...otherwise use results directly 2306 results : 2307 matcherIn; 2308 2309 // Find primary matches 2310 if ( matcher ) { 2311 matcher( matcherIn, matcherOut, context, xml ); 2312 } 2313 2314 // Apply postFilter 2315 if ( postFilter ) { 2316 temp = condense( matcherOut, postMap ); 2317 postFilter( temp, [], context, xml ); 2318 2319 // Un-match failing elements by moving them back to matcherIn 2320 i = temp.length; 2321 while ( i-- ) { 2322 if ( (elem = temp[i]) ) { 2323 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 2324 } 2325 } 2326 } 2327 2328 if ( seed ) { 2329 if ( postFinder || preFilter ) { 2330 if ( postFinder ) { 2331 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2332 temp = []; 2333 i = matcherOut.length; 2334 while ( i-- ) { 2335 if ( (elem = matcherOut[i]) ) { 2336 // Restore matcherIn since elem is not yet a final match 2337 temp.push( (matcherIn[i] = elem) ); 2338 } 2339 } 2340 postFinder( null, (matcherOut = []), temp, xml ); 2341 } 2342 2343 // Move matched elements from seed to results to keep them synchronized 2344 i = matcherOut.length; 2345 while ( i-- ) { 2346 if ( (elem = matcherOut[i]) && 2347 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 2348 2349 seed[temp] = !(results[temp] = elem); 2350 } 2351 } 2352 } 2353 2354 // Add elements to results, through postFinder if defined 2355 } else { 2356 matcherOut = condense( 2357 matcherOut === results ? 2358 matcherOut.splice( preexisting, matcherOut.length ) : 2359 matcherOut 2360 ); 2361 if ( postFinder ) { 2362 postFinder( null, results, matcherOut, xml ); 2363 } else { 2364 push.apply( results, matcherOut ); 2365 } 2366 } 2367 }); 2368} 2369 2370function matcherFromTokens( tokens ) { 2371 var checkContext, matcher, j, 2372 len = tokens.length, 2373 leadingRelative = Expr.relative[ tokens[0].type ], 2374 implicitRelative = leadingRelative || Expr.relative[" "], 2375 i = leadingRelative ? 1 : 0, 2376 2377 // The foundational matcher ensures that elements are reachable from top-level context(s) 2378 matchContext = addCombinator( function( elem ) { 2379 return elem === checkContext; 2380 }, implicitRelative, true ), 2381 matchAnyContext = addCombinator( function( elem ) { 2382 return indexOf( checkContext, elem ) > -1; 2383 }, implicitRelative, true ), 2384 matchers = [ function( elem, context, xml ) { 2385 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 2386 (checkContext = context).nodeType ? 2387 matchContext( elem, context, xml ) : 2388 matchAnyContext( elem, context, xml ) ); 2389 // Avoid hanging onto element (issue #299) 2390 checkContext = null; 2391 return ret; 2392 } ]; 2393 2394 for ( ; i < len; i++ ) { 2395 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 2396 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 2397 } else { 2398 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 2399 2400 // Return special upon seeing a positional matcher 2401 if ( matcher[ expando ] ) { 2402 // Find the next relative operator (if any) for proper handling 2403 j = ++i; 2404 for ( ; j < len; j++ ) { 2405 if ( Expr.relative[ tokens[j].type ] ) { 2406 break; 2407 } 2408 } 2409 return setMatcher( 2410 i > 1 && elementMatcher( matchers ), 2411 i > 1 && toSelector( 2412 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2413 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 2414 ).replace( rtrim, "$1" ), 2415 matcher, 2416 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2417 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 2418 j < len && toSelector( tokens ) 2419 ); 2420 } 2421 matchers.push( matcher ); 2422 } 2423 } 2424 2425 return elementMatcher( matchers ); 2426} 2427 2428function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2429 var bySet = setMatchers.length > 0, 2430 byElement = elementMatchers.length > 0, 2431 superMatcher = function( seed, context, xml, results, outermost ) { 2432 var elem, j, matcher, 2433 matchedCount = 0, 2434 i = "0", 2435 unmatched = seed && [], 2436 setMatched = [], 2437 contextBackup = outermostContext, 2438 // We must always have either seed elements or outermost context 2439 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 2440 // Use integer dirruns iff this is the outermost matcher 2441 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 2442 len = elems.length; 2443 2444 if ( outermost ) { 2445 outermostContext = context === document || context || outermost; 2446 } 2447 2448 // Add elements passing elementMatchers directly to results 2449 // Support: IE<9, Safari 2450 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2451 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 2452 if ( byElement && elem ) { 2453 j = 0; 2454 if ( !context && elem.ownerDocument !== document ) { 2455 setDocument( elem ); 2456 xml = !documentIsHTML; 2457 } 2458 while ( (matcher = elementMatchers[j++]) ) { 2459 if ( matcher( elem, context || document, xml) ) { 2460 results.push( elem ); 2461 break; 2462 } 2463 } 2464 if ( outermost ) { 2465 dirruns = dirrunsUnique; 2466 } 2467 } 2468 2469 // Track unmatched elements for set filters 2470 if ( bySet ) { 2471 // They will have gone through all possible matchers 2472 if ( (elem = !matcher && elem) ) { 2473 matchedCount--; 2474 } 2475 2476 // Lengthen the array for every element, matched or not 2477 if ( seed ) { 2478 unmatched.push( elem ); 2479 } 2480 } 2481 } 2482 2483 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2484 // makes the latter nonnegative. 2485 matchedCount += i; 2486 2487 // Apply set filters to unmatched elements 2488 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2489 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2490 // no element matchers and no seed. 2491 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2492 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2493 // numerically zero. 2494 if ( bySet && i !== matchedCount ) { 2495 j = 0; 2496 while ( (matcher = setMatchers[j++]) ) { 2497 matcher( unmatched, setMatched, context, xml ); 2498 } 2499 2500 if ( seed ) { 2501 // Reintegrate element matches to eliminate the need for sorting 2502 if ( matchedCount > 0 ) { 2503 while ( i-- ) { 2504 if ( !(unmatched[i] || setMatched[i]) ) { 2505 setMatched[i] = pop.call( results ); 2506 } 2507 } 2508 } 2509 2510 // Discard index placeholder values to get only actual matches 2511 setMatched = condense( setMatched ); 2512 } 2513 2514 // Add matches to results 2515 push.apply( results, setMatched ); 2516 2517 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2518 if ( outermost && !seed && setMatched.length > 0 && 2519 ( matchedCount + setMatchers.length ) > 1 ) { 2520 2521 Sizzle.uniqueSort( results ); 2522 } 2523 } 2524 2525 // Override manipulation of globals by nested matchers 2526 if ( outermost ) { 2527 dirruns = dirrunsUnique; 2528 outermostContext = contextBackup; 2529 } 2530 2531 return unmatched; 2532 }; 2533 2534 return bySet ? 2535 markFunction( superMatcher ) : 2536 superMatcher; 2537} 2538 2539compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 2540 var i, 2541 setMatchers = [], 2542 elementMatchers = [], 2543 cached = compilerCache[ selector + " " ]; 2544 2545 if ( !cached ) { 2546 // Generate a function of recursive functions that can be used to check each element 2547 if ( !match ) { 2548 match = tokenize( selector ); 2549 } 2550 i = match.length; 2551 while ( i-- ) { 2552 cached = matcherFromTokens( match[i] ); 2553 if ( cached[ expando ] ) { 2554 setMatchers.push( cached ); 2555 } else { 2556 elementMatchers.push( cached ); 2557 } 2558 } 2559 2560 // Cache the compiled function 2561 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2562 2563 // Save selector and tokenization 2564 cached.selector = selector; 2565 } 2566 return cached; 2567}; 2568 2569/** 2570 * A low-level selection function that works with Sizzle's compiled 2571 * selector functions 2572 * @param {String|Function} selector A selector or a pre-compiled 2573 * selector function built with Sizzle.compile 2574 * @param {Element} context 2575 * @param {Array} [results] 2576 * @param {Array} [seed] A set of elements to match against 2577 */ 2578select = Sizzle.select = function( selector, context, results, seed ) { 2579 var i, tokens, token, type, find, 2580 compiled = typeof selector === "function" && selector, 2581 match = !seed && tokenize( (selector = compiled.selector || selector) ); 2582 2583 results = results || []; 2584 2585 // Try to minimize operations if there is only one selector in the list and no seed 2586 // (the latter of which guarantees us context) 2587 if ( match.length === 1 ) { 2588 2589 // Reduce context if the leading compound selector is an ID 2590 tokens = match[0] = match[0].slice( 0 ); 2591 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 2592 support.getById && context.nodeType === 9 && documentIsHTML && 2593 Expr.relative[ tokens[1].type ] ) { 2594 2595 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 2596 if ( !context ) { 2597 return results; 2598 2599 // Precompiled matchers will still verify ancestry, so step up a level 2600 } else if ( compiled ) { 2601 context = context.parentNode; 2602 } 2603 2604 selector = selector.slice( tokens.shift().value.length ); 2605 } 2606 2607 // Fetch a seed set for right-to-left matching 2608 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 2609 while ( i-- ) { 2610 token = tokens[i]; 2611 2612 // Abort if we hit a combinator 2613 if ( Expr.relative[ (type = token.type) ] ) { 2614 break; 2615 } 2616 if ( (find = Expr.find[ type ]) ) { 2617 // Search, expanding context for leading sibling combinators 2618 if ( (seed = find( 2619 token.matches[0].replace( runescape, funescape ), 2620 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 2621 )) ) { 2622 2623 // If seed is empty or no tokens remain, we can return early 2624 tokens.splice( i, 1 ); 2625 selector = seed.length && toSelector( tokens ); 2626 if ( !selector ) { 2627 push.apply( results, seed ); 2628 return results; 2629 } 2630 2631 break; 2632 } 2633 } 2634 } 2635 } 2636 2637 // Compile and execute a filtering function if one is not provided 2638 // Provide `match` to avoid retokenization if we modified the selector above 2639 ( compiled || compile( selector, match ) )( 2640 seed, 2641 context, 2642 !documentIsHTML, 2643 results, 2644 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2645 ); 2646 return results; 2647}; 2648 2649// One-time assignments 2650 2651// Sort stability 2652support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 2653 2654// Support: Chrome 14-35+ 2655// Always assume duplicates if they aren't passed to the comparison function 2656support.detectDuplicates = !!hasDuplicate; 2657 2658// Initialize against the default document 2659setDocument(); 2660 2661// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 2662// Detached nodes confoundingly follow *each other* 2663support.sortDetached = assert(function(
vendor: 3,546 bytes, lines 2663-2816
2663div1 ) { 2664 // Should return 1, but returns 4 (following) 2665 return div1.compareDocumentPosition( document.createElement("div") ) & 1; 2666}); 2667 2668// Support: IE<8 2669// Prevent attribute/property "interpolation" 2670// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 2671if ( !assert(function( div ) { 2672 div.innerHTML = "<a href='#'></a>"; 2673 return div.firstChild.getAttribute("href") === "#" ; 2674}) ) { 2675 addHandle( "type|href|height|width", function( elem, name, isXML ) { 2676 if ( !isXML ) { 2677 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 2678 } 2679 }); 2680} 2681 2682// Support: IE<9 2683// Use defaultValue in place of getAttribute("value") 2684if ( !support.attributes || !assert(function( div ) { 2685 div.innerHTML = "<input/>"; 2686 div.firstChild.setAttribute( "value", "" ); 2687 return div.firstChild.getAttribute( "value" ) === ""; 2688}) ) { 2689 addHandle( "value", function( elem, name, isXML ) { 2690 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 2691 return elem.defaultValue; 2692 } 2693 }); 2694} 2695 2696// Support: IE<9 2697// Use getAttributeNode to fetch booleans when getAttribute lies 2698if ( !assert(function( div ) { 2699 return div.getAttribute("disabled") == null; 2700}) ) { 2701 addHandle( booleans, function( elem, name, isXML ) { 2702 var val; 2703 if ( !isXML ) { 2704 return elem[ name ] === true ? name.toLowerCase() : 2705 (val = elem.getAttributeNode( name )) && val.specified ? 2706 val.value : 2707 null; 2708 } 2709 }); 2710} 2711 2712return Sizzle; 2713 2714})( window ); 2715 2716 2717 2718jQuery.find = Sizzle; 2719jQuery.expr = Sizzle.selectors; 2720jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2721jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 2722jQuery.text = Sizzle.getText; 2723jQuery.isXMLDoc = Sizzle.isXML; 2724jQuery.contains = Sizzle.contains; 2725 2726 2727 2728var dir = function( elem, dir, until ) { 2729 var matched = [], 2730 truncate = until !== undefined; 2731 2732 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 2733 if ( elem.nodeType === 1 ) { 2734 if ( truncate && jQuery( elem ).is( until ) ) { 2735 break; 2736 } 2737 matched.push( elem ); 2738 } 2739 } 2740 return matched; 2741}; 2742 2743 2744var siblings = function( n, elem ) { 2745 var matched = []; 2746 2747 for ( ; n; n = n.nextSibling ) { 2748 if ( n.nodeType === 1 && n !== elem ) { 2749 matched.push( n ); 2750 } 2751 } 2752 2753 return matched; 2754}; 2755 2756 2757var rneedsContext = jQuery.expr.match.needsContext; 2758 2759var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); 2760 2761 2762 2763var risSimple = /^.[^:#\[\.,]*$/; 2764 2765// Implement the identical functionality for filter and not 2766function winnow( elements, qualifier, not ) { 2767 if ( jQuery.isFunction( qualifier ) ) { 2768 return jQuery.grep( elements, function( elem, i ) { 2769 /* jshint -W018 */ 2770 return !!qualifier.call( elem, i, elem ) !== not; 2771 } ); 2772 2773 } 2774 2775 if ( qualifier.nodeType ) { 2776 return jQuery.grep( elements, function( elem ) { 2777 return ( elem === qualifier ) !== not; 2778 } ); 2779 2780 } 2781 2782 if ( typeof qualifier === "string" ) { 2783 if ( risSimple.test( qualifier ) ) { 2784 return jQuery.filter( qualifier, elements, not ); 2785 } 2786 2787 qualifier = jQuery.filter( qualifier, elements ); 2788 } 2789 2790 return jQuery.grep( elements, function( elem ) { 2791 return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; 2792 } ); 2793} 2794 2795jQuery.filter = function( expr, elems, not ) { 2796 var elem = elems[ 0 ]; 2797 2798 if ( not ) { 2799 expr = ":not(" + expr + ")"; 2800 } 2801 2802 return elems.length === 1 && elem.nodeType === 1 ? 2803 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : 2804 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2805 return elem.nodeType === 1; 2806 } ) ); 2807}; 2808 2809jQuery.fn.extend( { 2810 find: function( selector ) { 2811 var i, 2812 ret = [], 2813 self = this, 2814 len = self.length; 2815 2816 if ( typeof selector !== "string" ) {
2817 return this.pushStack( jQuery( selector ).filter( function() { 2818 for ( i = 0; i < len; i++ ) { 2819 if ( jQuery.contains( self[ i ], this ) ) { 2820 return true; 2821 } 2822 } 2823 } ) ); 2824 } 2825 2826 for ( i = 0; i < len; i++ ) { 2827 jQuery.find( selector, self[ i ], ret ); 2828 } 2829 2830 // Needed because $( selector, context ) becomes $( context ).find( selector ) 2831 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); 2832 ret.selector = this.selector ? this.selector + " " + selector : selector; 2833 return ret; 2834 }, 2835 filter: function( selector ) { 2836 return this.pushStack( winnow( this, selector || [], false ) ); 2837 }, 2838 not: function( selector ) { 2839 return this.pushStack( winnow( this, selector || [], true ) ); 2840 }, 2841 is: function( selector ) { 2842 return !!winnow( 2843 this, 2844 2845 // If this is a positional/relative selector, check membership in the returned set 2846 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2847 typeof selector === "string" && rneedsContext.test( selector ) ? 2848 jQuery( selector ) : 2849 selector || [], 2850 false 2851 ).length; 2852 } 2853} ); 2854 2855 2856// Initialize a jQuery object 2857 2858 2859// A central reference to the root jQuery(document) 2860var rootjQuery, 2861 2862 // A simple way to check for HTML strings 2863 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 2864 // Strict HTML recognition (#11290: must start with <) 2865 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, 2866 2867 init = jQuery.fn.init = function( selector, context, root ) { 2868 var match, elem; 2869 2870 // HANDLE: $(""), $(null), $(undefined), $(false) 2871 if ( !selector ) { 2872 return this; 2873 } 2874 2875 // init accepts an alternate rootjQuery 2876 // so migrate can support jQuery.sub (gh-2101) 2877 root = root || rootjQuery; 2878 2879 // Handle HTML strings 2880 if ( typeof selector === "string" ) { 2881 if ( selector.charAt( 0 ) === "<" && 2882 selector.charAt( selector.length - 1 ) === ">" && 2883 selector.length >= 3 ) { 2884 2885 // Assume that strings that start and end with <> are HTML and skip the regex check 2886 match = [ null, selector, null ]; 2887 2888 } else { 2889 match = rquickExpr.exec( selector ); 2890 } 2891 2892 // Match html or make sure no context is specified for #id 2893 if ( match && ( match[ 1 ] || !context ) ) { 2894 2895 // HANDLE: $(html) -> $(array) 2896 if ( match[ 1 ] ) { 2897 context = context instanceof jQuery ? context[ 0 ] : context; 2898 2899 // scripts is true for back-compat 2900 // Intentionally let the error be thrown if parseHTML is not present 2901 jQuery.merge( this, jQuery.parseHTML( 2902 match[ 1 ], 2903 context && context.nodeType ? context.ownerDocument || context : document, 2904 true 2905 ) ); 2906 2907 // HANDLE: $(html, props) 2908 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 2909 for ( match in context ) { 2910 2911 // Properties of context are called as methods if possible 2912 if ( jQuery.isFunction( this[ match ] ) ) { 2913 this[ match ]( context[ match ] ); 2914 2915 // ...and otherwise set as attributes 2916 } else { 2917 this.attr( match, context[ match ] ); 2918 } 2919 } 2920 } 2921 2922 return this; 2923 2924 // HANDLE: $(#id) 2925 } else { 2926 elem = document.getElementById( match[ 2 ] ); 2927 2928 // Check parentNode to catch when Blackberry 4.6 returns 2929 // nodes that are no longer in the document #6963 2930 if ( elem && elem.parentNode ) { 2931 2932 // Handle the case where IE and Opera return items 2933 // by name instead of ID 2934 if ( elem.id !== match[ 2 ] ) { 2935 return rootjQuery.find( selector ); 2936 } 2937 2938 // Otherwise, we inject the element directly into the jQuery object 2939 this.length = 1; 2940 this[ 0 ] = elem; 2941 } 2942 2943 this.context = document; 2944 this.selector = selector; 2945 return this; 2946 } 2947 2948 // HANDLE: $(expr, $(...)) 2949 } else if ( !context || context.jquery ) { 2950 return ( context || root ).find( selector ); 2951 2952 // HANDLE: $(expr, context) 2953 // (which is just equivalent to: $(context).find(expr) 2954 } else { 2955 return this.constructor( context ).find( selector ); 2956 } 2957 2958 // HANDLE: $(DOMElement) 2959 } else if ( selector.nodeType ) { 2960 this.context = this[ 0 ] = selector; 2961 this.length = 1; 2962 return this; 2963 2964 // HANDLE: $(function) 2965 // Shortcut for document ready 2966 } else if ( jQuery.isFunction( selector ) ) { 2967 return typeof root.ready !== "undefined" ? 2968 root.ready( selector ) : 2969 2970 // Execute immediately if ready is not present 2971 selector( jQuery ); 2972 } 2973 2974 if ( selector.selector !== undefined ) { 2975 this.selector = selector.selector; 2976 this.context = selector.context; 2977 } 2978 2979 return jQuery.makeArray( selector, this ); 2980 }; 2981 2982// Give the init function the jQuery prototype for later instantiation 2983init.prototype = jQuery.fn; 2984 2985// Initialize central reference 2986rootjQuery = jQuery( document ); 2987 2988 2989var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2990 2991 // methods guaranteed to produce a unique set when starting from a unique set 2992 guaranteedUnique = { 2993 children: true, 2994 contents: true, 2995 next: true, 2996 prev: true 2997 }; 2998 2999jQuery.fn.extend( { 3000 has: function( target ) { 3001 var i, 3002 targets = jQuery( target, this ), 3003 len = targets.length; 3004 3005 return this.filter( function() { 3006 for ( i = 0; i < len; i++ ) { 3007 if ( jQuery.contains( this, targets[ i ] ) ) { 3008 return true; 3009 } 3010 } 3011 } ); 3012 }, 3013 3014 closest: function( selectors, context ) { 3015 var cur, 3016 i = 0, 3017 l = this.length, 3018 matched = [], 3019 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
vendor: 5,562 bytes, lines 3020-3238
3020 jQuery( selectors, context || this.context ) : 3021 0; 3022 3023 for ( ; i < l; i++ ) { 3024 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3025 3026 // Always skip document fragments 3027 if ( cur.nodeType < 11 && ( pos ? 3028 pos.index( cur ) > -1 : 3029 3030 // Don't pass non-elements to Sizzle 3031 cur.nodeType === 1 && 3032 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3033 3034 matched.push( cur ); 3035 break; 3036 } 3037 } 3038 } 3039 3040 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3041 }, 3042 3043 // Determine the position of an element within 3044 // the matched set of elements 3045 index: function( elem ) { 3046 3047 // No argument, return index in parent 3048 if ( !elem ) { 3049 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3050 } 3051 3052 // index in selector 3053 if ( typeof elem === "string" ) { 3054 return jQuery.inArray( this[ 0 ], jQuery( elem ) ); 3055 } 3056 3057 // Locate the position of the desired element 3058 return jQuery.inArray( 3059 3060 // If it receives a jQuery object, the first element is used 3061 elem.jquery ? elem[ 0 ] : elem, this ); 3062 }, 3063 3064 add: function( selector, context ) { 3065 return this.pushStack( 3066 jQuery.uniqueSort( 3067 jQuery.merge( this.get(), jQuery( selector, context ) ) 3068 ) 3069 ); 3070 }, 3071 3072 addBack: function( selector ) { 3073 return this.add( selector == null ? 3074 this.prevObject : this.prevObject.filter( selector ) 3075 ); 3076 } 3077} ); 3078 3079function sibling( cur, dir ) { 3080 do { 3081 cur = cur[ dir ]; 3082 } while ( cur && cur.nodeType !== 1 ); 3083 3084 return cur; 3085} 3086 3087jQuery.each( { 3088 parent: function( elem ) { 3089 var parent = elem.parentNode; 3090 return parent && parent.nodeType !== 11 ? parent : null; 3091 }, 3092 parents: function( elem ) { 3093 return dir( elem, "parentNode" ); 3094 }, 3095 parentsUntil: function( elem, i, until ) { 3096 return dir( elem, "parentNode", until ); 3097 }, 3098 next: function( elem ) { 3099 return sibling( elem, "nextSibling" ); 3100 }, 3101 prev: function( elem ) { 3102 return sibling( elem, "previousSibling" ); 3103 }, 3104 nextAll: function( elem ) { 3105 return dir( elem, "nextSibling" ); 3106 }, 3107 prevAll: function( elem ) { 3108 return dir( elem, "previousSibling" ); 3109 }, 3110 nextUntil: function( elem, i, until ) { 3111 return dir( elem, "nextSibling", until ); 3112 }, 3113 prevUntil: function( elem, i, until ) { 3114 return dir( elem, "previousSibling", until ); 3115 }, 3116 siblings: function( elem ) { 3117 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3118 }, 3119 children: function( elem ) { 3120 return siblings( elem.firstChild ); 3121 }, 3122 contents: function( elem ) { 3123 return jQuery.nodeName( elem, "iframe" ) ? 3124 elem.contentDocument || elem.contentWindow.document : 3125 jQuery.merge( [], elem.childNodes ); 3126 } 3127}, function( name, fn ) { 3128 jQuery.fn[ name ] = function( until, selector ) { 3129 var ret = jQuery.map( this, fn, until ); 3130 3131 if ( name.slice( -5 ) !== "Until" ) { 3132 selector = until; 3133 } 3134 3135 if ( selector && typeof selector === "string" ) { 3136 ret = jQuery.filter( selector, ret ); 3137 } 3138 3139 if ( this.length > 1 ) { 3140 3141 // Remove duplicates 3142 if ( !guaranteedUnique[ name ] ) { 3143 ret = jQuery.uniqueSort( ret ); 3144 } 3145 3146 // Reverse order for parents* and prev-derivatives 3147 if ( rparentsprev.test( name ) ) { 3148 ret = ret.reverse(); 3149 } 3150 } 3151 3152 return this.pushStack( ret ); 3153 }; 3154} ); 3155var rnotwhite = ( /\S+/g ); 3156 3157 3158 3159// Convert String-formatted options into Object-formatted ones 3160function createOptions( options ) { 3161 var object = {}; 3162 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { 3163 object[ flag ] = true; 3164 } ); 3165 return object; 3166} 3167 3168/* 3169 * Create a callback list using the following parameters: 3170 * 3171 * options: an optional list of space-separated options that will change how 3172 * the callback list behaves or a more traditional option object 3173 * 3174 * By default a callback list will act like an event callback list and can be 3175 * "fired" multiple times. 3176 * 3177 * Possible options: 3178 * 3179 * once: will ensure the callback list can only be fired once (like a Deferred) 3180 * 3181 * memory: will keep track of previous values and will call any callback added 3182 * after the list has been fired right away with the latest "memorized" 3183 * values (like a Deferred) 3184 * 3185 * unique: will ensure a callback can only be added once (no duplicate in the list) 3186 * 3187 * stopOnFalse: interrupt callings when a callback returns false 3188 * 3189 */ 3190jQuery.Callbacks = function( options ) { 3191 3192 // Convert options from String-formatted to Object-formatted if needed 3193 // (we check in cache first) 3194 options = typeof options === "string" ? 3195 createOptions( options ) : 3196 jQuery.extend( {}, options ); 3197 3198 var // Flag to know if list is currently firing 3199 firing, 3200 3201 // Last fire value for non-forgettable lists 3202 memory, 3203 3204 // Flag to know if list was already fired 3205 fired, 3206 3207 // Flag to prevent firing 3208 locked, 3209 3210 // Actual callback list 3211 list = [], 3212 3213 // Queue of execution data for repeatable lists 3214 queue = [], 3215 3216 // Index of currently firing callback (modified by add/remove as needed) 3217 firingIndex = -1, 3218 3219 // Fire callbacks 3220 fire = function() { 3221 3222 // Enforce single-firing 3223 locked = options.once; 3224 3225 // Execute callbacks for all pending executions, 3226 // respecting firingIndex overrides and runtime changes 3227 fired = firing = true; 3228 for ( ; queue.length; firingIndex = -1 ) { 3229 memory = queue.shift(); 3230 while ( ++firingIndex < list.length ) { 3231 3232 // Run callback and check for early termination 3233 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3234 options.stopOnFalse ) { 3235 3236 // Jump to end and forget the data so .add doesn't re-fire 3237 firingIndex = list.length; 3238 memory = false;
3239 } 3240 } 3241 } 3242 3243 // Forget the data if we're done with it 3244 if ( !options.memory ) { 3245 memory = false; 3246 } 3247 3248 firing = false; 3249 3250 // Clean up if we're done firing for good 3251 if ( locked ) { 3252 3253 // Keep an empty list if we have data for future add calls 3254 if ( memory ) { 3255 list = []; 3256 3257 // Otherwise, this object is spent 3258 } else { 3259 list = ""; 3260 } 3261 } 3262 }, 3263 3264 // Actual Callbacks object 3265 self = { 3266 3267 // Add a callback or a collection of callbacks to the list 3268 add: function() { 3269 if ( list ) { 3270 3271 // If we have memory from a past run, we should fire after adding 3272 if ( memory && !firing ) { 3273 firingIndex = list.length - 1; 3274 queue.push( memory ); 3275 } 3276 3277 ( function add( args ) { 3278 jQuery.each( args, function( _, arg ) { 3279 if ( jQuery.isFunction( arg ) ) { 3280 if ( !options.unique || !self.has( arg ) ) { 3281 list.push( arg ); 3282 } 3283 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { 3284 3285 // Inspect recursively 3286 add( arg ); 3287 } 3288 } ); 3289 } )( arguments ); 3290 3291 if ( memory && !firing ) { 3292 fire(); 3293 } 3294 } 3295 return this; 3296 }, 3297 3298 // Remove a callback from the list 3299 remove: function() { 3300 jQuery.each( arguments, function( _, arg ) { 3301 var index; 3302 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3303 list.splice( index, 1 ); 3304 3305 // Handle firing indexes 3306 if ( index <= firingIndex ) { 3307 firingIndex--; 3308 } 3309 } 3310 } ); 3311 return this; 3312 }, 3313 3314 // Check if a given callback is in the list. 3315 // If no argument is given, return whether or not list has callbacks attached. 3316 has: function( fn ) { 3317 return fn ? 3318 jQuery.inArray( fn, list ) > -1 : 3319 list.length > 0; 3320 }, 3321 3322 // Remove all callbacks from the list 3323 empty: function() { 3324 if ( list ) { 3325 list = []; 3326 } 3327 return this; 3328 }, 3329 3330 // Disable .fire and .add 3331 // Abort any current/pending executions 3332 // Clear all callbacks and values 3333 disable: function() { 3334 locked = queue = []; 3335 list = memory = ""; 3336 return this; 3337 }, 3338 disabled: function() { 3339 return !list; 3340 }, 3341 3342 // Disable .fire 3343 // Also disable .add unless we have memory (since it would have no effect) 3344 // Abort any pending executions 3345 lock: function() { 3346 locked = true; 3347 if ( !memory ) { 3348 self.disable(); 3349 } 3350 return this; 3351 }, 3352 locked: function() { 3353 return !!locked; 3354 }, 3355 3356 // Call all callbacks with the given context and arguments 3357 fireWith: function( context, args ) { 3358 if ( !locked ) { 3359 args = args || []; 3360 args = [ context, args.slice ? args.slice() : args ]; 3361 queue.push( args ); 3362 if ( !firing ) { 3363 fire(); 3364 } 3365 } 3366 return this; 3367 }, 3368 3369 // Call all the callbacks with the given arguments 3370 fire: function() { 3371 self.fireWith( this, arguments ); 3372 return this; 3373 }, 3374 3375 // To know if the callbacks have already been called at least once 3376 fired: function() { 3377 return !!fired; 3378 } 3379 }; 3380 3381 return self; 3382}; 3383 3384 3385jQuery.extend( { 3386 3387 Deferred: function( func ) { 3388 var tuples = [ 3389 3390 // action, add listener, listener list, final state 3391 [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], 3392 [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], 3393 [ "notify", "progress", jQuery.Callbacks( "memory" ) ] 3394 ], 3395 state = "pending", 3396 promise = { 3397 state: function() { 3398 return state; 3399 }, 3400 always: function() { 3401 deferred.done( arguments ).fail( arguments ); 3402 return this; 3403 }, 3404 then: function( /* fnDone, fnFail, fnProgress */ ) { 3405 var fns = arguments; 3406 return jQuery.Deferred( function( newDefer ) { 3407 jQuery.each( tuples, function( i, tuple ) { 3408 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; 3409 3410 // deferred[ done | fail | progress ] for forwarding actions to newDefer 3411 deferred[ tuple[ 1 ] ]( function() { 3412 var returned = fn && fn.apply( this, arguments ); 3413 if ( returned && jQuery.isFunction( returned.promise ) ) { 3414 returned.promise() 3415 .progress( newDefer.notify ) 3416 .done( newDefer.resolve ) 3417 .fail( newDefer.reject ); 3418 } else { 3419 newDefer[ tuple[ 0 ] + "With" ]( 3420 this === promise ? newDefer.promise() : this, 3421 fn ? [ returned ] : arguments 3422 ); 3423 } 3424 } ); 3425 } ); 3426 fns = null; 3427 } ).promise(); 3428 }, 3429 3430 // Get a promise for this deferred 3431 // If obj is provided, the promise aspect is added to the object 3432 promise: function( obj ) { 3433 return obj != null ? jQuery.extend( obj, promise ) : promise; 3434 } 3435 }, 3436 deferred = {}; 3437 3438 // Keep pipe for back-compat 3439 promise.pipe = promise.then; 3440 3441 // Add list-specific methods 3442 jQuery.each( tuples, function( i, tuple ) { 3443 var list = tuple[ 2 ], 3444 stateString = tuple[ 3 ]; 3445 3446 // promise[ done | fail | progress ] = list.add 3447 promise[ tuple[ 1 ] ] = list.add; 3448 3449 // Handle state 3450 if ( stateString ) { 3451 list.add( function() { 3452 3453 // state = [ resolved | rejected ] 3454 state = stateString; 3455 3456 // [ reject_list | resolve_list ].disable; progress_list.lock 3457 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); 3458 } 3459 3460 // deferred[ resolve | reject | notify ] 3461 deferred[ tuple[ 0 ] ] = function() { 3462 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); 3463 return this; 3464 }; 3465 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 3466 } ); 3467 3468 // Make the deferred a promise 3469 promise.promise( deferred ); 3470 3471 // Call given func if any 3472 if ( func ) { 3473 func.call( deferred, deferred ); 3474 } 3475 3476 // All done! 3477 return deferred; 3478 }, 3479 3480 // Deferred helper 3481 when: function( subordinate /* , ..., subordinateN */ ) { 3482 var i = 0, 3483 resolveValues = slice.call( arguments ), 3484 length = resolveValues.length, 3485 3486 // the count of uncompleted subordinates 3487 remaining = length !== 1 || 3488 ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, 3489 3490 // the master Deferred. 3491 // If resolveValues consist of only a single Deferred, just use that. 3492 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 3493 3494 // Update function for both resolve and progress values 3495 updateFunc = function( i, contexts, values ) { 3496 return function( value ) { 3497 contexts[ i ] = this; 3498 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3499 if ( values === progressValues ) { 3500 deferred.notifyWith( contexts, values ); 3501 3502 } else if ( !( --remaining ) ) { 3503 deferred.resolveWith( contexts, values ); 3504 } 3505 }; 3506 }, 3507 3508 progressValues, progressContexts, resolveContexts; 3509 3510 // add listeners to Deferred subordinates; treat others as resolved 3511 if ( length > 1 ) { 3512 progressValues = new Array( length ); 3513 progressContexts = new Array( length ); 3514 resolveContexts = new Array( length ); 3515 for ( ; i < length; i++ ) { 3516 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { 3517 resolveValues[ i ].promise() 3518 .progress( updateFunc( i, progressContexts, progressValues ) ) 3519 .done( updateFunc( i, resolveContexts, resolveValues ) ) 3520 .fail( deferred.reject ); 3521 } else { 3522 --remaining; 3523 } 3524 } 3525 } 3526 3527 // if we're not waiting on anything, resolve the master 3528 if ( !remaining ) {
3529 deferred.resolveWith( resolveContexts, resolveValues ); 3530 } 3531 3532 return deferred.promise(); 3533 } 3534} ); 3535 3536 3537// The deferred used on DOM ready 3538var readyList; 3539 3540jQuery.fn.ready = function( fn ) { 3541 3542 // Add the callback 3543 jQuery.ready.promise().done( fn ); 3544 3545 return this; 3546}; 3547 3548jQuery.extend( { 3549 3550 // Is the DOM ready to be used? Set to true once it occurs. 3551 isReady: false, 3552 3553 // A counter to track how many items to wait for before 3554 // the ready event fires. See #6781 3555 readyWait: 1, 3556 3557 // Hold (or release) the ready event 3558 holdReady: function( hold ) { 3559 if ( hold ) { 3560 jQuery.readyWait++; 3561 } else { 3562 jQuery.ready( true ); 3563 } 3564 }, 3565 3566 // Handle when the DOM is ready 3567 ready: function( wait ) { 3568 3569 // Abort if there are pending holds or we're already ready 3570 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3571 return; 3572 } 3573 3574 // Remember that the DOM is ready 3575 jQuery.isReady = true; 3576 3577 // If a normal DOM Ready event fired, decrement, and wait if need be 3578 if ( wait !== true && --jQuery.readyWait > 0 ) { 3579 return; 3580 } 3581 3582 // If there are functions bound, to execute 3583 readyList.resolveWith( document, [ jQuery ] ); 3584 3585 // Trigger any bound ready events 3586 if ( jQuery.fn.triggerHandler ) { 3587 jQuery( document ).triggerHandler( "ready" ); 3588 jQuery( document ).off( "ready" ); 3589 } 3590 } 3591} ); 3592 3593/** 3594 * Clean-up method for dom ready events 3595 */ 3596function detach() { 3597 if ( document.addEventListener ) { 3598 document.removeEventListener( "DOMContentLoaded", completed ); 3599 window.removeEventListener( "load", completed ); 3600 3601 } else { 3602 document.detachEvent( "onreadystatechange", completed ); 3603 window.detachEvent( "onload", completed ); 3604 } 3605} 3606 3607/** 3608 * The ready event handler and self cleanup method 3609 */ 3610function completed() { 3611 3612 // readyState === "complete" is good enough for us to call the dom ready in oldIE 3613 if ( document.addEventListener || 3614 window.event.type === "load" || 3615 document.readyState === "complete" ) { 3616 3617 detach(); 3618 jQuery.ready(); 3619 } 3620} 3621 3622jQuery.ready.promise = function( obj ) { 3623 if ( !readyList ) { 3624 3625 readyList = jQuery.Deferred(); 3626 3627 // Catch cases where $(document).ready() is called 3628 // after the browser event has already occurred.
3629 // Support: IE6-10 3630 // Older IE sometimes signals "interactive" too soon 3631 if ( document.readyState === "complete" || 3632 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 3633 3634 // Handle it asynchronously to allow scripts the opportunity to delay ready 3635 window.setTimeout( jQuery.ready ); 3636 3637 // Standards-based browsers support DOMContentLoaded 3638 } else if ( document.addEventListener ) { 3639 3640 // Use the handy event callback 3641 document.addEventListener( "DOMContentLoaded", completed ); 3642 3643 // A fallback to window.onload, that will always work 3644 window.addEventListener( "load", completed ); 3645 3646 // If IE event model is used 3647 } else { 3648 3649 // Ensure firing before onload, maybe late but safe also for iframes 3650 document.attachEvent( "onreadystatechange", completed ); 3651 3652 // A fallback to window.onload, that will always work 3653 window.attachEvent( "onload", completed ); 3654 3655 // If IE and not a frame 3656 // continually check to see if the document is ready 3657 var top = false; 3658 3659 try { 3660 top = window.frameElement == null && document.documentElement; 3661 } catch ( e ) {} 3662 3663 if ( top && top.doScroll ) { 3664 ( function doScrollCheck() { 3665 if ( !jQuery.isReady ) { 3666 3667 try { 3668 3669 // Use the trick by Diego Perini 3670 // http://javascript.nwbox.com/IEContentLoaded/ 3671 top.doScroll( "left" ); 3672 } catch ( e ) { 3673 return window.setTimeout( doScrollCheck, 50 ); 3674 } 3675 3676 // detach all dom ready events 3677 detach(); 3678 3679 // and execute any waiting functions 3680 jQuery.ready(); 3681 } 3682 } )(); 3683 } 3684 } 3685 } 3686 return readyList.promise( obj ); 3687}; 3688 3689// Kick off the DOM ready check even if the user does not 3690jQuery.ready.promise(); 3691 3692 3693 3694 3695// Support: IE<9 3696// Iteration over object's inherited properties before its own 3697var i; 3698for ( i in jQuery( support ) ) { 3699 break; 3700} 3701support.ownFirst = i === "0"; 3702 3703// Note: most support tests are defined in their respective modules. 3704// false until the test is run 3705support.inlineBlockNeedsLayout = false; 3706 3707// Execute ASAP in case we need to set body.style.zoom 3708jQuery( function() { 3709 3710 // Minified: var a,b,c,d 3711 var val, div, body, container; 3712 3713 body = document.getElementsByTagName( "body" )[ 0 ]; 3714 if ( !body || !body.style ) { 3715 3716 // Return for frameset docs that don't have a body 3717 return; 3718 } 3719 3720 // Setup 3721 div = document.createElement( "div" ); 3722 container = document.createElement( "div" ); 3723 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; 3724 body.appendChild( container ).appendChild( div ); 3725 3726 if ( typeof div.style.zoom !== "undefined" ) { 3727 3728 // Support: IE<8 3729 // Check if natively block-level elements act like inline-block 3730 // elements when setting their display to 'inline' and giving 3731 // them layout 3732 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; 3733 3734 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; 3735 if ( val ) { 3736 3737 // Prevent IE 6 from affecting layout for positioned elements #11048 3738 // Prevent IE from shrinking the body in IE 7 mode #12869 3739 // Support: IE<8 3740 body.style.zoom = 1; 3741 } 3742 } 3743 3744 body.removeChild( container ); 3745} ); 3746 3747 3748( function() { 3749 var div = document.createElement( "div" ); 3750 3751 // Support: IE<9 3752 support.deleteExpando = true; 3753 try { 3754 delete div.test; 3755 } catch ( e ) { 3756 support.deleteExpando = false; 3757 } 3758 3759 // Null elements to avoid leaks in IE. 3760 div = null; 3761} )(); 3762var acceptData = function( elem ) { 3763 var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], 3764 nodeType = +elem.nodeType || 1; 3765 3766 // Do not set data on non-element DOM nodes because it will not be cleared (#8335). 3767 return nodeType !== 1 && nodeType !== 9 ? 3768 false : 3769 3770 // Nodes accept data unless otherwise specified; rejection can be conditional 3771 !noData || noData !== true && elem.getAttribute( "classid" ) === noData; 3772}; 3773 3774 3775 3776 3777var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 3778 rmultiDash = /([A-Z])/g; 3779 3780function dataAttr( elem, key, data ) { 3781 3782 // If nothing was found internally, try to fetch any 3783 // data from the HTML5 data-* attribute 3784 if ( data === undefined && elem.nodeType === 1 ) { 3785 3786 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); 3787 3788 data = elem.getAttribute( name ); 3789 3790 if ( typeof data === "string" ) { 3791 try { 3792 data = data === "true" ? true :
3793 data === "false" ? false : 3794 data === "null" ? null : 3795 3796 // Only convert to a number if it doesn't change the string 3797 +data + "" === data ? +data : 3798 rbrace.test( data ) ? jQuery.parseJSON( data ) : 3799 data; 3800 } catch ( e ) {} 3801 3802 // Make sure we set the data so it isn't changed later 3803 jQuery.data( elem, key, data ); 3804 3805 } else { 3806 data = undefined; 3807 } 3808 } 3809 3810 return data; 3811} 3812 3813// checks a cache object for emptiness 3814function isEmptyDataObject( obj ) { 3815 var name; 3816 for ( name in obj ) { 3817 3818 // if the public data object is empty, the private is still empty 3819 if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { 3820 continue; 3821 } 3822 if ( name !== "toJSON" ) { 3823 return false; 3824 } 3825 } 3826 3827 return true; 3828} 3829 3830function internalData( elem, name, data, pvt /* Internal Use Only */ ) { 3831 if ( !acceptData( elem ) ) { 3832 return; 3833 } 3834 3835 var ret, thisCache, 3836 internalKey = jQuery.expando, 3837 3838 // We have to handle DOM nodes and JS objects differently because IE6-7 3839 // can't GC object references properly across the DOM-JS boundary 3840 isNode = elem.nodeType, 3841 3842 // Only DOM nodes need the global jQuery cache; JS object data is 3843 // attached directly to the object so GC can occur automatically 3844 cache = isNode ? jQuery.cache : elem, 3845 3846 // Only defining an ID for JS objects if its cache already exists allows 3847 // the code to shortcut on the same path as a DOM node with no cache 3848 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; 3849 3850 // Avoid doing any more work than we need to when trying to get data on an 3851 // object that has no data at all 3852 if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && 3853 data === undefined && typeof name === "string" ) { 3854 return; 3855 } 3856 3857 if ( !id ) { 3858 3859 // Only DOM nodes need a new unique ID for each element since their data 3860 // ends up in the global cache 3861 if ( isNode ) { 3862 id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; 3863 } else { 3864 id = internalKey; 3865 } 3866 } 3867 3868 if ( !cache[ id ] ) { 3869 3870 // Avoid exposing jQuery metadata on plain JS objects when the object 3871 // is serialized using JSON.stringify 3872 cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; 3873 } 3874 3875 // An object can be passed to jQuery.data instead of a key/value pair; this gets 3876 // shallow copied over onto the existing cache 3877 if ( typeof name === "object" || typeof name === "function" ) { 3878 if ( pvt ) { 3879 cache[ id ] = jQuery.extend( cache[ id ], name ); 3880 } else { 3881 cache[ id ].data = jQuery.extend( cache[ id ].data, name ); 3882 } 3883 } 3884 3885 thisCache = cache[ id ]; 3886 3887 // jQuery data() is stored in a separate object inside the object's internal data 3888 // cache in order to avoid key collisions between internal data and user-defined 3889 // data. 3890 if ( !pvt ) { 3891 if ( !thisCache.data ) { 3892 thisCache.data = {}; 3893 } 3894 3895 thisCache = thisCache.data; 3896 } 3897 3898 if ( data !== undefined ) { 3899 thisCache[ jQuery.camelCase( name ) ] = data; 3900 } 3901 3902 // Check for both converted-to-camel and non-converted data property names 3903 // If a data property was specified 3904 if ( typeof name === "string" ) { 3905 3906 // First Try to find as-is property data 3907 ret = thisCache[ name ]; 3908 3909 // Test for null|undefined property data 3910 if ( ret == null ) { 3911 3912 // Try to find the camelCased property 3913 ret = thisCache[ jQuery.camelCase( name ) ]; 3914 } 3915 } else { 3916 ret = thisCache; 3917 } 3918 3919 return ret; 3920} 3921 3922function internalRemoveData( elem, name, pvt ) { 3923 if ( !acceptData( elem ) ) { 3924 return; 3925 } 3926 3927 var thisCache, i, 3928 isNode = elem.nodeType, 3929 3930 // See jQuery.data for more information 3931 cache = isNode ? jQuery.cache : elem, 3932 id = isNode ? elem[ jQuery.expando ] : jQuery.expando; 3933 3934 // If there is already no cache entry for this object, there is no 3935 // purpose in continuing 3936 if ( !cache[ id ] ) { 3937 return; 3938 } 3939 3940 if ( name ) { 3941 3942 thisCache = pvt ? cache[ id ] : cache[ id ].data; 3943 3944 if ( thisCache ) { 3945 3946 // Support array or space separated string names for data keys 3947 if ( !jQuery.isArray( name ) ) { 3948 3949 // try the string as a key before any manipulation 3950 if ( name in thisCache ) { 3951 name = [ name ]; 3952 } else { 3953 3954 // split the camel cased version by spaces unless a key with the spaces exists 3955 name = jQuery.camelCase( name );
3956 if ( name in thisCache ) { 3957 name = [ name ]; 3958 } else { 3959 name = name.split( " " ); 3960 } 3961 } 3962 } else { 3963 3964 // If "name" is an array of keys... 3965 // When data is initially created, via ("key", "val") signature, 3966 // keys will be converted to camelCase. 3967 // Since there is no way to tell _how_ a key was added, remove 3968 // both plain key and camelCase key. #12786 3969 // This will only penalize the array argument path. 3970 name = name.concat( jQuery.map( name, jQuery.camelCase ) ); 3971 } 3972 3973 i = name.length; 3974 while ( i-- ) { 3975 delete thisCache[ name[ i ] ]; 3976 } 3977 3978 // If there is no data left in the cache, we want to continue 3979 // and let the cache object itself get destroyed 3980 if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { 3981 return; 3982 } 3983 } 3984 } 3985 3986 // See jQuery.data for more information 3987 if ( !pvt ) { 3988 delete cache[ id ].data; 3989 3990 // Don't destroy the parent cache unless the internal data object 3991 // had been the only thing left in it 3992 if ( !isEmptyDataObject( cache[ id ] ) ) { 3993 return; 3994 } 3995 } 3996 3997 // Destroy the cache 3998 if ( isNode ) { 3999 jQuery.cleanData( [ elem ], true ); 4000 4001 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) 4002 /* jshint eqeqeq: false */ 4003 } else if ( support.deleteExpando || cache != cache.window ) { 4004 /* jshint eqeqeq: true */ 4005 delete cache[ id ]; 4006 4007 // When all else fails, undefined 4008 } else { 4009 cache[ id ] = undefined; 4010 } 4011} 4012 4013jQuery.extend( { 4014 cache: {}, 4015 4016 // The following elements (space-suffixed to avoid Object.prototype collisions) 4017 // throw uncatchable exceptions if you attempt to set expando properties 4018 noData: { 4019 "applet ": true, 4020 "embed ": true, 4021 4022 // ...but Flash objects (which have this classid) *can* handle expandos 4023 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 4024 }, 4025 4026 hasData: function( elem ) { 4027 elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; 4028 return !!elem && !isEmptyDataObject( elem ); 4029 }, 4030 4031 data: function( elem, name, data ) { 4032 return internalData( elem, name, data ); 4033 }, 4034 4035 removeData: function( elem, name ) { 4036 return internalRemoveData( elem, name ); 4037 }, 4038 4039 // For internal use only. 4040 _data: function( elem, name, data ) { 4041 return internalData( elem, name, data, true ); 4042 }, 4043 4044 _removeData: function( elem, name ) { 4045 return internalRemoveData( elem, name, true ); 4046 } 4047} ); 4048 4049jQuery.fn.extend( { 4050 data: function( key, value ) { 4051 var i, name, data, 4052 elem = this[ 0 ], 4053 attrs = elem && elem.attributes; 4054 4055 // Special expections of .data basically thwart jQuery.access, 4056 // so implement the relevant behavior ourselves 4057 4058 // Gets all values 4059 if ( key === undefined ) { 4060 if ( this.length ) { 4061 data = jQuery.data( elem ); 4062 4063 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { 4064 i = attrs.length; 4065 while ( i-- ) { 4066 4067 // Support: IE11+ 4068 // The attrs elements can be null (#14894) 4069 if ( attrs[ i ] ) { 4070 name = attrs[ i ].name; 4071 if ( name.indexOf( "data-" ) === 0 ) { 4072 name = jQuery.camelCase( name.slice( 5 ) ); 4073 dataAttr( elem, name, data[ name ] ); 4074 } 4075 } 4076 } 4077 jQuery._data( elem, "parsedAttrs", true ); 4078 } 4079 } 4080 4081 return data; 4082 } 4083 4084 // Sets multiple values 4085 if ( typeof key === "object" ) { 4086 return this.each( function() { 4087 jQuery.data( this, key ); 4088 } ); 4089 } 4090 4091 return arguments.length > 1 ? 4092 4093 // Sets one value 4094 this.each( function() { 4095 jQuery.data( this, key, value ); 4096 } ) : 4097 4098 // Gets one value 4099 // Try to fetch any internally stored data first 4100 elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; 4101 }, 4102 4103 removeData: function( key ) { 4104 return this.each( function() { 4105 jQuery.removeData( this, key ); 4106 } ); 4107 } 4108} ); 4109 4110 4111jQuery.extend( { 4112 queue: function( elem, type, data ) { 4113 var queue; 4114 4115 if ( elem ) { 4116 type = ( type || "fx" ) + "queue"; 4117 queue = jQuery._data( elem, type ); 4118 4119 // Speed up dequeue by getting out quickly if this is just a lookup 4120 if ( data ) { 4121 if ( !queue || jQuery.isArray( data ) ) { 4122 queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); 4123 } else { 4124 queue.push( data ); 4125 } 4126 } 4127 return queue || []; 4128 } 4129 }, 4130 4131 dequeue: function( elem, type ) {
vendor: 2,750 bytes, lines 4132-4257
4132 type = type || "fx"; 4133 4134 var queue = jQuery.queue( elem, type ), 4135 startLength = queue.length, 4136 fn = queue.shift(), 4137 hooks = jQuery._queueHooks( elem, type ), 4138 next = function() { 4139 jQuery.dequeue( elem, type ); 4140 }; 4141 4142 // If the fx queue is dequeued, always remove the progress sentinel 4143 if ( fn === "inprogress" ) { 4144 fn = queue.shift(); 4145 startLength--; 4146 } 4147 4148 if ( fn ) { 4149 4150 // Add a progress sentinel to prevent the fx queue from being 4151 // automatically dequeued 4152 if ( type === "fx" ) { 4153 queue.unshift( "inprogress" ); 4154 } 4155 4156 // clear up the last queue stop function 4157 delete hooks.stop; 4158 fn.call( elem, next, hooks ); 4159 } 4160 4161 if ( !startLength && hooks ) { 4162 hooks.empty.fire(); 4163 } 4164 }, 4165 4166 // not intended for public consumption - generates a queueHooks object, 4167 // or returns the current one 4168 _queueHooks: function( elem, type ) { 4169 var key = type + "queueHooks"; 4170 return jQuery._data( elem, key ) || jQuery._data( elem, key, { 4171 empty: jQuery.Callbacks( "once memory" ).add( function() { 4172 jQuery._removeData( elem, type + "queue" ); 4173 jQuery._removeData( elem, key ); 4174 } ) 4175 } ); 4176 } 4177} ); 4178 4179jQuery.fn.extend( { 4180 queue: function( type, data ) { 4181 var setter = 2; 4182 4183 if ( typeof type !== "string" ) { 4184 data = type; 4185 type = "fx"; 4186 setter--; 4187 } 4188 4189 if ( arguments.length < setter ) { 4190 return jQuery.queue( this[ 0 ], type ); 4191 } 4192 4193 return data === undefined ? 4194 this : 4195 this.each( function() { 4196 var queue = jQuery.queue( this, type, data ); 4197 4198 // ensure a hooks for this queue 4199 jQuery._queueHooks( this, type ); 4200 4201 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4202 jQuery.dequeue( this, type ); 4203 } 4204 } ); 4205 }, 4206 dequeue: function( type ) { 4207 return this.each( function() { 4208 jQuery.dequeue( this, type ); 4209 } ); 4210 }, 4211 clearQueue: function( type ) { 4212 return this.queue( type || "fx", [] ); 4213 }, 4214 4215 // Get a promise resolved when queues of a certain type 4216 // are emptied (fx is the type by default) 4217 promise: function( type, obj ) { 4218 var tmp, 4219 count = 1, 4220 defer = jQuery.Deferred(), 4221 elements = this, 4222 i = this.length, 4223 resolve = function() { 4224 if ( !( --count ) ) { 4225 defer.resolveWith( elements, [ elements ] ); 4226 } 4227 }; 4228 4229 if ( typeof type !== "string" ) { 4230 obj = type; 4231 type = undefined; 4232 } 4233 type = type || "fx"; 4234 4235 while ( i-- ) { 4236 tmp = jQuery._data( elements[ i ], type + "queueHooks" ); 4237 if ( tmp && tmp.empty ) { 4238 count++; 4239 tmp.empty.add( resolve ); 4240 } 4241 } 4242 resolve(); 4243 return defer.promise( obj ); 4244 } 4245} ); 4246 4247 4248( function() { 4249 var shrinkWrapBlocksVal; 4250 4251 support.shrinkWrapBlocks = function() { 4252 if ( shrinkWrapBlocksVal != null ) { 4253 return shrinkWrapBlocksVal; 4254 } 4255 4256 // Will be changed later if needed. 4257 shrinkWrapBlocksVal = false;
4258 4259 // Minified: var b,c,d 4260 var div, body, container; 4261 4262 body = document.getElementsByTagName( "body" )[ 0 ]; 4263 if ( !body || !body.style ) { 4264 4265 // Test fired too early or in an unsupported environment, exit. 4266 return; 4267 } 4268 4269 // Setup 4270 div = document.createElement( "div" ); 4271 container = document.createElement( "div" ); 4272 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; 4273 body.appendChild( container ).appendChild( div ); 4274 4275 // Support: IE6 4276 // Check if elements with layout shrink-wrap their children 4277 if ( typeof div.style.zoom !== "undefined" ) { 4278 4279 // Reset CSS: box-sizing; display; margin; border 4280 div.style.cssText = 4281 4282 // Support: Firefox<29, Android 2.3 4283 // Vendor-prefix box-sizing 4284 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + 4285 "box-sizing:content-box;display:block;margin:0;border:0;" + 4286 "padding:1px;width:1px;zoom:1"; 4287 div.appendChild( document.createElement( "div" ) ).style.width = "5px"; 4288 shrinkWrapBlocksVal = div.offsetWidth !== 3; 4289 } 4290 4291 body.removeChild( container ); 4292 4293 return shrinkWrapBlocksVal; 4294 }; 4295 4296} )(); 4297var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4298 4299var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4300 4301 4302var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4303 4304var isHidden = function( elem, el ) { 4305 4306 // isHidden might be called from jQuery#filter function; 4307 // in that case, element will be second argument 4308 elem = el || elem; 4309 return jQuery.css( elem, "display" ) === "none" || 4310 !jQuery.contains( elem.ownerDocument, elem ); 4311 }; 4312 4313 4314 4315function adjustCSS( elem, prop, valueParts, tween ) { 4316 var adjusted, 4317 scale = 1, 4318 maxIterations = 20, 4319 currentValue = tween ? 4320 function() { return tween.cur(); } : 4321 function() { return jQuery.css( elem, prop, "" ); }, 4322 initial = currentValue(), 4323 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4324 4325 // Starting value computation is required for potential unit mismatches 4326 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4327 rcssNum.exec( jQuery.css( elem, prop ) ); 4328 4329 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4330 4331 // Trust units reported by jQuery.css 4332 unit = unit || initialInUnit[ 3 ]; 4333 4334 // Make sure we update the tween properties later on 4335 valueParts = valueParts || []; 4336 4337 // Iteratively approximate from a nonzero starting point 4338 initialInUnit = +initial || 1; 4339 4340 do { 4341 4342 // If previous iteration zeroed out, double until we get *something*. 4343 // Use string for doubling so we don't accidentally see scale as unchanged below 4344 scale = scale || ".5"; 4345 4346 // Adjust and apply 4347 initialInUnit = initialInUnit / scale; 4348 jQuery.style( elem, prop, initialInUnit + unit ); 4349 4350 // Update scale, tolerating zero or NaN from tween.cur() 4351 // Break the loop if scale is unchanged or perfect, or if we've just had enough. 4352 } while ( 4353 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations 4354 ); 4355 } 4356 4357 if ( valueParts ) { 4358 initialInUnit = +initialInUnit || +initial || 0; 4359 4360 // Apply relative offset (+=/-=) if specified 4361 adjusted = valueParts[ 1 ] ? 4362 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4363 +valueParts[ 2 ]; 4364 if ( tween ) { 4365 tween.unit = unit; 4366 tween.start = initialInUnit; 4367 tween.end = adjusted; 4368 } 4369 } 4370 return adjusted; 4371} 4372 4373 4374// Multifunctional method to get and set values of a collection 4375// The value/s can optionally be executed if it's a function 4376var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 4377 var i = 0, 4378 length = elems.length, 4379 bulk = key == null; 4380 4381 // Sets many values 4382 if ( jQuery.type( key ) === "object" ) { 4383 chainable = true; 4384 for ( i in key ) { 4385 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 4386 } 4387 4388 // Sets one value 4389 } else if ( value !== undefined ) { 4390 chainable = true; 4391 4392 if ( !jQuery.isFunction( value ) ) { 4393 raw = true; 4394 } 4395 4396 if ( bulk ) { 4397 4398 // Bulk operations run against the entire set 4399 if ( raw ) { 4400 fn.call( elems, value ); 4401 fn = null; 4402 4403 // ...except when executing function values 4404 } else { 4405 bulk = fn; 4406 fn = function( elem, key, value ) {
4407 return bulk.call( jQuery( elem ), value ); 4408 }; 4409 } 4410 } 4411 4412 if ( fn ) { 4413 for ( ; i < length; i++ ) { 4414 fn( 4415 elems[ i ], 4416 key, 4417 raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) 4418 ); 4419 } 4420 } 4421 } 4422 4423 return chainable ? 4424 elems : 4425 4426 // Gets 4427 bulk ? 4428 fn.call( elems ) : 4429 length ? fn( elems[ 0 ], key ) : emptyGet; 4430}; 4431var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4432 4433var rtagName = ( /<([\w:-]+)/ ); 4434 4435var rscriptType = ( /^$|\/(?:java|ecma)script/i ); 4436 4437var rleadingWhitespace = ( /^\s+/ ); 4438 4439var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + 4440 "details|dialog|figcaption|figure|footer|header|hgroup|main|" + 4441 "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; 4442 4443 4444 4445function createSafeFragment( document ) { 4446 var list = nodeNames.split( "|" ), 4447 safeFrag = document.createDocumentFragment(); 4448 4449 if ( safeFrag.createElement ) { 4450 while ( list.length ) { 4451 safeFrag.createElement( 4452 list.pop() 4453 ); 4454 } 4455 } 4456 return safeFrag; 4457} 4458 4459 4460( function() { 4461 var div = document.createElement( "div" ), 4462 fragment = document.createDocumentFragment(), 4463 input = document.createElement( "input" ); 4464 4465 // Setup 4466 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; 4467 4468 // IE strips leading whitespace when .innerHTML is used 4469 support.leadingWhitespace = div.firstChild.nodeType === 3; 4470 4471 // Make sure that tbody elements aren't automatically inserted 4472 // IE will insert them into empty tables 4473 support.tbody = !div.getElementsByTagName( "tbody" ).length; 4474 4475 // Make sure that link elements get serialized correctly by innerHTML 4476 // This requires a wrapper element in IE 4477 support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; 4478 4479 // Makes sure cloning an html5 element does not cause problems 4480 // Where outerHTML is undefined, this still works 4481 support.html5Clone = 4482 document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>"; 4483 4484 // Check if a disconnected checkbox will retain its checked 4485 // value of true after appended to the DOM (IE6/7) 4486 input.type = "checkbox"; 4487 input.checked = true; 4488 fragment.appendChild( input ); 4489 support.appendChecked = input.checked; 4490 4491 // Make sure textarea (and checkbox) defaultValue is properly cloned 4492 // Support: IE6-IE11+ 4493 div.innerHTML = "<textarea>x</textarea>"; 4494 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4495 4496 // #11217 - WebKit loses check when the name is after the checked attribute 4497 fragment.appendChild( div ); 4498 4499 // Support: Windows Web Apps (WWA) 4500 // `name` and `type` must use .setAttribute for WWA (#14901) 4501 input = document.createElement( "input" ); 4502 input.setAttribute( "type", "radio" ); 4503 input.setAttribute( "checked", "checked" ); 4504 input.setAttribute( "name", "t" ); 4505 4506 div.appendChild( input ); 4507 4508 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 4509 // old WebKit doesn't clone checked state correctly in fragments 4510 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4511 4512 // Support: IE<9 4513 // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ 4514 support.noCloneEvent = !!div.addEventListener; 4515 4516 // Support: IE<9 4517 // Since attributes and properties are the same in IE, 4518 // cleanData must set properties to undefined rather than use removeAttribute 4519 div[ jQuery.expando ] = 1; 4520 support.attributes = !div.getAttribute( jQuery.expando ); 4521} )(); 4522 4523 4524// We have to close these tags to support XHTML (#13200) 4525var wrapMap = { 4526 option: [ 1, "<select multiple='multiple'>", "</select>" ], 4527 legend: [ 1, "<fieldset>", "</fieldset>" ], 4528 area: [ 1, "<map>", "</map>" ], 4529 4530 // Support: IE8 4531 param: [ 1, "<object>", "</object>" ], 4532 thead: [ 1, "<table>", "</table>" ], 4533 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4534 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 4535 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4536 4537 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, 4538 // unless wrapped in a div with non-breaking characters in front of it. 4539 _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ] 4540}; 4541 4542// Support: IE8-IE9 4543wrapMap.optgroup = wrapMap.option; 4544 4545wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4546wrapMap.th = wrapMap.td; 4547 4548 4549function getAll( context, tag ) { 4550 var elems, elem, 4551 i = 0, 4552 found = typeof context.getElementsByTagName !== "undefined" ? 4553 context.getElementsByTagName( tag || "*" ) : 4554 typeof context.querySelectorAll !== "undefined" ? 4555 context.querySelectorAll( tag || "*" ) : 4556 undefined; 4557 4558 if ( !found ) { 4559 for ( found = [], elems = context.childNodes || context; 4560 ( elem = elems[ i ] ) != null; 4561 i++ 4562 ) { 4563 if ( !tag || jQuery.nodeName( elem, tag ) ) { 4564 found.push( elem ); 4565 } else { 4566 jQuery.merge( found, getAll( elem, tag ) ); 4567 } 4568 } 4569 } 4570 4571 return tag === undefined || tag && jQuery.nodeName( context, tag ) ? 4572 jQuery.merge( [ context ], found ) : 4573 found; 4574} 4575 4576 4577// Mark scripts as having already been evaluated 4578function setGlobalEval( elems, refElements ) { 4579 var elem, 4580 i = 0; 4581 for ( ; ( elem = elems[ i ] ) != null; i++ ) { 4582 jQuery._data( 4583 elem, 4584 "globalEval", 4585 !refElements || jQuery._data( refElements[ i ], "globalEval" ) 4586 ); 4587 } 4588} 4589 4590
4591var rhtml = /<|&#?\w+;/, 4592 rtbody = /<tbody/i; 4593 4594function fixDefaultChecked( elem ) { 4595 if ( rcheckableType.test( elem.type ) ) { 4596 elem.defaultChecked = elem.checked; 4597 } 4598} 4599 4600function buildFragment( elems, context, scripts, selection, ignored ) { 4601 var j, elem, contains, 4602 tmp, tag, tbody, wrap, 4603 l = elems.length, 4604 4605 // Ensure a safe fragment 4606 safe = createSafeFragment( context ), 4607 4608 nodes = [], 4609 i = 0; 4610 4611 for ( ; i < l; i++ ) { 4612 elem = elems[ i ]; 4613 4614 if ( elem || elem === 0 ) { 4615 4616 // Add nodes directly 4617 if ( jQuery.type( elem ) === "object" ) { 4618 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 4619 4620 // Convert non-html into a text node 4621 } else if ( !rhtml.test( elem ) ) { 4622 nodes.push( context.createTextNode( elem ) ); 4623 4624 // Convert html into DOM nodes 4625 } else { 4626 tmp = tmp || safe.appendChild( context.createElement( "div" ) ); 4627 4628 // Deserialize a standard representation 4629 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 4630 wrap = wrapMap[ tag ] || wrapMap._default; 4631 4632 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 4633 4634 // Descend through wrappers to the right content 4635 j = wrap[ 0 ]; 4636 while ( j-- ) { 4637 tmp = tmp.lastChild; 4638 } 4639 4640 // Manually add leading whitespace removed by IE 4641 if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 4642 nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) ); 4643 } 4644 4645 // Remove IE's autoinserted <tbody> from table fragments 4646 if ( !support.tbody ) { 4647 4648 // String was a <table>, *may* have spurious <tbody> 4649 elem = tag === "table" && !rtbody.test( elem ) ? 4650 tmp.firstChild : 4651 4652 // String was a bare <thead> or <tfoot> 4653 wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ? 4654 tmp : 4655 0; 4656 4657 j = elem && elem.childNodes.length; 4658 while ( j-- ) { 4659 if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && 4660 !tbody.childNodes.length ) { 4661 4662 elem.removeChild( tbody ); 4663 } 4664 } 4665 } 4666 4667 jQuery.merge( nodes, tmp.childNodes ); 4668 4669 // Fix #12392 for WebKit and IE > 9 4670 tmp.textContent = ""; 4671 4672 // Fix #12392 for oldIE 4673 while ( tmp.firstChild ) { 4674 tmp.removeChild( tmp.firstChild ); 4675 } 4676 4677 // Remember the top-level container for proper cleanup 4678 tmp = safe.lastChild; 4679 } 4680 } 4681 } 4682 4683 // Fix #11356: Clear elements from fragment 4684 if ( tmp ) { 4685 safe.removeChild( tmp ); 4686 } 4687 4688 // Reset defaultChecked for any radios and checkboxes 4689 // about to be appended to the DOM in IE 6/7 (#8060) 4690 if ( !support.appendChecked ) { 4691 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); 4692 } 4693 4694 i = 0; 4695 while ( ( elem = nodes[ i++ ] ) ) { 4696 4697 // Skip elements already in the context collection (trac-4087) 4698 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 4699 if ( ignored ) { 4700 ignored.push( elem ); 4701 } 4702 4703 continue; 4704 } 4705 4706 contains = jQuery.contains( elem.ownerDocument, elem ); 4707 4708 // Append to fragment 4709 tmp = getAll( safe.appendChild( elem ), "script" ); 4710 4711 // Preserve script evaluation history 4712 if ( contains ) { 4713 setGlobalEval( tmp ); 4714 } 4715 4716 // Capture executables 4717 if ( scripts ) { 4718 j = 0; 4719 while ( ( elem = tmp[ j++ ] ) ) { 4720 if ( rscriptType.test( elem.type || "" ) ) { 4721 scripts.push( elem ); 4722 } 4723 } 4724 } 4725 } 4726 4727 tmp = null; 4728 4729 return safe; 4730} 4731 4732 4733( function() { 4734 var i, eventName, 4735 div = document.createElement( "div" ); 4736 4737 // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) 4738 for ( i in { submit: true, change: true, focusin: true } ) { 4739 eventName = "on" + i; 4740
vendor: 13,833 bytes, lines 4741-5220
4741 if ( !( support[ i ] = eventName in window ) ) { 4742 4743 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) 4744 div.setAttribute( eventName, "t" ); 4745 support[ i ] = div.attributes[ eventName ].expando === false; 4746 } 4747 } 4748 4749 // Null elements to avoid leaks in IE. 4750 div = null; 4751} )(); 4752 4753 4754var rformElems = /^(?:input|select|textarea)$/i, 4755 rkeyEvent = /^key/, 4756 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 4757 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 4758 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4759 4760function returnTrue() { 4761 return true; 4762} 4763 4764function returnFalse() { 4765 return false; 4766} 4767 4768// Support: IE9 4769// See #13393 for more info 4770function safeActiveElement() { 4771 try { 4772 return document.activeElement; 4773 } catch ( err ) { } 4774} 4775 4776function on( elem, types, selector, data, fn, one ) { 4777 var origFn, type; 4778 4779 // Types can be a map of types/handlers 4780 if ( typeof types === "object" ) { 4781 4782 // ( types-Object, selector, data ) 4783 if ( typeof selector !== "string" ) { 4784 4785 // ( types-Object, data ) 4786 data = data || selector; 4787 selector = undefined; 4788 } 4789 for ( type in types ) { 4790 on( elem, type, selector, data, types[ type ], one ); 4791 } 4792 return elem; 4793 } 4794 4795 if ( data == null && fn == null ) { 4796 4797 // ( types, fn ) 4798 fn = selector; 4799 data = selector = undefined; 4800 } else if ( fn == null ) { 4801 if ( typeof selector === "string" ) { 4802 4803 // ( types, selector, fn ) 4804 fn = data; 4805 data = undefined; 4806 } else { 4807 4808 // ( types, data, fn ) 4809 fn = data; 4810 data = selector; 4811 selector = undefined; 4812 } 4813 } 4814 if ( fn === false ) { 4815 fn = returnFalse; 4816 } else if ( !fn ) { 4817 return elem; 4818 } 4819 4820 if ( one === 1 ) { 4821 origFn = fn; 4822 fn = function( event ) { 4823 4824 // Can use an empty set, since event contains the info 4825 jQuery().off( event ); 4826 return origFn.apply( this, arguments ); 4827 }; 4828 4829 // Use same guid so caller can remove using origFn 4830 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4831 } 4832 return elem.each( function() { 4833 jQuery.event.add( this, types, fn, data, selector ); 4834 } ); 4835} 4836 4837/* 4838 * Helper functions for managing events -- not part of the public interface. 4839 * Props to Dean Edwards' addEvent library for many of the ideas. 4840 */ 4841jQuery.event = { 4842 4843 global: {}, 4844 4845 add: function( elem, types, handler, data, selector ) { 4846 var tmp, events, t, handleObjIn, 4847 special, eventHandle, handleObj, 4848 handlers, type, namespaces, origType, 4849 elemData = jQuery._data( elem ); 4850 4851 // Don't attach events to noData or text/comment nodes (but allow plain objects) 4852 if ( !elemData ) { 4853 return; 4854 } 4855 4856 // Caller can pass in an object of custom data in lieu of the handler 4857 if ( handler.handler ) { 4858 handleObjIn = handler; 4859 handler = handleObjIn.handler; 4860 selector = handleObjIn.selector; 4861 } 4862 4863 // Make sure that the handler has a unique ID, used to find/remove it later 4864 if ( !handler.guid ) { 4865 handler.guid = jQuery.guid++; 4866 } 4867 4868 // Init the element's event structure and main handler, if this is the first 4869 if ( !( events = elemData.events ) ) { 4870 events = elemData.events = {}; 4871 } 4872 if ( !( eventHandle = elemData.handle ) ) { 4873 eventHandle = elemData.handle = function( e ) { 4874 4875 // Discard the second event of a jQuery.event.trigger() and 4876 // when an event is called after a page has unloaded 4877 return typeof jQuery !== "undefined" && 4878 ( !e || jQuery.event.triggered !== e.type ) ? 4879 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : 4880 undefined; 4881 }; 4882 4883 // Add elem as a property of the handle fn to prevent a memory leak 4884 // with IE non-native events 4885 eventHandle.elem = elem; 4886 } 4887 4888 // Handle multiple events separated by a space 4889 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4890 t = types.length; 4891 while ( t-- ) { 4892 tmp = rtypenamespace.exec( types[ t ] ) || []; 4893 type = origType = tmp[ 1 ]; 4894 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4895 4896 // There *must* be a type, no attaching namespace-only handlers 4897 if ( !type ) { 4898 continue; 4899 } 4900 4901 // If event changes its type, use the special event handlers for the changed type 4902 special = jQuery.event.special[ type ] || {}; 4903 4904 // If selector defined, determine special event api type, otherwise given type 4905 type = ( selector ? special.delegateType : special.bindType ) || type; 4906 4907 // Update special based on newly reset type 4908 special = jQuery.event.special[ type ] || {}; 4909 4910 // handleObj is passed to all event handlers 4911 handleObj = jQuery.extend( { 4912 type: type, 4913 origType: origType, 4914 data: data, 4915 handler: handler, 4916 guid: handler.guid, 4917 selector: selector, 4918 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 4919 namespace: namespaces.join( "." ) 4920 }, handleObjIn ); 4921 4922 // Init the event handler queue if we're the first 4923 if ( !( handlers = events[ type ] ) ) { 4924 handlers = events[ type ] = []; 4925 handlers.delegateCount = 0; 4926 4927 // Only use addEventListener/attachEvent if the special events handler returns false 4928 if ( !special.setup || 4929 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 4930 4931 // Bind the global event handler to the element 4932 if ( elem.addEventListener ) { 4933 elem.addEventListener( type, eventHandle, false ); 4934 4935 } else if ( elem.attachEvent ) { 4936 elem.attachEvent( "on" + type, eventHandle ); 4937 } 4938 } 4939 } 4940 4941 if ( special.add ) { 4942 special.add.call( elem, handleObj ); 4943 4944 if ( !handleObj.handler.guid ) { 4945 handleObj.handler.guid = handler.guid; 4946 } 4947 } 4948 4949 // Add to the element's handler list, delegates in front 4950 if ( selector ) { 4951 handlers.splice( handlers.delegateCount++, 0, handleObj ); 4952 } else { 4953 handlers.push( handleObj ); 4954 } 4955 4956 // Keep track of which events have ever been used, for event optimization 4957 jQuery.event.global[ type ] = true; 4958 } 4959 4960 // Nullify elem to prevent memory leaks in IE 4961 elem = null; 4962 }, 4963 4964 // Detach an event or set of events from an element 4965 remove: function( elem, types, handler, selector, mappedTypes ) { 4966 var j, handleObj, tmp, 4967 origCount, t, events, 4968 special, handlers, type, 4969 namespaces, origType, 4970 elemData = jQuery.hasData( elem ) && jQuery._data( elem ); 4971 4972 if ( !elemData || !( events = elemData.events ) ) { 4973 return; 4974 } 4975 4976 // Once for each type.namespace in types; type may be omitted 4977 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4978 t = types.length; 4979 while ( t-- ) { 4980 tmp = rtypenamespace.exec( types[ t ] ) || []; 4981 type = origType = tmp[ 1 ]; 4982 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4983 4984 // Unbind all events (on this namespace, if provided) for the element 4985 if ( !type ) { 4986 for ( type in events ) { 4987 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 4988 } 4989 continue; 4990 } 4991 4992 special = jQuery.event.special[ type ] || {}; 4993 type = ( selector ? special.delegateType : special.bindType ) || type; 4994 handlers = events[ type ] || []; 4995 tmp = tmp[ 2 ] && 4996 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 4997 4998 // Remove matching events 4999 origCount = j = handlers.length; 5000 while ( j-- ) { 5001 handleObj = handlers[ j ]; 5002 5003 if ( ( mappedTypes || origType === handleObj.origType ) && 5004 ( !handler || handler.guid === handleObj.guid ) && 5005 ( !tmp || tmp.test( handleObj.namespace ) ) && 5006 ( !selector || selector === handleObj.selector || 5007 selector === "**" && handleObj.selector ) ) { 5008 handlers.splice( j, 1 ); 5009 5010 if ( handleObj.selector ) { 5011 handlers.delegateCount--; 5012 } 5013 if ( special.remove ) { 5014 special.remove.call( elem, handleObj ); 5015 } 5016 } 5017 } 5018 5019 // Remove generic event handler if we removed something and no more handlers exist 5020 // (avoids potential for endless recursion during removal of special event handlers) 5021 if ( origCount && !handlers.length ) { 5022 if ( !special.teardown || 5023 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5024 5025 jQuery.removeEvent( elem, type, elemData.handle ); 5026 } 5027 5028 delete events[ type ]; 5029 } 5030 } 5031 5032 // Remove the expando if it's no longer used 5033 if ( jQuery.isEmptyObject( events ) ) { 5034 delete elemData.handle; 5035 5036 // removeData also checks for emptiness and clears the expando if empty 5037 // so use it instead of delete 5038 jQuery._removeData( elem, "events" ); 5039 } 5040 }, 5041 5042 trigger: function( event, data, elem, onlyHandlers ) { 5043 var handle, ontype, cur, 5044 bubbleType, special, tmp, i, 5045 eventPath = [ elem || document ], 5046 type = hasOwn.call( event, "type" ) ? event.type : event, 5047 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 5048 5049 cur = tmp = elem = elem || document; 5050 5051 // Don't do events on text and comment nodes 5052 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 5053 return; 5054 } 5055 5056 // focus/blur morphs to focusin/out; ensure we're not firing them right now 5057 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 5058 return; 5059 } 5060 5061 if ( type.indexOf( "." ) > -1 ) { 5062 5063 // Namespaced trigger; create a regexp to match event type in handle() 5064 namespaces = type.split( "." ); 5065 type = namespaces.shift(); 5066 namespaces.sort(); 5067 } 5068 ontype = type.indexOf( ":" ) < 0 && "on" + type; 5069 5070 // Caller can pass in a jQuery.Event object, Object, or just an event type string 5071 event = event[ jQuery.expando ] ? 5072 event : 5073 new jQuery.Event( type, typeof event === "object" && event ); 5074 5075 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 5076 event.isTrigger = onlyHandlers ? 2 : 3; 5077 event.namespace = namespaces.join( "." ); 5078 event.rnamespace = event.namespace ? 5079 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 5080 null; 5081 5082 // Clean up the event in case it is being reused 5083 event.result = undefined; 5084 if ( !event.target ) { 5085 event.target = elem; 5086 } 5087 5088 // Clone any incoming data and prepend the event, creating the handler arg list 5089 data = data == null ? 5090 [ event ] : 5091 jQuery.makeArray( data, [ event ] ); 5092 5093 // Allow special events to draw outside the lines 5094 special = jQuery.event.special[ type ] || {}; 5095 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 5096 return; 5097 } 5098 5099 // Determine event propagation path in advance, per W3C events spec (#9951) 5100 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 5101 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 5102 5103 bubbleType = special.delegateType || type; 5104 if ( !rfocusMorph.test( bubbleType + type ) ) { 5105 cur = cur.parentNode; 5106 } 5107 for ( ; cur; cur = cur.parentNode ) { 5108 eventPath.push( cur ); 5109 tmp = cur; 5110 } 5111 5112 // Only add window if we got to document (e.g., not plain obj or detached DOM) 5113 if ( tmp === ( elem.ownerDocument || document ) ) { 5114 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 5115 } 5116 } 5117 5118 // Fire handlers on the event path 5119 i = 0; 5120 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 5121 5122 event.type = i > 1 ? 5123 bubbleType : 5124 special.bindType || type; 5125 5126 // jQuery handler 5127 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && 5128 jQuery._data( cur, "handle" ); 5129 5130 if ( handle ) { 5131 handle.apply( cur, data ); 5132 } 5133 5134 // Native handler 5135 handle = ontype && cur[ ontype ]; 5136 if ( handle && handle.apply && acceptData( cur ) ) { 5137 event.result = handle.apply( cur, data ); 5138 if ( event.result === false ) { 5139 event.preventDefault(); 5140 } 5141 } 5142 } 5143 event.type = type; 5144 5145 // If nobody prevented the default action, do it now 5146 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 5147 5148 if ( 5149 ( !special._default || 5150 special._default.apply( eventPath.pop(), data ) === false 5151 ) && acceptData( elem ) 5152 ) { 5153 5154 // Call a native DOM method on the target with the same name name as the event. 5155 // Can't use an .isFunction() check here because IE6/7 fails that test. 5156 // Don't do default actions on window, that's where global variables be (#6170) 5157 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { 5158 5159 // Don't re-trigger an onFOO event when we call its FOO() method 5160 tmp = elem[ ontype ]; 5161 5162 if ( tmp ) { 5163 elem[ ontype ] = null; 5164 } 5165 5166 // Prevent re-triggering of the same event, since we already bubbled it above 5167 jQuery.event.triggered = type; 5168 try { 5169 elem[ type ](); 5170 } catch ( e ) { 5171 5172 // IE<9 dies on focus/blur to hidden element (#1486,#12518) 5173 // only reproducible on winXP IE8 native, not IE9 in IE8 mode 5174 } 5175 jQuery.event.triggered = undefined; 5176 5177 if ( tmp ) { 5178 elem[ ontype ] = tmp; 5179 } 5180 } 5181 } 5182 } 5183 5184 return event.result; 5185 }, 5186 5187 dispatch: function( event ) { 5188 5189 // Make a writable jQuery.Event from the native event object 5190 event = jQuery.event.fix( event ); 5191 5192 var i, j, ret, matched, handleObj, 5193 handlerQueue = [], 5194 args = slice.call( arguments ), 5195 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], 5196 special = jQuery.event.special[ event.type ] || {}; 5197 5198 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5199 args[ 0 ] = event; 5200 event.delegateTarget = this; 5201 5202 // Call the preDispatch hook for the mapped type, and let it bail if desired 5203 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5204 return; 5205 } 5206 5207 // Determine handlers 5208 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 5209 5210 // Run delegates first; they may want to stop propagation beneath us 5211 i = 0; 5212 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 5213 event.currentTarget = matched.elem; 5214 5215 j = 0; 5216 while ( ( handleObj = matched.handlers[ j++ ] ) && 5217 !event.isImmediatePropagationStopped() ) { 5218 5219 // Triggered event must either 1) have no namespace, or 2) have namespace(s) 5220 // a subset or equal to those in the bound event (both can have no namespace).
5221 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { 5222 5223 event.handleObj = handleObj; 5224 event.data = handleObj.data; 5225 5226 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 5227 handleObj.handler ).apply( matched.elem, args ); 5228 5229 if ( ret !== undefined ) { 5230 if ( ( event.result = ret ) === false ) { 5231 event.preventDefault(); 5232 event.stopPropagation(); 5233 } 5234 } 5235 } 5236 } 5237 } 5238 5239 // Call the postDispatch hook for the mapped type 5240 if ( special.postDispatch ) { 5241 special.postDispatch.call( this, event ); 5242 } 5243 5244 return event.result; 5245 }, 5246 5247 handlers: function( event, handlers ) { 5248 var i, matches, sel, handleObj, 5249 handlerQueue = [], 5250 delegateCount = handlers.delegateCount, 5251 cur = event.target; 5252 5253 // Support (at least): Chrome, IE9 5254 // Find delegate handlers 5255 // Black-hole SVG <use> instance trees (#13180) 5256 // 5257 // Support: Firefox<=42+ 5258 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) 5259 if ( delegateCount && cur.nodeType && 5260 ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { 5261 5262 /* jshint eqeqeq: false */ 5263 for ( ; cur != this; cur = cur.parentNode || this ) { 5264 /* jshint eqeqeq: true */ 5265 5266 // Don't check non-elements (#13208) 5267 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 5268 if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { 5269 matches = []; 5270 for ( i = 0; i < delegateCount; i++ ) { 5271 handleObj = handlers[ i ]; 5272 5273 // Don't conflict with Object.prototype properties (#13203) 5274 sel = handleObj.selector + " "; 5275 5276 if ( matches[ sel ] === undefined ) { 5277 matches[ sel ] = handleObj.needsContext ? 5278 jQuery( sel, this ).index( cur ) > -1 : 5279 jQuery.find( sel, this, null, [ cur ] ).length; 5280 } 5281 if ( matches[ sel ] ) { 5282 matches.push( handleObj ); 5283 } 5284 } 5285 if ( matches.length ) { 5286 handlerQueue.push( { elem: cur, handlers: matches } ); 5287 } 5288 } 5289 } 5290 } 5291 5292 // Add the remaining (directly-bound) handlers 5293 if ( delegateCount < handlers.length ) { 5294 handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); 5295 } 5296 5297 return handlerQueue; 5298 }, 5299 5300 fix: function( event ) { 5301 if ( event[ jQuery.expando ] ) { 5302 return event; 5303 } 5304 5305 // Create a writable copy of the event object and normalize some properties 5306 var i, prop, copy, 5307 type = event.type, 5308 originalEvent = event, 5309 fixHook = this.fixHooks[ type ]; 5310 5311 if ( !fixHook ) { 5312 this.fixHooks[ type ] = fixHook = 5313 rmouseEvent.test( type ) ? this.mouseHooks : 5314 rkeyEvent.test( type ) ? this.keyHooks : 5315 {}; 5316 } 5317 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 5318 5319 event = new jQuery.Event( originalEvent ); 5320 5321 i = copy.length; 5322 while ( i-- ) { 5323 prop = copy[ i ]; 5324 event[ prop ] = originalEvent[ prop ]; 5325 } 5326 5327 // Support: IE<9 5328 // Fix target property (#1925) 5329 if ( !event.target ) { 5330 event.target = originalEvent.srcElement || document; 5331 } 5332 5333 // Support: Safari 6-8+ 5334 // Target should not be a text node (#504, #13143) 5335 if ( event.target.nodeType === 3 ) { 5336 event.target = event.target.parentNode; 5337 } 5338 5339 // Support: IE<9 5340 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) 5341 event.metaKey = !!event.metaKey; 5342 5343 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; 5344 }, 5345 5346 // Includes some event props shared by KeyEvent and MouseEvent 5347 props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + 5348 "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), 5349 5350 fixHooks: {}, 5351 5352 keyHooks: { 5353 props: "char charCode key keyCode".split( " " ), 5354 filter: function( event, original ) { 5355 5356 // Add which for key events 5357 if ( event.which == null ) { 5358 event.which = original.charCode != null ? original.charCode : original.keyCode; 5359 } 5360 5361 return event; 5362 } 5363 }, 5364 5365 mouseHooks: { 5366 props: ( "button buttons clientX clientY fromElement offsetX offsetY " + 5367 "pageX pageY screenX screenY toElement" ).split( " " ), 5368 filter: function( event, original ) { 5369 var body, eventDoc, doc, 5370 button = original.button, 5371 fromElement = original.fromElement; 5372 5373 // Calculate pageX/Y if missing and clientX/Y available 5374 if ( event.pageX == null && original.clientX != null ) { 5375 eventDoc = event.target.ownerDocument || document; 5376 doc = eventDoc.documentElement; 5377 body = eventDoc.body; 5378 5379 event.pageX = original.clientX + 5380 ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - 5381 ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 5382 event.pageY = original.clientY + 5383 ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - 5384 ( doc && doc.clientTop || body && body.clientTop || 0 ); 5385 } 5386 5387 // Add relatedTarget, if necessary 5388 if ( !event.relatedTarget && fromElement ) { 5389 event.relatedTarget = fromElement === event.target ? 5390 original.toElement : 5391 fromElement; 5392 } 5393 5394 // Add which for click: 1 === left; 2 === middle; 3 === right 5395 // Note: button is not normalized, so don't use it 5396 if ( !event.which && button !== undefined ) { 5397 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 5398 } 5399 5400 return event; 5401 } 5402 }, 5403 5404 special: { 5405 load: { 5406 5407 // Prevent triggered image.load events from bubbling to window.load 5408 noBubble: true 5409 }, 5410 focus: { 5411 5412 // Fire native event if possible so blur/focus sequence is correct 5413 trigger: function() { 5414 if ( this !== safeActiveElement() && this.focus ) { 5415 try { 5416 this.focus(); 5417 return false;
5418 } catch ( e ) { 5419 5420 // Support: IE<9 5421 // If we error on focus to hidden element (#1486, #12518), 5422 // let .trigger() run the handlers 5423 } 5424 } 5425 }, 5426 delegateType: "focusin" 5427 }, 5428 blur: { 5429 trigger: function() { 5430 if ( this === safeActiveElement() && this.blur ) { 5431 this.blur(); 5432 return false; 5433 } 5434 }, 5435 delegateType: "focusout" 5436 }, 5437 click: { 5438 5439 // For checkbox, fire native event so checked state will be right 5440 trigger: function() { 5441 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { 5442 this.click(); 5443 return false; 5444 } 5445 }, 5446 5447 // For cross-browser consistency, don't fire native .click() on links 5448 _default: function( event ) { 5449 return jQuery.nodeName( event.target, "a" ); 5450 } 5451 }, 5452 5453 beforeunload: { 5454 postDispatch: function( event ) { 5455 5456 // Support: Firefox 20+ 5457 // Firefox doesn't alert if the returnValue field is not set. 5458 if ( event.result !== undefined && event.originalEvent ) { 5459 event.originalEvent.returnValue = event.result; 5460 } 5461 } 5462 } 5463 }, 5464 5465 // Piggyback on a donor event to simulate a different one 5466 simulate: function( type, elem, event ) { 5467 var e = jQuery.extend( 5468 new jQuery.Event(), 5469 event, 5470 { 5471 type: type, 5472 isSimulated: true 5473 5474 // Previously, `originalEvent: {}` was set here, so stopPropagation call 5475 // would not be triggered on donor event, since in our own 5476 // jQuery.event.stopPropagation function we had a check for existence of 5477 // originalEvent.stopPropagation method, so, consequently it would be a noop. 5478 // 5479 // Guard for simulated events was moved to jQuery.event.stopPropagation function 5480 // since `originalEvent` should point to the original event for the 5481 // constancy with other events and for more focused logic 5482 } 5483 ); 5484 5485 jQuery.event.trigger( e, null, elem ); 5486 5487 if ( e.isDefaultPrevented() ) { 5488 event.preventDefault(); 5489 } 5490 } 5491}; 5492 5493jQuery.removeEvent = document.removeEventListener ? 5494 function( elem, type, handle ) { 5495 5496 // This "if" is needed for plain objects 5497 if ( elem.removeEventListener ) { 5498 elem.removeEventListener( type, handle ); 5499 } 5500 } : 5501 function( elem, type, handle ) { 5502 var name = "on" + type; 5503 5504 if ( elem.detachEvent ) { 5505 5506 // #8545, #7054, preventing memory leaks for custom events in IE6-8 5507 // detachEvent needed property on element, by name of that event, 5508 // to properly expose it to GC 5509 if ( typeof elem[ name ] === "undefined" ) { 5510 elem[ name ] = null; 5511 } 5512 5513 elem.detachEvent( name, handle ); 5514 } 5515 }; 5516 5517jQuery.Event = function( src, props ) { 5518 5519 // Allow instantiation without the 'new' keyword 5520 if ( !( this instanceof jQuery.Event ) ) { 5521 return new jQuery.Event( src, props ); 5522 } 5523 5524 // Event object 5525 if ( src && src.type ) { 5526 this.originalEvent = src; 5527 this.type = src.type; 5528 5529 // Events bubbling up the document may have been marked as prevented 5530 // by a handler lower down the tree; reflect the correct value. 5531 this.isDefaultPrevented = src.defaultPrevented || 5532 src.defaultPrevented === undefined && 5533 5534 // Support: IE < 9, Android < 4.0 5535 src.returnValue === false ? 5536 returnTrue : 5537 returnFalse; 5538 5539 // Event type 5540 } else { 5541 this.type = src; 5542 } 5543 5544 // Put explicitly provided properties onto the event object 5545 if ( props ) { 5546 jQuery.extend( this, props ); 5547 } 5548 5549 // Create a timestamp if incoming event doesn't have one 5550 this.timeStamp = src && src.timeStamp || jQuery.now(); 5551 5552 // Mark it as fixed 5553 this[ jQuery.expando ] = true; 5554}; 5555 5556// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5557// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5558jQuery.Event.prototype = { 5559 constructor: jQuery.Event, 5560 isDefaultPrevented: returnFalse, 5561 isPropagationStopped: returnFalse, 5562 isImmediatePropagationStopped: returnFalse, 5563 5564 preventDefault: function() { 5565 var e = this.originalEvent; 5566 5567 this.isDefaultPrevented = returnTrue; 5568 if ( !e ) { 5569 return; 5570 } 5571 5572 // If preventDefault exists, run it on the original event 5573 if ( e.preventDefault ) { 5574 e.preventDefault(); 5575 5576 // Support: IE 5577 // Otherwise set the returnValue property of the original event to false 5578 } else { 5579 e.returnValue = false;
5580 } 5581 }, 5582 stopPropagation: function() { 5583 var e = this.originalEvent; 5584 5585 this.isPropagationStopped = returnTrue; 5586 5587 if ( !e || this.isSimulated ) { 5588 return; 5589 } 5590 5591 // If stopPropagation exists, run it on the original event 5592 if ( e.stopPropagation ) { 5593 e.stopPropagation(); 5594 } 5595 5596 // Support: IE 5597 // Set the cancelBubble property of the original event to true 5598 e.cancelBubble = true; 5599 }, 5600 stopImmediatePropagation: function() { 5601 var e = this.originalEvent; 5602 5603 this.isImmediatePropagationStopped = returnTrue; 5604 5605 if ( e && e.stopImmediatePropagation ) { 5606 e.stopImmediatePropagation(); 5607 } 5608 5609 this.stopPropagation(); 5610 } 5611}; 5612 5613// Create mouseenter/leave events using mouseover/out and event-time checks 5614// so that event delegation works in jQuery. 5615// Do the same for pointerenter/pointerleave and pointerover/pointerout 5616// 5617// Support: Safari 7 only 5618// Safari sends mouseenter too often; see: 5619// https://code.google.com/p/chromium/issues/detail?id=470258 5620// for the description of the bug (it existed in older Chrome versions as well). 5621jQuery.each( { 5622 mouseenter: "mouseover", 5623 mouseleave: "mouseout", 5624 pointerenter: "pointerover", 5625 pointerleave: "pointerout" 5626}, function( orig, fix ) { 5627 jQuery.event.special[ orig ] = { 5628 delegateType: fix, 5629 bindType: fix, 5630 5631 handle: function( event ) { 5632 var ret, 5633 target = this, 5634 related = event.relatedTarget, 5635 handleObj = event.handleObj; 5636 5637 // For mouseenter/leave call the handler if related is outside the target. 5638 // NB: No relatedTarget if the mouse left/entered the browser window 5639 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5640 event.type = handleObj.origType; 5641 ret = handleObj.handler.apply( this, arguments ); 5642 event.type = fix; 5643 } 5644 return ret; 5645 } 5646 }; 5647} ); 5648 5649// IE submit delegation 5650if ( !support.submit ) { 5651 5652 jQuery.event.special.submit = { 5653 setup: function() { 5654 5655 // Only need this for delegated form submit events 5656 if ( jQuery.nodeName( this, "form" ) ) { 5657 return false; 5658 } 5659 5660 // Lazy-add a submit handler when a descendant form may potentially be submitted 5661 jQuery.event.add( this, "click._submit keypress._submit", function( e ) { 5662 5663 // Node name check avoids a VML-related crash in IE (#9807) 5664 var elem = e.target, 5665 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? 5666 5667 // Support: IE <=8 5668 // We use jQuery.prop instead of elem.form 5669 // to allow fixing the IE8 delegated submit issue (gh-2332) 5670 // by 3rd party polyfills/workarounds. 5671 jQuery.prop( elem, "form" ) : 5672 undefined; 5673 5674 if ( form && !jQuery._data( form, "submit" ) ) { 5675 jQuery.event.add( form, "submit._submit", function( event ) { 5676 event._submitBubble = true; 5677 } ); 5678 jQuery._data( form, "submit", true ); 5679 } 5680 } ); 5681 5682 // return undefined since we don't need an event listener 5683 }, 5684 5685 postDispatch: function( event ) { 5686 5687 // If form was submitted by the user, bubble the event up the tree 5688 if ( event._submitBubble ) { 5689 delete event._submitBubble; 5690 if ( this.parentNode && !event.isTrigger ) { 5691 jQuery.event.simulate( "submit", this.parentNode, event ); 5692 } 5693 } 5694 }, 5695 5696 teardown: function() { 5697 5698 // Only need this for delegated form submit events 5699 if ( jQuery.nodeName( this, "form" ) ) { 5700 return false; 5701 } 5702 5703 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above 5704 jQuery.event.remove( this, "._submit" ); 5705 } 5706 }; 5707} 5708 5709// IE change delegation and checkbox/radio fix 5710if ( !support.change ) { 5711 5712 jQuery.event.special.change = { 5713 5714 setup: function() { 5715 5716 if ( rformElems.test( this.nodeName ) ) { 5717 5718 // IE doesn't fire change on a check/radio until blur; trigger it on click 5719 // after a propertychange. Eat the blur-change in special.change.handle. 5720 // This still fires onchange a second time for check/radio after blur. 5721 if ( this.type === "checkbox" || this.type === "radio" ) { 5722 jQuery.event.add( this, "propertychange._change", function( event ) { 5723 if ( event.originalEvent.propertyName === "checked" ) { 5724 this._justChanged = true; 5725 } 5726 } ); 5727 jQuery.event.add( this, "click._change", function( event ) { 5728 if ( this._justChanged && !event.isTrigger ) { 5729 this._justChanged = false;
5730 } 5731 5732 // Allow triggered, simulated change events (#11500) 5733 jQuery.event.simulate( "change", this, event ); 5734 } ); 5735 } 5736 return false; 5737 } 5738 5739 // Delegated event; lazy-add a change handler on descendant inputs 5740 jQuery.event.add( this, "beforeactivate._change", function( e ) { 5741 var elem = e.target; 5742 5743 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { 5744 jQuery.event.add( elem, "change._change", function( event ) { 5745 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { 5746 jQuery.event.simulate( "change", this.parentNode, event ); 5747 } 5748 } ); 5749 jQuery._data( elem, "change", true ); 5750 } 5751 } ); 5752 }, 5753 5754 handle: function( event ) { 5755 var elem = event.target; 5756 5757 // Swallow native change events from checkbox/radio, we already triggered them above 5758 if ( this !== elem || event.isSimulated || event.isTrigger || 5759 ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { 5760 5761 return event.handleObj.handler.apply( this, arguments ); 5762 } 5763 }, 5764 5765 teardown: function() { 5766 jQuery.event.remove( this, "._change" ); 5767 5768 return !rformElems.test( this.nodeName ); 5769 } 5770 }; 5771} 5772 5773// Support: Firefox 5774// Firefox doesn't have focus(in | out) events 5775// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5776// 5777// Support: Chrome, Safari 5778// focus(in | out) events fire after focus & blur events, 5779// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 5780// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 5781if ( !support.focusin ) { 5782 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 5783 5784 // Attach a single capturing handler on the document while someone wants focusin/focusout 5785 var handler = function( event ) { 5786 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 5787 }; 5788 5789 jQuery.event.special[ fix ] = { 5790 setup: function() { 5791 var doc = this.ownerDocument || this, 5792 attaches = jQuery._data( doc, fix ); 5793 5794 if ( !attaches ) { 5795 doc.addEventListener( orig, handler, true ); 5796 } 5797 jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); 5798 }, 5799 teardown: function() { 5800 var doc = this.ownerDocument || this, 5801 attaches = jQuery._data( doc, fix ) - 1; 5802 5803 if ( !attaches ) { 5804 doc.removeEventListener( orig, handler, true ); 5805 jQuery._removeData( doc, fix ); 5806 } else { 5807 jQuery._data( doc, fix, attaches ); 5808 } 5809 } 5810 }; 5811 } ); 5812} 5813 5814jQuery.fn.extend( { 5815 5816 on: function( types, selector, data, fn ) { 5817 return on( this, types, selector, data, fn ); 5818 }, 5819 one: function( types, selector, data, fn ) { 5820 return on( this, types, selector, data, fn, 1 ); 5821 }, 5822 off: function( types, selector, fn ) { 5823 var handleObj, type; 5824 if ( types && types.preventDefault && types.handleObj ) { 5825 5826 // ( event ) dispatched jQuery.Event 5827 handleObj = types.handleObj; 5828 jQuery( types.delegateTarget ).off( 5829 handleObj.namespace ? 5830 handleObj.origType + "." + handleObj.namespace : 5831 handleObj.origType, 5832 handleObj.selector, 5833 handleObj.handler 5834 ); 5835 return this; 5836 } 5837 if ( typeof types === "object" ) { 5838 5839 // ( types-object [, selector] ) 5840 for ( type in types ) { 5841 this.off( type, selector, types[ type ] ); 5842 } 5843 return this; 5844 } 5845 if ( selector === false || typeof selector === "function" ) { 5846 5847 // ( types [, fn] ) 5848 fn = selector; 5849 selector = undefined; 5850 } 5851 if ( fn === false ) { 5852 fn = returnFalse; 5853 } 5854 return this.each( function() { 5855 jQuery.event.remove( this, types, fn, selector ); 5856 } ); 5857 }, 5858 5859 trigger: function( type, data ) { 5860 return this.each( function() { 5861 jQuery.event.trigger( type, data, this ); 5862 } ); 5863 }, 5864 triggerHandler: function( type, data ) { 5865 var elem = this[ 0 ]; 5866 if ( elem ) { 5867 return jQuery.event.trigger( type, data, elem, true ); 5868 } 5869 } 5870} ); 5871 5872 5873var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, 5874 rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), 5875 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, 5876 5877 // Support: IE 10-11, Edge 10240+ 5878 // In IE/Edge using regex groups here causes severe slowdowns. 5879 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5880 rnoInnerhtml = /<script|<style|<link/i, 5881 5882 // checked="checked" or checked 5883 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5884 rscriptTypeMasked = /^true\/(.*)/, 5885 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, 5886 safeFragment = createSafeFragment( document ), 5887 fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); 5888 5889// Support: IE<8 5890// Manipulating tables requires a tbody 5891function manipulationTarget( elem, content ) { 5892 return jQuery.nodeName( elem, "table" ) && 5893 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? 5894 5895 elem.getElementsByTagName( "tbody" )[ 0 ] || 5896 elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : 5897 elem; 5898} 5899 5900// Replace/restore the type attribute of script elements for safe DOM manipulation 5901function disableScript( elem ) { 5902 elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; 5903 return elem; 5904} 5905function restoreScript( elem ) { 5906 var match = rscriptTypeMasked.exec( elem.type ); 5907 if ( match ) { 5908 elem.type = match[ 1 ]; 5909 } else { 5910 elem.removeAttribute( "type" ); 5911 } 5912 return elem; 5913} 5914 5915function cloneCopyEvent( src, dest ) {
5916 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { 5917 return; 5918 } 5919 5920 var type, i, l, 5921 oldData = jQuery._data( src ), 5922 curData = jQuery._data( dest, oldData ), 5923 events = oldData.events; 5924 5925 if ( events ) { 5926 delete curData.handle; 5927 curData.events = {}; 5928 5929 for ( type in events ) { 5930 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5931 jQuery.event.add( dest, type, events[ type ][ i ] ); 5932 } 5933 } 5934 } 5935 5936 // make the cloned public data object a copy from the original 5937 if ( curData.data ) { 5938 curData.data = jQuery.extend( {}, curData.data ); 5939 } 5940} 5941 5942function fixCloneNodeIssues( src, dest ) { 5943 var nodeName, e, data; 5944 5945 // We do not need to do anything for non-Elements 5946 if ( dest.nodeType !== 1 ) { 5947 return; 5948 } 5949 5950 nodeName = dest.nodeName.toLowerCase(); 5951 5952 // IE6-8 copies events bound via attachEvent when using cloneNode. 5953 if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { 5954 data = jQuery._data( dest ); 5955 5956 for ( e in data.events ) { 5957 jQuery.removeEvent( dest, e, data.handle ); 5958 } 5959 5960 // Event data gets referenced instead of copied if the expando gets copied too 5961 dest.removeAttribute( jQuery.expando ); 5962 } 5963 5964 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text 5965 if ( nodeName === "script" && dest.text !== src.text ) { 5966 disableScript( dest ).text = src.text; 5967 restoreScript( dest ); 5968 5969 // IE6-10 improperly clones children of object elements using classid. 5970 // IE10 throws NoModificationAllowedError if parent is null, #12132. 5971 } else if ( nodeName === "object" ) { 5972 if ( dest.parentNode ) { 5973 dest.outerHTML = src.outerHTML; 5974 } 5975 5976 // This path appears unavoidable for IE9. When cloning an object 5977 // element in IE9, the outerHTML strategy above is not sufficient. 5978 // If the src has innerHTML and the destination does not, 5979 // copy the src.innerHTML into the dest.innerHTML. #10324 5980 if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { 5981 dest.innerHTML = src.innerHTML; 5982 } 5983 5984 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5985 5986 // IE6-8 fails to persist the checked state of a cloned checkbox 5987 // or radio button. Worse, IE6-7 fail to give the cloned element 5988 // a checked appearance if the defaultChecked value isn't also set 5989 5990 dest.defaultChecked = dest.checked = src.checked; 5991 5992 // IE6-7 get confused and end up setting the value of a cloned 5993 // checkbox/radio button to an empty string instead of "on" 5994 if ( dest.value !== src.value ) { 5995 dest.value = src.value; 5996 } 5997 5998 // IE6-8 fails to return the selected option to the default selected 5999 // state when cloning options 6000 } else if ( nodeName === "option" ) { 6001 dest.defaultSelected = dest.selected = src.defaultSelected; 6002 6003 // IE6-8 fails to set the defaultValue to the correct value when 6004 // cloning other types of input fields 6005 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6006 dest.defaultValue = src.defaultValue; 6007 } 6008} 6009 6010function domManip( collection, args, callback, ignored ) { 6011 6012 // Flatten any nested arrays 6013 args = concat.apply( [], args ); 6014 6015 var first, node, hasScripts, 6016 scripts, doc, fragment, 6017 i = 0, 6018 l = collection.length, 6019 iNoClone = l - 1, 6020 value = args[ 0 ], 6021 isFunction = jQuery.isFunction( value ); 6022 6023 // We can't cloneNode fragments that contain checked, in WebKit 6024 if ( isFunction || 6025 ( l > 1 && typeof value === "string" && 6026 !support.checkClone && rchecked.test( value ) ) ) { 6027 return collection.each( function( index ) { 6028 var self = collection.eq( index ); 6029 if ( isFunction ) { 6030 args[ 0 ] = value.call( this, index, self.html() ); 6031 } 6032 domManip( self, args, callback, ignored ); 6033 } ); 6034 } 6035 6036 if ( l ) { 6037 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 6038 first = fragment.firstChild; 6039 6040 if ( fragment.childNodes.length === 1 ) { 6041 fragment = first; 6042 } 6043 6044 // Require either new content or an interest in ignored elements to invoke the callback 6045 if ( first || ignored ) { 6046 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 6047 hasScripts = scripts.length; 6048 6049 // Use the original fragment for the last item 6050 // instead of the first because it can end up 6051 // being emptied incorrectly in certain situations (#8070). 6052 for ( ; i < l; i++ ) { 6053 node = fragment; 6054 6055 if ( i !== iNoClone ) { 6056 node = jQuery.clone( node, true, true ); 6057 6058 // Keep references to cloned scripts for later restoration 6059 if ( hasScripts ) { 6060
6061 // Support: Android<4.1, PhantomJS<2 6062 // push.apply(_, arraylike) throws on ancient WebKit 6063 jQuery.merge( scripts, getAll( node, "script" ) ); 6064 } 6065 } 6066 6067 callback.call( collection[ i ], node, i ); 6068 } 6069 6070 if ( hasScripts ) { 6071 doc = scripts[ scripts.length - 1 ].ownerDocument; 6072 6073 // Reenable scripts 6074 jQuery.map( scripts, restoreScript ); 6075 6076 // Evaluate executable scripts on first document insertion 6077 for ( i = 0; i < hasScripts; i++ ) { 6078 node = scripts[ i ]; 6079 if ( rscriptType.test( node.type || "" ) && 6080 !jQuery._data( node, "globalEval" ) && 6081 jQuery.contains( doc, node ) ) { 6082 6083 if ( node.src ) { 6084 6085 // Optional AJAX dependency, but won't run scripts if not present 6086 if ( jQuery._evalUrl ) { 6087 jQuery._evalUrl( node.src ); 6088 } 6089 } else { 6090 jQuery.globalEval( 6091 ( node.text || node.textContent || node.innerHTML || "" ) 6092 .replace( rcleanScript, "" ) 6093 ); 6094 } 6095 } 6096 } 6097 } 6098 6099 // Fix #11809: Avoid leaking memory 6100 fragment = first = null; 6101 } 6102 } 6103 6104 return collection; 6105} 6106 6107function remove( elem, selector, keepData ) { 6108 var node, 6109 elems = selector ? jQuery.filter( selector, elem ) : elem, 6110 i = 0; 6111 6112 for ( ; ( node = elems[ i ] ) != null; i++ ) { 6113 6114 if ( !keepData && node.nodeType === 1 ) { 6115 jQuery.cleanData( getAll( node ) ); 6116 } 6117 6118 if ( node.parentNode ) { 6119 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { 6120 setGlobalEval( getAll( node, "script" ) ); 6121 } 6122 node.parentNode.removeChild( node ); 6123 } 6124 } 6125 6126 return elem; 6127} 6128 6129jQuery.extend( { 6130 htmlPrefilter: function( html ) { 6131 return html.replace( rxhtmlTag, "<$1></$2>" ); 6132 }, 6133 6134 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6135 var destElements, node, clone, i, srcElements, 6136 inPage = jQuery.contains( elem.ownerDocument, elem ); 6137 6138 if ( support.html5Clone || jQuery.isXMLDoc( elem ) || 6139 !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { 6140 6141 clone = elem.cloneNode( true ); 6142 6143 // IE<=8 does not properly clone detached, unknown element nodes 6144 } else { 6145 fragmentDiv.innerHTML = elem.outerHTML; 6146 fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); 6147 } 6148 6149 if ( ( !support.noCloneEvent || !support.noCloneChecked ) && 6150 ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { 6151 6152 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 6153 destElements = getAll( clone ); 6154 srcElements = getAll( elem ); 6155 6156 // Fix all IE cloning issues 6157 for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { 6158 6159 // Ensure that the destination node is not null; Fixes #9587 6160 if ( destElements[ i ] ) { 6161 fixCloneNodeIssues( node, destElements[ i ] ); 6162 } 6163 } 6164 } 6165 6166 // Copy the events from the original to the clone 6167 if ( dataAndEvents ) { 6168 if ( deepDataAndEvents ) { 6169 srcElements = srcElements || getAll( elem ); 6170 destElements = destElements || getAll( clone ); 6171 6172 for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { 6173 cloneCopyEvent( node, destElements[ i ] ); 6174 } 6175 } else { 6176 cloneCopyEvent( elem, clone ); 6177 } 6178 } 6179 6180 // Preserve script evaluation history 6181 destElements = getAll( clone, "script" ); 6182 if ( destElements.length > 0 ) { 6183 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6184 } 6185 6186 destElements = srcElements = node = null; 6187 6188 // Return the cloned set 6189 return clone; 6190 }, 6191 6192 cleanData: function( elems, /* internal */ forceAcceptData ) { 6193 var elem, type, id, data, 6194 i = 0, 6195 internalKey = jQuery.expando, 6196 cache = jQuery.cache, 6197 attributes = support.attributes, 6198 special = jQuery.event.special; 6199 6200 for ( ; ( elem = elems[ i ] ) != null; i++ ) { 6201 if ( forceAcceptData || acceptData( elem ) ) { 6202 6203 id = elem[ internalKey ]; 6204 data = id && cache[ id ]; 6205 6206 if ( data ) { 6207 if ( data.events ) { 6208 for ( type in data.events ) { 6209 if ( special[ type ] ) { 6210 jQuery.event.remove( elem, type ); 6211 6212 // This is a shortcut to avoid jQuery.event.remove's overhead 6213 } else { 6214 jQuery.removeEvent( elem, type, data.handle ); 6215 } 6216 } 6217 } 6218 6219 // Remove cache only if it was not already removed by jQuery.event.remove 6220 if ( cache[ id ] ) { 6221 6222 delete cache[ id ]; 6223
6224 // Support: IE<9 6225 // IE does not allow us to delete expando properties from nodes 6226 // IE creates expando attributes along with the property 6227 // IE does not have a removeAttribute function on Document nodes 6228 if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { 6229 elem.removeAttribute( internalKey ); 6230 6231 // Webkit & Blink performance suffers when deleting properties 6232 // from DOM nodes, so set to undefined instead 6233 // https://code.google.com/p/chromium/issues/detail?id=378607 6234 } else { 6235 elem[ internalKey ] = undefined; 6236 } 6237 6238 deletedIds.push( id ); 6239 } 6240 } 6241 } 6242 } 6243 } 6244} ); 6245 6246jQuery.fn.extend( { 6247 6248 // Keep domManip exposed until 3.0 (gh-2225) 6249 domManip: domManip, 6250 6251 detach: function( selector ) { 6252 return remove( this, selector, true ); 6253 }, 6254 6255 remove: function( selector ) { 6256 return remove( this, selector ); 6257 }, 6258 6259 text: function( value ) { 6260 return access( this, function( value ) { 6261 return value === undefined ? 6262 jQuery.text( this ) : 6263 this.empty().append( 6264 ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) 6265 ); 6266 }, null, value, arguments.length ); 6267 }, 6268 6269 append: function() { 6270 return domManip( this, arguments, function( elem ) { 6271 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6272 var target = manipulationTarget( this, elem ); 6273 target.appendChild( elem ); 6274 } 6275 } ); 6276 }, 6277
6278 prepend: function() { 6279 return domManip( this, arguments, function( elem ) { 6280 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6281 var target = manipulationTarget( this, elem ); 6282 target.insertBefore( elem, target.firstChild ); 6283 } 6284 } ); 6285 }, 6286 6287 before: function() { 6288 return domManip( this, arguments, function( elem ) { 6289 if ( this.parentNode ) { 6290 this.parentNode.insertBefore( elem, this ); 6291 } 6292 } ); 6293 }, 6294 6295 after: function() { 6296 return domManip( this, arguments, function( elem ) { 6297 if ( this.parentNode ) { 6298 this.parentNode.insertBefore( elem, this.nextSibling ); 6299 } 6300 } ); 6301 }, 6302 6303 empty: function() { 6304 var elem, 6305 i = 0; 6306 6307 for ( ; ( elem = this[ i ] ) != null; i++ ) { 6308 6309 // Remove element nodes and prevent memory leaks 6310 if ( elem.nodeType === 1 ) { 6311 jQuery.cleanData( getAll( elem, false ) ); 6312 } 6313 6314 // Remove any remaining nodes 6315 while ( elem.firstChild ) { 6316 elem.removeChild( elem.firstChild ); 6317 } 6318 6319 // If this is a select, ensure that it displays empty (#12336) 6320 // Support: IE<9 6321 if ( elem.options && jQuery.nodeName( elem, "select" ) ) { 6322 elem.options.length = 0; 6323 } 6324 } 6325 6326 return this; 6327 }, 6328 6329 clone: function( dataAndEvents, deepDataAndEvents ) { 6330 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6331 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6332 6333 return this.map( function() { 6334 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 6335 } ); 6336 }, 6337 6338 html: function( value ) { 6339 return access( this, function( value ) { 6340 var elem = this[ 0 ] || {}, 6341 i = 0, 6342 l = this.length; 6343 6344 if ( value === undefined ) { 6345 return elem.nodeType === 1 ? 6346 elem.innerHTML.replace( rinlinejQuery, "" ) : 6347 undefined; 6348 } 6349 6350 // See if we can take a shortcut and just use innerHTML 6351 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 6352 ( support.htmlSerialize || !rnoshimcache.test( value ) ) && 6353 ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && 6354 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 6355 6356 value = jQuery.htmlPrefilter( value ); 6357 6358 try { 6359 for ( ; i < l; i++ ) { 6360 6361 // Remove element nodes and prevent memory leaks 6362 elem = this[ i ] || {}; 6363 if ( elem.nodeType === 1 ) { 6364 jQuery.cleanData( getAll( elem, false ) ); 6365 elem.innerHTML = value; 6366 } 6367 } 6368 6369 elem = 0; 6370 6371 // If using innerHTML throws an exception, use the fallback method 6372 } catch ( e ) {} 6373 } 6374 6375 if ( elem ) { 6376 this.empty().append( value ); 6377 } 6378 }, null, value, arguments.length ); 6379 }, 6380 6381 replaceWith: function() { 6382 var ignored = []; 6383 6384 // Make the changes, replacing each non-ignored context element with the new content 6385 return domManip( this, arguments, function( elem ) { 6386 var parent = this.parentNode; 6387 6388 if ( jQuery.inArray( this, ignored ) < 0 ) { 6389 jQuery.cleanData( getAll( this ) ); 6390 if ( parent ) { 6391 parent.replaceChild( elem, this ); 6392 } 6393 } 6394 6395 // Force callback invocation 6396 }, ignored ); 6397 } 6398} ); 6399 6400jQuery.each( { 6401 appendTo: "append", 6402 prependTo: "prepend", 6403 insertBefore: "before", 6404 insertAfter: "after", 6405 replaceAll: "replaceWith" 6406}, function( name, original ) { 6407 jQuery.fn[ name ] = function( selector ) { 6408 var elems, 6409 i = 0, 6410 ret = [], 6411 insert = jQuery( selector ), 6412 last = insert.length - 1; 6413 6414 for ( ; i <= last; i++ ) { 6415 elems = i === last ? this : this.clone( true ); 6416 jQuery( insert[ i ] )[ original ]( elems ); 6417 6418 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() 6419 push.apply( ret, elems.get() ); 6420 } 6421 6422 return this.pushStack( ret ); 6423 }; 6424} ); 6425 6426 6427var iframe, 6428 elemdisplay = { 6429 6430 // Support: Firefox 6431 // We have to pre-define these values for FF (#10227) 6432 HTML: "block", 6433 BODY: "block" 6434 }; 6435 6436/** 6437 * Retrieve the actual display of a element 6438 * @param {String} name nodeName of the element 6439 * @param {Object} doc Document object 6440 */ 6441 6442// Called only from within defaultDisplay 6443function actualDisplay( name, doc ) { 6444 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), 6445 6446 display = jQuery.css( elem[ 0 ], "display" ); 6447 6448 // We don't have any data stored on the element, 6449 // so use "detach" method as fast way to get rid of the element 6450 elem.detach(); 6451
6452 return display; 6453} 6454 6455/** 6456 * Try to determine the default display value of an element 6457 * @param {String} nodeName 6458 */ 6459function defaultDisplay( nodeName ) { 6460 var doc = document, 6461 display = elemdisplay[ nodeName ]; 6462 6463 if ( !display ) { 6464 display = actualDisplay( nodeName, doc ); 6465 6466 // If the simple way fails, read from inside an iframe 6467 if ( display === "none" || !display ) { 6468 6469 // Use the already-created iframe if possible 6470 iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) ) 6471 .appendTo( doc.documentElement ); 6472 6473 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse 6474 doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document; 6475 6476 // Support: IE 6477 doc.write(); 6478 doc.close(); 6479 6480 display = actualDisplay( nodeName, doc ); 6481 iframe.detach(); 6482 } 6483 6484 // Store the correct default display 6485 elemdisplay[ nodeName ] = display; 6486 } 6487 6488 return display; 6489} 6490var rmargin = ( /^margin/ ); 6491 6492var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 6493 6494var swap = function( elem, options, callback, args ) { 6495 var ret, name, 6496 old = {}; 6497 6498 // Remember the old values, and insert the new ones 6499 for ( name in options ) { 6500 old[ name ] = elem.style[ name ]; 6501 elem.style[ name ] = options[ name ]; 6502 } 6503 6504 ret = callback.apply( elem, args || [] ); 6505 6506 // Revert the old values 6507 for ( name in options ) { 6508 elem.style[ name ] = old[ name ]; 6509 } 6510 6511 return ret; 6512}; 6513 6514 6515var documentElement = document.documentElement; 6516 6517 6518 6519( function() { 6520 var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal, 6521 reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal, 6522 container = document.createElement( "div" ), 6523 div = document.createElement( "div" ); 6524 6525 // Finish early in limited (non-browser) environments 6526 if ( !div.style ) { 6527 return; 6528 } 6529 6530 div.style.cssText = "float:left;opacity:.5"; 6531 6532 // Support: IE<9 6533 // Make sure that element opacity exists (as opposed to filter) 6534 support.opacity = div.style.opacity === "0.5"; 6535 6536 // Verify style float existence 6537 // (IE uses styleFloat instead of cssFloat) 6538 support.cssFloat = !!div.style.cssFloat; 6539 6540 div.style.backgroundClip = "content-box"; 6541 div.cloneNode( true ).style.backgroundClip = ""; 6542 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6543 6544 container = document.createElement( "div" ); 6545 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + 6546 "padding:0;margin-top:1px;position:absolute"; 6547 div.innerHTML = ""; 6548 container.appendChild( div ); 6549 6550 // Support: Firefox<29, Android 2.3 6551 // Vendor-prefix box-sizing 6552 support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" || 6553 div.style.WebkitBoxSizing === ""; 6554 6555 jQuery.extend( support, { 6556 reliableHiddenOffsets: function() { 6557 if ( pixelPositionVal == null ) { 6558 computeStyleTests(); 6559 } 6560 return reliableHiddenOffsetsVal; 6561 }, 6562 6563 boxSizingReliable: function() { 6564 6565 // We're checking for pixelPositionVal here instead of boxSizingReliableVal 6566 // since that compresses better and they're computed together anyway. 6567 if ( pixelPositionVal == null ) { 6568 computeStyleTests(); 6569 } 6570 return boxSizingReliableVal; 6571 }, 6572 6573 pixelMarginRight: function() { 6574 6575 // Support: Android 4.0-4.3 6576 if ( pixelPositionVal == null ) { 6577 computeStyleTests(); 6578 } 6579 return pixelMarginRightVal; 6580 }, 6581 6582 pixelPosition: function() { 6583 if ( pixelPositionVal == null ) { 6584 computeStyleTests(); 6585 } 6586 return pixelPositionVal; 6587 }, 6588 6589 reliableMarginRight: function() { 6590 6591 // Support: Android 2.3 6592 if ( pixelPositionVal == null ) { 6593 computeStyleTests(); 6594 } 6595 return reliableMarginRightVal; 6596 }, 6597 6598 reliableMarginLeft: function() { 6599 6600 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37 6601 if ( pixelPositionVal == null ) { 6602 computeStyleTests(); 6603 } 6604 return reliableMarginLeftVal; 6605 } 6606 } ); 6607 6608 function computeStyleTests() { 6609 var contents, divStyle, 6610 documentElement = document.documentElement; 6611 6612 // Setup 6613 documentElement.appendChild( container ); 6614 6615 div.style.cssText = 6616 6617 // Support: Android 2.3 6618 // Vendor-prefix box-sizing 6619 "-webkit-box-sizing:border-box;box-sizing:border-box;" + 6620 "position:relative;display:block;" + 6621 "margin:auto;border:1px;padding:1px;" + 6622 "top:1%;width:50%"; 6623
6624 // Support: IE<9 6625 // Assume reasonable values in the absence of getComputedStyle 6626 pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false; 6627 pixelMarginRightVal = reliableMarginRightVal = true; 6628 6629 // Check for getComputedStyle so that this code is not run in IE<9. 6630 if ( window.getComputedStyle ) { 6631 divStyle = window.getComputedStyle( div ); 6632 pixelPositionVal = ( divStyle || {} ).top !== "1%"; 6633 reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px"; 6634 boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px"; 6635 6636 // Support: Android 4.0 - 4.3 only 6637 // Some styles come back with percentage values, even though they shouldn't 6638 div.style.marginRight = "50%"; 6639 pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px"; 6640 6641 // Support: Android 2.3 only 6642 // Div with explicit width and no margin-right incorrectly 6643 // gets computed margin-right based on width of container (#3333) 6644 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 6645 contents = div.appendChild( document.createElement( "div" ) ); 6646 6647 // Reset CSS: box-sizing; display; margin; border; padding 6648 contents.style.cssText = div.style.cssText = 6649 6650 // Support: Android 2.3 6651 // Vendor-prefix box-sizing 6652 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + 6653 "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; 6654 contents.style.marginRight = contents.style.width = "0"; 6655 div.style.width = "1px"; 6656 6657 reliableMarginRightVal = 6658 !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight ); 6659 6660 div.removeChild( contents ); 6661 } 6662 6663 // Support: IE6-8 6664 // First check that getClientRects works as expected 6665 // Check if table cells still have offsetWidth/Height when they are set 6666 // to display:none and there are still other visible table cells in a 6667 // table row; if so, offsetWidth/Height are not reliable for use when 6668 // determining if an element has been hidden directly using 6669 // display:none (it is still safe to use offsets if a parent element is 6670 // hidden; don safety goggles and see bug #4512 for more information). 6671 div.style.display = "none"; 6672 reliableHiddenOffsetsVal = div.getClientRects().length === 0; 6673 if ( reliableHiddenOffsetsVal ) { 6674 div.style.display = ""; 6675 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; 6676 div.childNodes[ 0 ].style.borderCollapse = "separate"; 6677 contents = div.getElementsByTagName( "td" ); 6678 contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none"; 6679 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; 6680 if ( reliableHiddenOffsetsVal ) { 6681 contents[ 0 ].style.display = ""; 6682 contents[ 1 ].style.display = "none"; 6683 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; 6684 } 6685 } 6686 6687 // Teardown 6688 documentElement.removeChild( container ); 6689 } 6690 6691} )(); 6692 6693 6694var getStyles, curCSS, 6695 rposition = /^(top|right|bottom|left)$/; 6696 6697if ( window.getComputedStyle ) { 6698 getStyles = function( elem ) { 6699 6700 // Support: IE<=11+, Firefox<=30+ (#15098, #14150) 6701 // IE throws on elements created in popups 6702 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6703 var view = elem.ownerDocument.defaultView; 6704 6705 if ( !view || !view.opener ) { 6706 view = window; 6707 } 6708 6709 return view.getComputedStyle( elem ); 6710 }; 6711 6712 curCSS = function( elem, name, computed ) { 6713 var width, minWidth, maxWidth, ret, 6714 style = elem.style; 6715 6716 computed = computed || getStyles( elem ); 6717 6718 // getPropertyValue is only needed for .css('filter') in IE9, see #12537 6719 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; 6720 6721 // Support: Opera 12.1x only 6722 // Fall back to style even without computed 6723 // computed is undefined for elems on document fragments 6724 if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) { 6725 ret = jQuery.style( elem, name ); 6726 } 6727 6728 if ( computed ) { 6729 6730 // A tribute to the "awesome hack by Dean Edwards" 6731 // Chrome < 17 and Safari 5.0 uses "computed value" 6732 // instead of "used value" for margin-right 6733 // Safari 5.1.7 (at least) returns percentage for a larger set of values, 6734 // but width seems to be reliably pixels 6735 // this is against the CSSOM draft spec: 6736 // http://dev.w3.org/csswg/cssom/#resolved-values 6737 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { 6738 6739 // Remember the original values 6740 width = style.width; 6741 minWidth = style.minWidth; 6742 maxWidth = style.maxWidth; 6743 6744 // Put in the new values to get a computed value out 6745 style.minWidth = style.maxWidth = style.width = ret; 6746 ret = computed.width; 6747 6748 // Revert the changed values 6749 style.width = width; 6750 style.minWidth = minWidth; 6751 style.maxWidth = maxWidth; 6752 } 6753 } 6754
6755 // Support: IE 6756 // IE returns zIndex value as an integer. 6757 return ret === undefined ? 6758 ret : 6759 ret + ""; 6760 }; 6761} else if ( documentElement.currentStyle ) { 6762 getStyles = function( elem ) { 6763 return elem.currentStyle; 6764 }; 6765 6766 curCSS = function( elem, name, computed ) { 6767 var left, rs, rsLeft, ret, 6768 style = elem.style; 6769 6770 computed = computed || getStyles( elem ); 6771 ret = computed ? computed[ name ] : undefined; 6772 6773 // Avoid setting ret to empty string here 6774 // so we don't default to auto 6775 if ( ret == null && style && style[ name ] ) { 6776 ret = style[ name ]; 6777 } 6778 6779 // From the awesome hack by Dean Edwards 6780 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6781 6782 // If we're not dealing with a regular pixel number 6783 // but a number that has a weird ending, we need to convert it to pixels 6784 // but not position css attributes, as those are 6785 // proportional to the parent element instead 6786 // and we can't measure the parent instead because it 6787 // might trigger a "stacking dolls" problem 6788 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { 6789 6790 // Remember the original values 6791 left = style.left; 6792 rs = elem.runtimeStyle; 6793 rsLeft = rs && rs.left; 6794 6795 // Put in the new values to get a computed value out 6796 if ( rsLeft ) { 6797 rs.left = elem.currentStyle.left; 6798 } 6799 style.left = name === "fontSize" ? "1em" : ret; 6800 ret = style.pixelLeft + "px"; 6801 6802 // Revert the changed values 6803 style.left = left; 6804 if ( rsLeft ) { 6805 rs.left = rsLeft; 6806 } 6807 } 6808 6809 // Support: IE 6810 // IE returns zIndex value as an integer. 6811 return ret === undefined ? 6812 ret : 6813 ret + "" || "auto"; 6814 }; 6815} 6816 6817 6818 6819 6820function addGetHookIf( conditionFn, hookFn ) { 6821 6822 // Define the hook, we'll check on the first run if it's really needed. 6823 return { 6824 get: function() { 6825 if ( conditionFn() ) { 6826 6827 // Hook not needed (or it's not possible to use it due 6828 // to missing dependency), remove it. 6829 delete this.get; 6830 return; 6831 } 6832 6833 // Hook needed; redefine it so that the support test is not executed again. 6834 return ( this.get = hookFn ).apply( this, arguments ); 6835 } 6836 }; 6837} 6838 6839 6840var 6841 6842 ralpha = /alpha\([^)]*\)/i, 6843 ropacity = /opacity\s*=\s*([^)]*)/i, 6844 6845 // swappable if display is none or starts with table except 6846 // "table", "table-cell", or "table-caption" 6847 // see here for display values: 6848 // https://developer.mozilla.org/en-US/docs/CSS/display 6849 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6850 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), 6851 6852 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6853 cssNormalTransform = { 6854 letterSpacing: "0", 6855 fontWeight: "400" 6856 }, 6857 6858 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], 6859 emptyStyle = document.createElement( "div" ).style; 6860 6861 6862// return a css property mapped to a potentially vendor prefixed property 6863function vendorPropName( name ) { 6864 6865 // shortcut for names that are not vendor prefixed 6866 if ( name in emptyStyle ) { 6867 return name; 6868 } 6869 6870 // check for vendor prefixed names 6871 var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ), 6872 i = cssPrefixes.length; 6873 6874 while ( i-- ) { 6875 name = cssPrefixes[ i ] + capName; 6876 if ( name in emptyStyle ) { 6877 return name; 6878 } 6879 } 6880} 6881 6882function showHide( elements, show ) { 6883 var display, elem, hidden, 6884 values = [], 6885 index = 0, 6886 length = elements.length; 6887 6888 for ( ; index < length; index++ ) { 6889 elem = elements[ index ]; 6890 if ( !elem.style ) { 6891 continue; 6892 } 6893 6894 values[ index ] = jQuery._data( elem, "olddisplay" ); 6895 display = elem.style.display; 6896 if ( show ) { 6897 6898 // Reset the inline display of this element to learn if it is 6899 // being hidden by cascaded rules or not 6900 if ( !values[ index ] && display === "none" ) { 6901 elem.style.display = ""; 6902 } 6903 6904 // Set elements which have been overridden with display: none 6905 // in a stylesheet to whatever the default browser style is 6906 // for such an element 6907 if ( elem.style.display === "" && isHidden( elem ) ) { 6908 values[ index ] = 6909 jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) ); 6910 } 6911 } else { 6912 hidden = isHidden( elem ); 6913 6914 if ( display && display !== "none" || !hidden ) { 6915 jQuery._data( 6916 elem, 6917 "olddisplay",
vendor: 6,043 bytes, lines 6918-7129
6918 hidden ? display : jQuery.css( elem, "display" ) 6919 ); 6920 } 6921 } 6922 } 6923 6924 // Set the display of most of the elements in a second loop 6925 // to avoid the constant reflow 6926 for ( index = 0; index < length; index++ ) { 6927 elem = elements[ index ]; 6928 if ( !elem.style ) { 6929 continue; 6930 } 6931 if ( !show || elem.style.display === "none" || elem.style.display === "" ) { 6932 elem.style.display = show ? values[ index ] || "" : "none"; 6933 } 6934 } 6935 6936 return elements; 6937} 6938 6939function setPositiveNumber( elem, value, subtract ) { 6940 var matches = rnumsplit.exec( value ); 6941 return matches ? 6942 6943 // Guard against undefined "subtract", e.g., when used as in cssHooks 6944 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : 6945 value; 6946} 6947 6948function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { 6949 var i = extra === ( isBorderBox ? "border" : "content" ) ? 6950 6951 // If we already have the right measurement, avoid augmentation 6952 4 : 6953 6954 // Otherwise initialize for horizontal or vertical properties 6955 name === "width" ? 1 : 0, 6956 6957 val = 0; 6958 6959 for ( ; i < 4; i += 2 ) { 6960 6961 // both box models exclude margin, so add it if we want it 6962 if ( extra === "margin" ) { 6963 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); 6964 } 6965 6966 if ( isBorderBox ) { 6967 6968 // border-box includes padding, so remove it if we want content 6969 if ( extra === "content" ) { 6970 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6971 } 6972 6973 // at this point, extra isn't border nor margin, so remove border 6974 if ( extra !== "margin" ) { 6975 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6976 } 6977 } else { 6978 6979 // at this point, extra isn't content, so add padding 6980 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6981 6982 // at this point, extra isn't content nor padding, so add border 6983 if ( extra !== "padding" ) { 6984 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6985 } 6986 } 6987 } 6988 6989 return val; 6990} 6991 6992function getWidthOrHeight( elem, name, extra ) { 6993 6994 // Start with offset property, which is equivalent to the border-box value 6995 var valueIsBorderBox = true, 6996 val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 6997 styles = getStyles( elem ), 6998 isBorderBox = support.boxSizing && 6999 jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 7000 7001 // some non-html elements return undefined for offsetWidth, so check for null/undefined 7002 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 7003 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 7004 if ( val <= 0 || val == null ) { 7005 7006 // Fall back to computed then uncomputed css if necessary 7007 val = curCSS( elem, name, styles ); 7008 if ( val < 0 || val == null ) { 7009 val = elem.style[ name ]; 7010 } 7011 7012 // Computed unit is not pixels. Stop here and return. 7013 if ( rnumnonpx.test( val ) ) { 7014 return val; 7015 } 7016 7017 // we need the check for style in case a browser which returns unreliable values 7018 // for getComputedStyle silently falls back to the reliable elem.style 7019 valueIsBorderBox = isBorderBox && 7020 ( support.boxSizingReliable() || val === elem.style[ name ] ); 7021 7022 // Normalize "", auto, and prepare for extra 7023 val = parseFloat( val ) || 0; 7024 } 7025 7026 // use the active box-sizing model to add/subtract irrelevant styles 7027 return ( val + 7028 augmentWidthOrHeight( 7029 elem, 7030 name, 7031 extra || ( isBorderBox ? "border" : "content" ), 7032 valueIsBorderBox, 7033 styles 7034 ) 7035 ) + "px"; 7036} 7037 7038jQuery.extend( { 7039 7040 // Add in style property hooks for overriding the default 7041 // behavior of getting and setting a style property 7042 cssHooks: { 7043 opacity: { 7044 get: function( elem, computed ) { 7045 if ( computed ) { 7046 7047 // We should always get a number back from opacity 7048 var ret = curCSS( elem, "opacity" ); 7049 return ret === "" ? "1" : ret; 7050 } 7051 } 7052 } 7053 }, 7054 7055 // Don't automatically add "px" to these possibly-unitless properties 7056 cssNumber: { 7057 "animationIterationCount": true, 7058 "columnCount": true, 7059 "fillOpacity": true, 7060 "flexGrow": true, 7061 "flexShrink": true, 7062 "fontWeight": true, 7063 "lineHeight": true, 7064 "opacity": true, 7065 "order": true, 7066 "orphans": true, 7067 "widows": true, 7068 "zIndex": true, 7069 "zoom": true 7070 }, 7071 7072 // Add in properties whose names you wish to fix before 7073 // setting or getting the value 7074 cssProps: { 7075 7076 // normalize float css property 7077 "float": support.cssFloat ? "cssFloat" : "styleFloat" 7078 }, 7079 7080 // Get and set the style property on a DOM Node 7081 style: function( elem, name, value, extra ) { 7082 7083 // Don't set styles on text and comment nodes 7084 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 7085 return; 7086 } 7087 7088 // Make sure that we're working with the right name 7089 var ret, type, hooks, 7090 origName = jQuery.camelCase( name ), 7091 style = elem.style; 7092 7093 name = jQuery.cssProps[ origName ] || 7094 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); 7095 7096 // gets hook for the prefixed version 7097 // followed by the unprefixed version 7098 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7099 7100 // Check if we're setting a value 7101 if ( value !== undefined ) { 7102 type = typeof value; 7103 7104 // Convert "+=" or "-=" to relative numbers (#7345) 7105 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 7106 value = adjustCSS( elem, name, ret ); 7107 7108 // Fixes bug #9237 7109 type = "number"; 7110 } 7111 7112 // Make sure that null and NaN values aren't set. See: #7116 7113 if ( value == null || value !== value ) { 7114 return; 7115 } 7116 7117 // If a number was passed in, add the unit (except for certain CSS properties) 7118 if ( type === "number" ) { 7119 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 7120 } 7121 7122 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, 7123 // but it would mean to define eight 7124 // (for every problematic property) identical functions 7125 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 7126 style[ name ] = "inherit"; 7127 } 7128 7129 // If a hook was provided, use that value, otherwise just set the specified value
7130 if ( !hooks || !( "set" in hooks ) || 7131 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 7132 7133 // Support: IE 7134 // Swallow errors from 'invalid' CSS values (#5509) 7135 try { 7136 style[ name ] = value; 7137 } catch ( e ) {} 7138 } 7139 7140 } else { 7141 7142 // If a hook was provided get the non-computed value from there 7143 if ( hooks && "get" in hooks && 7144 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 7145 7146 return ret; 7147 } 7148 7149 // Otherwise just get the value from the style object 7150 return style[ name ]; 7151 } 7152 }, 7153 7154 css: function( elem, name, extra, styles ) { 7155 var num, val, hooks, 7156 origName = jQuery.camelCase( name ); 7157 7158 // Make sure that we're working with the right name 7159 name = jQuery.cssProps[ origName ] || 7160 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); 7161 7162 // gets hook for the prefixed version 7163 // followed by the unprefixed version 7164 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7165 7166 // If a hook was provided get the computed value from there 7167 if ( hooks && "get" in hooks ) { 7168 val = hooks.get( elem, true, extra ); 7169 } 7170 7171 // Otherwise, if a way to get the computed value exists, use that 7172 if ( val === undefined ) { 7173 val = curCSS( elem, name, styles ); 7174 } 7175 7176 //convert "normal" to computed value 7177 if ( val === "normal" && name in cssNormalTransform ) { 7178 val = cssNormalTransform[ name ]; 7179 } 7180 7181 // Return, converting to number if forced or a qualifier was provided and val looks numeric 7182 if ( extra === "" || extra ) { 7183 num = parseFloat( val ); 7184 return extra === true || isFinite( num ) ? num || 0 : val; 7185 } 7186 return val; 7187 } 7188} ); 7189 7190jQuery.each( [ "height", "width" ], function( i, name ) { 7191 jQuery.cssHooks[ name ] = { 7192 get: function( elem, computed, extra ) { 7193 if ( computed ) { 7194 7195 // certain elements can have dimension info if we invisibly show them 7196 // however, it must have a current display style that would benefit from this 7197 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 7198 elem.offsetWidth === 0 ? 7199 swap( elem, cssShow, function() { 7200 return getWidthOrHeight( elem, name, extra ); 7201 } ) : 7202 getWidthOrHeight( elem, name, extra ); 7203 } 7204 }, 7205 7206 set: function( elem, value, extra ) { 7207 var styles = extra && getStyles( elem ); 7208 return setPositiveNumber( elem, value, extra ? 7209 augmentWidthOrHeight( 7210 elem, 7211 name, 7212 extra, 7213 support.boxSizing && 7214 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 7215 styles 7216 ) : 0 7217 ); 7218 } 7219 }; 7220} ); 7221 7222if ( !support.opacity ) { 7223 jQuery.cssHooks.opacity = { 7224 get: function( elem, computed ) { 7225 7226 // IE uses filters for opacity 7227 return ropacity.test( ( computed && elem.currentStyle ? 7228 elem.currentStyle.filter : 7229 elem.style.filter ) || "" ) ? 7230 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : 7231 computed ? "1" : ""; 7232 }, 7233 7234 set: function( elem, value ) { 7235 var style = elem.style, 7236 currentStyle = elem.currentStyle, 7237 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", 7238 filter = currentStyle && currentStyle.filter || style.filter || ""; 7239 7240 // IE has trouble with opacity if it does not have layout 7241 // Force it by setting the zoom level 7242 style.zoom = 1; 7243 7244 // if setting opacity to 1, and no other filters exist - 7245 // attempt to remove filter attribute #6652 7246 // if value === "", then remove inline opacity #12685 7247 if ( ( value >= 1 || value === "" ) && 7248 jQuery.trim( filter.replace( ralpha, "" ) ) === "" && 7249 style.removeAttribute ) { 7250 7251 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText 7252 // if "filter:" is present at all, clearType is disabled, we want to avoid this 7253 // style.removeAttribute is IE Only, but so apparently is this code path... 7254 style.removeAttribute( "filter" ); 7255 7256 // if there is no filter style applied in a css rule 7257 // or unset inline opacity, we are done 7258 if ( value === "" || currentStyle && !currentStyle.filter ) { 7259 return; 7260 } 7261 } 7262 7263 // otherwise, set new filter values 7264 style.filter = ralpha.test( filter ) ? 7265 filter.replace( ralpha, opacity ) : 7266 filter + " " + opacity; 7267 } 7268 }; 7269} 7270 7271jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, 7272 function( elem, computed ) { 7273 if ( computed ) { 7274 return swap( elem, { "display": "inline-block" }, 7275 curCSS, [ elem, "marginRight" ] ); 7276 } 7277 } 7278); 7279 7280jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 7281 function( elem, computed ) { 7282 if ( computed ) { 7283 return ( 7284 parseFloat( curCSS( elem, "marginLeft" ) ) || 7285
vendor: 4,625 bytes, lines 7286-7464
7286 // Support: IE<=11+ 7287 // Running getBoundingClientRect on a disconnected node in IE throws an error 7288 // Support: IE8 only 7289 // getClientRects() errors on disconnected elems 7290 ( jQuery.contains( elem.ownerDocument, elem ) ? 7291 elem.getBoundingClientRect().left - 7292 swap( elem, { marginLeft: 0 }, function() { 7293 return elem.getBoundingClientRect().left; 7294 } ) : 7295 0 7296 ) 7297 ) + "px"; 7298 } 7299 } 7300); 7301 7302// These hooks are used by animate to expand properties 7303jQuery.each( { 7304 margin: "", 7305 padding: "", 7306 border: "Width" 7307}, function( prefix, suffix ) { 7308 jQuery.cssHooks[ prefix + suffix ] = { 7309 expand: function( value ) { 7310 var i = 0, 7311 expanded = {}, 7312 7313 // assumes a single number if not a string 7314 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 7315 7316 for ( ; i < 4; i++ ) { 7317 expanded[ prefix + cssExpand[ i ] + suffix ] = 7318 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 7319 } 7320 7321 return expanded; 7322 } 7323 }; 7324 7325 if ( !rmargin.test( prefix ) ) { 7326 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7327 } 7328} ); 7329 7330jQuery.fn.extend( { 7331 css: function( name, value ) { 7332 return access( this, function( elem, name, value ) { 7333 var styles, len, 7334 map = {}, 7335 i = 0; 7336 7337 if ( jQuery.isArray( name ) ) { 7338 styles = getStyles( elem ); 7339 len = name.length; 7340 7341 for ( ; i < len; i++ ) { 7342 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 7343 } 7344 7345 return map; 7346 } 7347 7348 return value !== undefined ? 7349 jQuery.style( elem, name, value ) : 7350 jQuery.css( elem, name ); 7351 }, name, value, arguments.length > 1 ); 7352 }, 7353 show: function() { 7354 return showHide( this, true ); 7355 }, 7356 hide: function() { 7357 return showHide( this ); 7358 }, 7359 toggle: function( state ) { 7360 if ( typeof state === "boolean" ) { 7361 return state ? this.show() : this.hide(); 7362 } 7363 7364 return this.each( function() { 7365 if ( isHidden( this ) ) { 7366 jQuery( this ).show(); 7367 } else { 7368 jQuery( this ).hide(); 7369 } 7370 } ); 7371 } 7372} ); 7373 7374 7375function Tween( elem, options, prop, end, easing ) { 7376 return new Tween.prototype.init( elem, options, prop, end, easing ); 7377} 7378jQuery.Tween = Tween; 7379 7380Tween.prototype = { 7381 constructor: Tween, 7382 init: function( elem, options, prop, end, easing, unit ) { 7383 this.elem = elem; 7384 this.prop = prop; 7385 this.easing = easing || jQuery.easing._default; 7386 this.options = options; 7387 this.start = this.now = this.cur(); 7388 this.end = end; 7389 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 7390 }, 7391 cur: function() { 7392 var hooks = Tween.propHooks[ this.prop ]; 7393 7394 return hooks && hooks.get ? 7395 hooks.get( this ) : 7396 Tween.propHooks._default.get( this ); 7397 }, 7398 run: function( percent ) { 7399 var eased, 7400 hooks = Tween.propHooks[ this.prop ]; 7401 7402 if ( this.options.duration ) { 7403 this.pos = eased = jQuery.easing[ this.easing ]( 7404 percent, this.options.duration * percent, 0, 1, this.options.duration 7405 ); 7406 } else { 7407 this.pos = eased = percent; 7408 } 7409 this.now = ( this.end - this.start ) * eased + this.start; 7410 7411 if ( this.options.step ) { 7412 this.options.step.call( this.elem, this.now, this ); 7413 } 7414 7415 if ( hooks && hooks.set ) { 7416 hooks.set( this ); 7417 } else { 7418 Tween.propHooks._default.set( this ); 7419 } 7420 return this; 7421 } 7422}; 7423 7424Tween.prototype.init.prototype = Tween.prototype; 7425 7426Tween.propHooks = { 7427 _default: { 7428 get: function( tween ) { 7429 var result; 7430 7431 // Use a property on the element directly when it is not a DOM element, 7432 // or when there is no matching style property that exists. 7433 if ( tween.elem.nodeType !== 1 || 7434 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 7435 return tween.elem[ tween.prop ]; 7436 } 7437 7438 // passing an empty string as a 3rd parameter to .css will automatically 7439 // attempt a parseFloat and fallback to a string if the parse fails 7440 // so, simple values such as "10px" are parsed to Float. 7441 // complex values such as "rotate(1rad)" are returned as is. 7442 result = jQuery.css( tween.elem, tween.prop, "" ); 7443 7444 // Empty strings, null, undefined and "auto" are converted to 0. 7445 return !result || result === "auto" ? 0 : result; 7446 }, 7447 set: function( tween ) { 7448 7449 // use step hook for back compat - use cssHook if its there - use .style if its 7450 // available and use plain properties where available 7451 if ( jQuery.fx.step[ tween.prop ] ) { 7452 jQuery.fx.step[ tween.prop ]( tween ); 7453 } else if ( tween.elem.nodeType === 1 && 7454 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || 7455 jQuery.cssHooks[ tween.prop ] ) ) { 7456 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 7457 } else { 7458 tween.elem[ tween.prop ] = tween.now; 7459 } 7460 } 7461 } 7462}; 7463 7464// Support: IE <=9
7465// Panic based approach to setting things on disconnected nodes 7466 7467Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7468 set: function( tween ) { 7469 if ( tween.elem.nodeType && tween.elem.parentNode ) { 7470 tween.elem[ tween.prop ] = tween.now; 7471 } 7472 } 7473}; 7474 7475jQuery.easing = { 7476 linear: function( p ) { 7477 return p; 7478 }, 7479 swing: function( p ) { 7480 return 0.5 - Math.cos( p * Math.PI ) / 2; 7481 }, 7482 _default: "swing" 7483}; 7484 7485jQuery.fx = Tween.prototype.init; 7486 7487// Back Compat <1.8 extension point 7488jQuery.fx.step = {}; 7489 7490 7491 7492 7493var 7494 fxNow, timerId, 7495 rfxtypes = /^(?:toggle|show|hide)$/, 7496 rrun = /queueHooks$/; 7497 7498// Animations created synchronously will run synchronously 7499function createFxNow() { 7500 window.setTimeout( function() { 7501 fxNow = undefined; 7502 } ); 7503 return ( fxNow = jQuery.now() ); 7504} 7505 7506// Generate parameters to create a standard animation 7507function genFx( type, includeWidth ) { 7508 var which, 7509 attrs = { height: type }, 7510 i = 0; 7511 7512 // if we include width, step value is 1 to do all cssExpand values, 7513 // if we don't include width, step value is 2 to skip over Left and Right 7514 includeWidth = includeWidth ? 1 : 0; 7515 for ( ; i < 4 ; i += 2 - includeWidth ) { 7516 which = cssExpand[ i ]; 7517 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 7518 } 7519 7520 if ( includeWidth ) { 7521 attrs.opacity = attrs.width = type; 7522 } 7523 7524 return attrs; 7525} 7526 7527function createTween( value, prop, animation ) { 7528 var tween, 7529 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 7530 index = 0, 7531 length = collection.length; 7532 for ( ; index < length; index++ ) { 7533 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 7534 7535 // we're done with this property 7536 return tween; 7537 } 7538 } 7539} 7540 7541function defaultPrefilter( elem, props, opts ) { 7542 /* jshint validthis: true */ 7543 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, 7544 anim = this, 7545 orig = {}, 7546 style = elem.style, 7547 hidden = elem.nodeType && isHidden( elem ), 7548 dataShow = jQuery._data( elem, "fxshow" ); 7549 7550 // handle queue: false promises 7551 if ( !opts.queue ) { 7552 hooks = jQuery._queueHooks( elem, "fx" ); 7553 if ( hooks.unqueued == null ) { 7554 hooks.unqueued = 0; 7555 oldfire = hooks.empty.fire; 7556 hooks.empty.fire = function() { 7557 if ( !hooks.unqueued ) { 7558 oldfire(); 7559 } 7560 }; 7561 } 7562 hooks.unqueued++; 7563 7564 anim.always( function() { 7565 7566 // doing this makes sure that the complete handler will be called 7567 // before this completes 7568 anim.always( function() { 7569 hooks.unqueued--; 7570 if ( !jQuery.queue( elem, "fx" ).length ) { 7571 hooks.empty.fire(); 7572 } 7573 } ); 7574 } ); 7575 } 7576 7577 // height/width overflow pass 7578 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { 7579 7580 // Make sure that nothing sneaks out 7581 // Record all 3 overflow attributes because IE does not 7582 // change the overflow attribute when overflowX and 7583 // overflowY are set to the same value 7584 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 7585 7586 // Set display property to inline-block for height/width 7587 // animations on inline elements that are having width/height animated 7588 display = jQuery.css( elem, "display" ); 7589 7590 // Test default display if display is currently "none" 7591 checkDisplay = display === "none" ? 7592 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; 7593 7594 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { 7595 7596 // inline-level elements accept inline-block; 7597 // block-level elements need to be inline with layout 7598 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) { 7599 style.display = "inline-block"; 7600 } else { 7601 style.zoom = 1; 7602 } 7603 } 7604 } 7605 7606 if ( opts.overflow ) { 7607 style.overflow = "hidden"; 7608 if ( !support.shrinkWrapBlocks() ) { 7609 anim.always( function() { 7610 style.overflow = opts.overflow[ 0 ]; 7611 style.overflowX = opts.overflow[ 1 ]; 7612 style.overflowY = opts.overflow[ 2 ]; 7613 } ); 7614 } 7615 } 7616 7617 // show/hide pass 7618 for ( prop in props ) { 7619 value = props[ prop ]; 7620 if ( rfxtypes.exec( value ) ) { 7621 delete props[ prop ]; 7622 toggle = toggle || value === "toggle"; 7623 if ( value === ( hidden ? "hide" : "show" ) ) { 7624 7625 // If there is dataShow left over from a stopped hide or show 7626 // and we are going to proceed with show, we should pretend to be hidden 7627 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 7628 hidden = true; 7629 } else { 7630 continue; 7631 } 7632 } 7633 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 7634 7635 // Any non-fx value stops us from restoring the original display value 7636 } else { 7637 display = undefined; 7638 } 7639 } 7640 7641 if ( !jQuery.isEmptyObject( orig ) ) { 7642 if ( dataShow ) { 7643 if ( "hidden" in dataShow ) { 7644 hidden = dataShow.hidden; 7645 } 7646 } else { 7647 dataShow = jQuery._data( elem, "fxshow", {} ); 7648 } 7649 7650 // store state if its toggle - enables .stop().toggle() to "reverse" 7651 if ( toggle ) { 7652 dataShow.hidden = !hidden; 7653 } 7654 if ( hidden ) { 7655 jQuery( elem ).show(); 7656 } else { 7657 anim.done( function() { 7658 jQuery( elem ).hide(); 7659 } ); 7660 } 7661 anim.done( function() { 7662 var prop; 7663 jQuery._removeData( elem, "fxshow" ); 7664 for ( prop in orig ) { 7665 jQuery.style( elem, prop, orig[ prop ] ); 7666 } 7667 } ); 7668 for ( prop in orig ) { 7669 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 7670 7671 if ( !( prop in dataShow ) ) { 7672 dataShow[ prop ] = tween.start; 7673 if ( hidden ) { 7674 tween.end = tween.start; 7675 tween.start = prop === "width" || prop === "height" ? 1 : 0; 7676 } 7677 } 7678 } 7679 7680 // If this is a noop like .hide().hide(), restore an overwritten display value 7681 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : dis
vendor: 10,851 bytes, lines 7681-8113
7681play ) === "inline" ) { 7682 style.display = display; 7683 } 7684} 7685 7686function propFilter( props, specialEasing ) { 7687 var index, name, easing, value, hooks; 7688 7689 // camelCase, specialEasing and expand cssHook pass 7690 for ( index in props ) { 7691 name = jQuery.camelCase( index ); 7692 easing = specialEasing[ name ]; 7693 value = props[ index ]; 7694 if ( jQuery.isArray( value ) ) { 7695 easing = value[ 1 ]; 7696 value = props[ index ] = value[ 0 ]; 7697 } 7698 7699 if ( index !== name ) { 7700 props[ name ] = value; 7701 delete props[ index ]; 7702 } 7703 7704 hooks = jQuery.cssHooks[ name ]; 7705 if ( hooks && "expand" in hooks ) { 7706 value = hooks.expand( value ); 7707 delete props[ name ]; 7708 7709 // not quite $.extend, this wont overwrite keys already present. 7710 // also - reusing 'index' from above because we have the correct "name" 7711 for ( index in value ) { 7712 if ( !( index in props ) ) { 7713 props[ index ] = value[ index ]; 7714 specialEasing[ index ] = easing; 7715 } 7716 } 7717 } else { 7718 specialEasing[ name ] = easing; 7719 } 7720 } 7721} 7722 7723function Animation( elem, properties, options ) { 7724 var result, 7725 stopped, 7726 index = 0, 7727 length = Animation.prefilters.length, 7728 deferred = jQuery.Deferred().always( function() { 7729 7730 // don't match elem in the :animated selector 7731 delete tick.elem; 7732 } ), 7733 tick = function() { 7734 if ( stopped ) { 7735 return false; 7736 } 7737 var currentTime = fxNow || createFxNow(), 7738 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 7739 7740 // Support: Android 2.3 7741 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 7742 temp = remaining / animation.duration || 0, 7743 percent = 1 - temp, 7744 index = 0, 7745 length = animation.tweens.length; 7746 7747 for ( ; index < length ; index++ ) { 7748 animation.tweens[ index ].run( percent ); 7749 } 7750 7751 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 7752 7753 if ( percent < 1 && length ) { 7754 return remaining; 7755 } else { 7756 deferred.resolveWith( elem, [ animation ] ); 7757 return false; 7758 } 7759 }, 7760 animation = deferred.promise( { 7761 elem: elem, 7762 props: jQuery.extend( {}, properties ), 7763 opts: jQuery.extend( true, { 7764 specialEasing: {}, 7765 easing: jQuery.easing._default 7766 }, options ), 7767 originalProperties: properties, 7768 originalOptions: options, 7769 startTime: fxNow || createFxNow(), 7770 duration: options.duration, 7771 tweens: [], 7772 createTween: function( prop, end ) { 7773 var tween = jQuery.Tween( elem, animation.opts, prop, end, 7774 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 7775 animation.tweens.push( tween ); 7776 return tween; 7777 }, 7778 stop: function( gotoEnd ) { 7779 var index = 0, 7780 7781 // if we are going to the end, we want to run all the tweens 7782 // otherwise we skip this part 7783 length = gotoEnd ? animation.tweens.length : 0; 7784 if ( stopped ) { 7785 return this; 7786 } 7787 stopped = true; 7788 for ( ; index < length ; index++ ) { 7789 animation.tweens[ index ].run( 1 ); 7790 } 7791 7792 // resolve when we played the last frame 7793 // otherwise, reject 7794 if ( gotoEnd ) { 7795 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7796 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 7797 } else { 7798 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 7799 } 7800 return this; 7801 } 7802 } ), 7803 props = animation.props; 7804 7805 propFilter( props, animation.opts.specialEasing ); 7806 7807 for ( ; index < length ; index++ ) { 7808 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 7809 if ( result ) { 7810 if ( jQuery.isFunction( result.stop ) ) { 7811 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 7812 jQuery.proxy( result.stop, result ); 7813 } 7814 return result; 7815 } 7816 } 7817 7818 jQuery.map( props, createTween, animation ); 7819 7820 if ( jQuery.isFunction( animation.opts.start ) ) { 7821 animation.opts.start.call( elem, animation ); 7822 } 7823 7824 jQuery.fx.timer( 7825 jQuery.extend( tick, { 7826 elem: elem, 7827 anim: animation, 7828 queue: animation.opts.queue 7829 } ) 7830 ); 7831 7832 // attach callbacks from options 7833 return animation.progress( animation.opts.progress ) 7834 .done( animation.opts.done, animation.opts.complete ) 7835 .fail( animation.opts.fail ) 7836 .always( animation.opts.always ); 7837} 7838 7839jQuery.Animation = jQuery.extend( Animation, { 7840 7841 tweeners: { 7842 "*": [ function( prop, value ) { 7843 var tween = this.createTween( prop, value ); 7844 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 7845 return tween; 7846 } ] 7847 }, 7848 7849 tweener: function( props, callback ) { 7850 if ( jQuery.isFunction( props ) ) { 7851 callback = props; 7852 props = [ "*" ]; 7853 } else { 7854 props = props.match( rnotwhite ); 7855 } 7856 7857 var prop, 7858 index = 0, 7859 length = props.length; 7860 7861 for ( ; index < length ; index++ ) { 7862 prop = props[ index ]; 7863 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 7864 Animation.tweeners[ prop ].unshift( callback ); 7865 } 7866 }, 7867 7868 prefilters: [ defaultPrefilter ], 7869 7870 prefilter: function( callback, prepend ) { 7871 if ( prepend ) { 7872 Animation.prefilters.unshift( callback ); 7873 } else { 7874 Animation.prefilters.push( callback ); 7875 } 7876 } 7877} ); 7878 7879jQuery.speed = function( speed, easing, fn ) { 7880 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 7881 complete: fn || !fn && easing || 7882 jQuery.isFunction( speed ) && speed, 7883 duration: speed, 7884 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 7885 }; 7886 7887 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 7888 opt.duration in jQuery.fx.speeds ? 7889 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 7890 7891 // normalize opt.queue - true/undefined/null -> "fx" 7892 if ( opt.queue == null || opt.queue === true ) { 7893 opt.queue = "fx"; 7894 } 7895 7896 // Queueing 7897 opt.old = opt.complete; 7898 7899 opt.complete = function() { 7900 if ( jQuery.isFunction( opt.old ) ) { 7901 opt.old.call( this ); 7902 } 7903 7904 if ( opt.queue ) { 7905 jQuery.dequeue( this, opt.queue ); 7906 } 7907 }; 7908 7909 return opt; 7910}; 7911 7912jQuery.fn.extend( { 7913 fadeTo: function( speed, to, easing, callback ) { 7914 7915 // show any hidden elements after setting opacity to 0 7916 return this.filter( isHidden ).css( "opacity", 0 ).show() 7917 7918 // animate to the value specified 7919 .end().animate( { opacity: to }, speed, easing, callback ); 7920 }, 7921 animate: function( prop, speed, easing, callback ) { 7922 var empty = jQuery.isEmptyObject( prop ), 7923 optall = jQuery.speed( speed, easing, callback ), 7924 doAnimation = function() { 7925 7926 // Operate on a copy of prop so per-property easing won't be lost 7927 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 7928 7929 // Empty animations, or finishing resolves immediately 7930 if ( empty || jQuery._data( this, "finish" ) ) { 7931 anim.stop( true ); 7932 } 7933 }; 7934 doAnimation.finish = doAnimation; 7935 7936 return empty || optall.queue === false ? 7937 this.each( doAnimation ) : 7938 this.queue( optall.queue, doAnimation ); 7939 }, 7940 stop: function( type, clearQueue, gotoEnd ) { 7941 var stopQueue = function( hooks ) { 7942 var stop = hooks.stop; 7943 delete hooks.stop; 7944 stop( gotoEnd ); 7945 }; 7946 7947 if ( typeof type !== "string" ) { 7948 gotoEnd = clearQueue; 7949 clearQueue = type; 7950 type = undefined; 7951 } 7952 if ( clearQueue && type !== false ) { 7953 this.queue( type || "fx", [] ); 7954 } 7955 7956 return this.each( function() { 7957 var dequeue = true, 7958 index = type != null && type + "queueHooks", 7959 timers = jQuery.timers, 7960 data = jQuery._data( this ); 7961 7962 if ( index ) { 7963 if ( data[ index ] && data[ index ].stop ) { 7964 stopQueue( data[ index ] ); 7965 } 7966 } else { 7967 for ( index in data ) { 7968 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 7969 stopQueue( data[ index ] ); 7970 } 7971 } 7972 } 7973 7974 for ( index = timers.length; index--; ) { 7975 if ( timers[ index ].elem === this && 7976 ( type == null || timers[ index ].queue === type ) ) { 7977 7978 timers[ index ].anim.stop( gotoEnd ); 7979 dequeue = false; 7980 timers.splice( index, 1 ); 7981 } 7982 } 7983 7984 // start the next in the queue if the last step wasn't forced 7985 // timers currently will call their complete callbacks, which will dequeue 7986 // but only if they were gotoEnd 7987 if ( dequeue || !gotoEnd ) { 7988 jQuery.dequeue( this, type ); 7989 } 7990 } ); 7991 }, 7992 finish: function( type ) { 7993 if ( type !== false ) { 7994 type = type || "fx"; 7995 } 7996 return this.each( function() { 7997 var index, 7998 data = jQuery._data( this ), 7999 queue = data[ type + "queue" ], 8000 hooks = data[ type + "queueHooks" ], 8001 timers = jQuery.timers, 8002 length = queue ? queue.length : 0; 8003 8004 // enable finishing flag on private data 8005 data.finish = true; 8006 8007 // empty the queue first 8008 jQuery.queue( this, type, [] ); 8009 8010 if ( hooks && hooks.stop ) { 8011 hooks.stop.call( this, true ); 8012 } 8013 8014 // look for any active animations, and finish them 8015 for ( index = timers.length; index--; ) { 8016 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 8017 timers[ index ].anim.stop( true ); 8018 timers.splice( index, 1 ); 8019 } 8020 } 8021 8022 // look for any animations in the old queue and finish them 8023 for ( index = 0; index < length; index++ ) { 8024 if ( queue[ index ] && queue[ index ].finish ) { 8025 queue[ index ].finish.call( this ); 8026 } 8027 } 8028 8029 // turn off finishing flag 8030 delete data.finish; 8031 } ); 8032 } 8033} ); 8034 8035jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { 8036 var cssFn = jQuery.fn[ name ]; 8037 jQuery.fn[ name ] = function( speed, easing, callback ) { 8038 return speed == null || typeof speed === "boolean" ? 8039 cssFn.apply( this, arguments ) : 8040 this.animate( genFx( name, true ), speed, easing, callback ); 8041 }; 8042} ); 8043 8044// Generate shortcuts for custom animations 8045jQuery.each( { 8046 slideDown: genFx( "show" ), 8047 slideUp: genFx( "hide" ), 8048 slideToggle: genFx( "toggle" ), 8049 fadeIn: { opacity: "show" }, 8050 fadeOut: { opacity: "hide" }, 8051 fadeToggle: { opacity: "toggle" } 8052}, function( name, props ) { 8053 jQuery.fn[ name ] = function( speed, easing, callback ) { 8054 return this.animate( props, speed, easing, callback ); 8055 }; 8056} ); 8057 8058jQuery.timers = []; 8059jQuery.fx.tick = function() { 8060 var timer, 8061 timers = jQuery.timers, 8062 i = 0; 8063 8064 fxNow = jQuery.now(); 8065 8066 for ( ; i < timers.length; i++ ) { 8067 timer = timers[ i ]; 8068 8069 // Checks the timer has not already been removed 8070 if ( !timer() && timers[ i ] === timer ) { 8071 timers.splice( i--, 1 ); 8072 } 8073 } 8074 8075 if ( !timers.length ) { 8076 jQuery.fx.stop(); 8077 } 8078 fxNow = undefined; 8079}; 8080 8081jQuery.fx.timer = function( timer ) { 8082 jQuery.timers.push( timer ); 8083 if ( timer() ) { 8084 jQuery.fx.start(); 8085 } else { 8086 jQuery.timers.pop(); 8087 } 8088}; 8089 8090jQuery.fx.interval = 13; 8091 8092jQuery.fx.start = function() { 8093 if ( !timerId ) { 8094 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); 8095 } 8096}; 8097 8098jQuery.fx.stop = function() { 8099 window.clearInterval( timerId ); 8100 timerId = null; 8101}; 8102 8103jQuery.fx.speeds = { 8104 slow: 600, 8105 fast: 200, 8106 8107 // Default speed 8108 _default: 400 8109}; 8110 8111 8112// Based off of the plugin by Clint Helfers, with permission. 8113// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8114jQuery.fn.delay = function( time, type ) { 8115 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 8116 type = type || "fx"; 8117 8118 return this.queue( type, function( next, hooks ) { 8119 var timeout = window.setTimeout( next, time ); 8120 hooks.stop = function() { 8121 window.clearTimeout( timeout ); 8122 }; 8123 } ); 8124}; 8125 8126 8127( function() { 8128 var a, 8129 input = document.createElement( "input" ), 8130 div = document.createElement( "div" ), 8131 select = document.createElement( "select" ), 8132 opt = select.appendChild( document.createElement( "option" ) ); 8133 8134 // Setup 8135 div = document.createElement( "div" ); 8136 div.setAttribute( "className", "t" ); 8137 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; 8138 a = div.getElementsByTagName( "a" )[ 0 ]; 8139 8140 // Support: Windows Web Apps (WWA) 8141 // `type` must use .setAttribute for WWA (#14901) 8142 input.setAttribute( "type", "checkbox" ); 8143 div.appendChild( input ); 8144 8145 a = div.getElementsByTagName( "a" )[ 0 ]; 8146 8147 // First batch of tests. 8148 a.style.cssText = "top:1px"; 8149 8150 // Test setAttribute on camelCase class. 8151 // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8152 support.getSetAttribute = div.className !== "t"; 8153 8154 // Get the style information from getAttribute 8155 // (IE uses .cssText instead) 8156 support.style = /top/.test( a.getAttribute( "style" ) ); 8157 8158 // Make sure that URLs aren't manipulated 8159 // (IE normalizes it by default) 8160 support.hrefNormalized = a.getAttribute( "href" ) === "/a"; 8161 8162 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) 8163 support.checkOn = !!input.value; 8164 8165 // Make sure that a selected-by-default option has a working selected property. 8166 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 8167 support.optSelected = opt.selected; 8168 8169 // Tests for enctype support on a form (#6743) 8170 support.enctype = !!document.createElement( "form" ).enctype; 8171 8172 // Make sure that the options inside disabled selects aren't marked as disabled 8173 // (WebKit marks them as disabled) 8174 select.disabled = true; 8175 support.optDisabled = !opt.disabled; 8176 8177 // Support: IE8 only 8178 // Check if we can trust getAttribute("value") 8179 input = document.createElement( "input" ); 8180 input.setAttribute( "value", "" ); 8181 support.input = input.getAttribute( "value" ) === ""; 8182 8183 // Check if an input maintains its value after becoming a radio 8184 input.value = "t"; 8185 input.setAttribute( "type", "radio" ); 8186 support.radioValue = input.value === "t"; 8187} )(); 8188 8189 8190var rreturn = /\r/g, 8191 rspaces = /[\x20\t\r\n\f]+/g; 8192 8193jQuery.fn.extend( { 8194 val: function( value ) { 8195 var hooks, ret, isFunction, 8196 elem = this[ 0 ]; 8197 8198 if ( !arguments.length ) { 8199 if ( elem ) { 8200 hooks = jQuery.valHooks[ elem.type ] || 8201 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 8202 8203 if ( 8204 hooks && 8205 "get" in hooks && 8206 ( ret = hooks.get( elem, "value" ) ) !== undefined 8207 ) { 8208 return ret; 8209 } 8210 8211 ret = elem.value; 8212 8213 return typeof ret === "string" ? 8214 8215 // handle most common string cases 8216 ret.replace( rreturn, "" ) : 8217 8218 // handle cases where value is null/undef or number 8219 ret == null ? "" : ret; 8220 } 8221 8222 return; 8223 } 8224 8225 isFunction = jQuery.isFunction( value ); 8226 8227 return this.each( function( i ) { 8228 var val; 8229 8230 if ( this.nodeType !== 1 ) { 8231 return; 8232 } 8233 8234 if ( isFunction ) { 8235 val = value.call( this, i, jQuery( this ).val() ); 8236 } else { 8237 val = value; 8238 } 8239 8240 // Treat null/undefined as ""; convert numbers to string 8241 if ( val == null ) { 8242 val = ""; 8243 } else if ( typeof val === "number" ) { 8244 val += ""; 8245 } else if ( jQuery.isArray( val ) ) { 8246 val = jQuery.map( val, function( value ) { 8247 return value == null ? "" : value + ""; 8248 } ); 8249 } 8250 8251 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 8252 8253 // If set returns undefined, fall back to normal setting
8254 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 8255 this.value = val; 8256 } 8257 } ); 8258 } 8259} ); 8260 8261jQuery.extend( { 8262 valHooks: { 8263 option: { 8264 get: function( elem ) { 8265 var val = jQuery.find.attr( elem, "value" ); 8266 return val != null ? 8267 val : 8268 8269 // Support: IE10-11+ 8270 // option.text throws exceptions (#14686, #14858) 8271 // Strip and collapse whitespace 8272 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8273 jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " ); 8274 } 8275 }, 8276 select: { 8277 get: function( elem ) { 8278 var value, option, 8279 options = elem.options, 8280 index = elem.selectedIndex, 8281 one = elem.type === "select-one" || index < 0, 8282 values = one ? null : [], 8283 max = one ? index + 1 : options.length, 8284 i = index < 0 ? 8285 max : 8286 one ? index : 0; 8287 8288 // Loop through all the selected options 8289 for ( ; i < max; i++ ) { 8290 option = options[ i ]; 8291 8292 // oldIE doesn't update selected after form reset (#2551) 8293 if ( ( option.selected || i === index ) && 8294 8295 // Don't return options that are disabled or in a disabled optgroup 8296 ( support.optDisabled ? 8297 !option.disabled : 8298 option.getAttribute( "disabled" ) === null ) && 8299 ( !option.parentNode.disabled || 8300 !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { 8301 8302 // Get the specific value for the option 8303 value = jQuery( option ).val(); 8304 8305 // We don't need an array for one selects 8306 if ( one ) { 8307 return value; 8308 } 8309 8310 // Multi-Selects return an array 8311 values.push( value ); 8312 } 8313 } 8314 8315 return values; 8316 }, 8317 8318 set: function( elem, value ) { 8319 var optionSet, option, 8320 options = elem.options, 8321 values = jQuery.makeArray( value ), 8322 i = options.length; 8323 8324 while ( i-- ) { 8325 option = options[ i ]; 8326 8327 if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { 8328 8329 // Support: IE6 8330 // When new option element is added to select box we need to 8331 // force reflow of newly added node in order to workaround delay 8332 // of initialization properties 8333 try { 8334 option.selected = optionSet = true; 8335 8336 } catch ( _ ) { 8337 8338 // Will be executed only in IE6 8339 option.scrollHeight; 8340 } 8341 8342 } else { 8343 option.selected = false; 8344 } 8345 } 8346 8347 // Force browsers to behave consistently when non-matching value is set 8348 if ( !optionSet ) { 8349 elem.selectedIndex = -1; 8350 } 8351 8352 return options; 8353 } 8354 } 8355 } 8356} ); 8357 8358// Radios and checkboxes getter/setter 8359jQuery.each( [ "radio", "checkbox" ], function() { 8360 jQuery.valHooks[ this ] = { 8361 set: function( elem, value ) { 8362 if ( jQuery.isArray( value ) ) { 8363 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 8364 } 8365 } 8366 }; 8367 if ( !support.checkOn ) { 8368 jQuery.valHooks[ this ].get = function( elem ) { 8369 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 8370 }; 8371 } 8372} ); 8373 8374 8375 8376 8377var nodeHook, boolHook, 8378 attrHandle = jQuery.expr.attrHandle, 8379 ruseDefault = /^(?:checked|selected)$/i, 8380 getSetAttribute = support.getSetAttribute, 8381 getSetInput = support.input; 8382 8383jQuery.fn.extend( { 8384 attr: function( name, value ) { 8385 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 8386 }, 8387 8388 removeAttr: function( name ) { 8389 return this.each( function() { 8390 jQuery.removeAttr( this, name ); 8391 } ); 8392 } 8393} ); 8394 8395jQuery.extend( { 8396 attr: function( elem, name, value ) { 8397 var ret, hooks, 8398 nType = elem.nodeType; 8399 8400 // Don't get/set attributes on text, comment and attribute nodes 8401 if ( nType === 3 || nType === 8 || nType === 2 ) { 8402 return; 8403 } 8404 8405 // Fallback to prop when attributes are not supported 8406 if ( typeof elem.getAttribute === "undefined" ) { 8407 return jQuery.prop( elem, name, value ); 8408 } 8409 8410 // All attributes are lowercase 8411 // Grab necessary hook if one is defined 8412 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8413 name = name.toLowerCase(); 8414 hooks = jQuery.attrHooks[ name ] || 8415 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); 8416 } 8417 8418 if ( value !== undefined ) { 8419 if ( value === null ) { 8420 jQuery.removeAttr( elem, name ); 8421 return; 8422 } 8423 8424 if ( hooks && "set" in hooks && 8425 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8426 return ret; 8427 } 8428 8429 elem.setAttribute( name, value + "" ); 8430 return value; 8431 } 8432 8433 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8434 return ret; 8435 } 8436 8437 ret = jQuery.find.attr( elem, name ); 8438 8439 // Non-existent attributes return null, we normalize to undefined 8440 return ret == null ? undefined : ret; 8441 }, 8442 8443 attrHooks: { 8444 type: {
8445 set: function( elem, value ) { 8446 if ( !support.radioValue && value === "radio" && 8447 jQuery.nodeName( elem, "input" ) ) { 8448 8449 // Setting the type on a radio button after the value resets the value in IE8-9 8450 // Reset value to default in case type is set after value during creation 8451 var val = elem.value; 8452 elem.setAttribute( "type", value ); 8453 if ( val ) { 8454 elem.value = val; 8455 } 8456 return value; 8457 } 8458 } 8459 } 8460 }, 8461 8462 removeAttr: function( elem, value ) { 8463 var name, propName, 8464 i = 0, 8465 attrNames = value && value.match( rnotwhite ); 8466 8467 if ( attrNames && elem.nodeType === 1 ) { 8468 while ( ( name = attrNames[ i++ ] ) ) { 8469 propName = jQuery.propFix[ name ] || name; 8470 8471 // Boolean attributes get special treatment (#10870) 8472 if ( jQuery.expr.match.bool.test( name ) ) { 8473 8474 // Set corresponding property to false 8475 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { 8476 elem[ propName ] = false; 8477 8478 // Support: IE<9 8479 // Also clear defaultChecked/defaultSelected (if appropriate) 8480 } else { 8481 elem[ jQuery.camelCase( "default-" + name ) ] = 8482 elem[ propName ] = false; 8483 } 8484 8485 // See #9699 for explanation of this approach (setting first, then removal) 8486 } else { 8487 jQuery.attr( elem, name, "" ); 8488 } 8489 8490 elem.removeAttribute( getSetAttribute ? name : propName ); 8491 } 8492 } 8493 } 8494} ); 8495 8496// Hooks for boolean attributes 8497boolHook = { 8498 set: function( elem, value, name ) { 8499 if ( value === false ) { 8500 8501 // Remove boolean attributes when set to false 8502 jQuery.removeAttr( elem, name ); 8503 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { 8504 8505 // IE<8 needs the *property* name 8506 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); 8507 8508 } else { 8509 8510 // Support: IE<9 8511 // Use defaultChecked and defaultSelected for oldIE 8512 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; 8513 } 8514 return name; 8515 } 8516}; 8517 8518jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 8519 var getter = attrHandle[ name ] || jQuery.find.attr; 8520 8521 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { 8522 attrHandle[ name ] = function( elem, name, isXML ) { 8523 var ret, handle; 8524 if ( !isXML ) { 8525 8526 // Avoid an infinite loop by temporarily removing this function from the getter 8527 handle = attrHandle[ name ]; 8528 attrHandle[ name ] = ret; 8529 ret = getter( elem, name, isXML ) != null ? 8530 name.toLowerCase() : 8531 null; 8532 attrHandle[ name ] = handle; 8533 } 8534 return ret; 8535 }; 8536 } else { 8537 attrHandle[ name ] = function( elem, name, isXML ) { 8538 if ( !isXML ) { 8539 return elem[ jQuery.camelCase( "default-" + name ) ] ? 8540 name.toLowerCase() : 8541 null; 8542 } 8543 }; 8544 } 8545} ); 8546 8547// fix oldIE attroperties 8548if ( !getSetInput || !getSetAttribute ) { 8549 jQuery.attrHooks.value = { 8550 set: function( elem, value, name ) { 8551 if ( jQuery.nodeName( elem, "input" ) ) { 8552 8553 // Does not return so that setAttribute is also used 8554 elem.defaultValue = value; 8555 } else { 8556 8557 // Use nodeHook if defined (#1954); otherwise setAttribute is fine 8558 return nodeHook && nodeHook.set( elem, value, name ); 8559 } 8560 } 8561 }; 8562} 8563 8564// IE6/7 do not support getting/setting some attributes with get/setAttribute 8565if ( !getSetAttribute ) { 8566 8567 // Use this for any attribute in IE6/7 8568 // This fixes almost every IE6/7 issue 8569 nodeHook = { 8570 set: function( elem, value, name ) { 8571 8572 // Set the existing or create a new attribute node 8573 var ret = elem.getAttributeNode( name ); 8574 if ( !ret ) { 8575 elem.setAttributeNode( 8576 ( ret = elem.ownerDocument.createAttribute( name ) ) 8577 ); 8578 } 8579 8580 ret.value = value += ""; 8581 8582 // Break association with cloned elements by also using setAttribute (#9646) 8583 if ( name === "value" || value === elem.getAttribute( name ) ) { 8584 return value; 8585 } 8586 } 8587 }; 8588 8589 // Some attributes are constructed with empty-string values when not defined 8590 attrHandle.id = attrHandle.name = attrHandle.coords = 8591 function( elem, name, isXML ) { 8592 var ret; 8593 if ( !isXML ) { 8594 return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ? 8595 ret.value : 8596 null; 8597 } 8598 }; 8599 8600 // Fixing value retrieval on a button requires this module 8601 jQuery.valHooks.button = { 8602 get: function( elem, name ) { 8603 var ret = elem.getAttributeNode( name ); 8604 if ( ret && ret.specified ) { 8605 return ret.value; 8606 } 8607 }, 8608 set: nodeHook.set 8609 }; 8610 8611 // Set contenteditable to false on removals(#10429)
8612 // Setting to empty string throws an error as an invalid value 8613 jQuery.attrHooks.contenteditable = { 8614 set: function( elem, value, name ) { 8615 nodeHook.set( elem, value === "" ? false : value, name ); 8616 } 8617 }; 8618 8619 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 8620 // This is for removals 8621 jQuery.each( [ "width", "height" ], function( i, name ) { 8622 jQuery.attrHooks[ name ] = { 8623 set: function( elem, value ) { 8624 if ( value === "" ) { 8625 elem.setAttribute( name, "auto" ); 8626 return value; 8627 } 8628 } 8629 }; 8630 } ); 8631} 8632 8633if ( !support.style ) { 8634 jQuery.attrHooks.style = { 8635 get: function( elem ) { 8636 8637 // Return undefined in the case of empty string 8638 // Note: IE uppercases css property names, but if we were to .toLowerCase() 8639 // .cssText, that would destroy case sensitivity in URL's, like in "background" 8640 return elem.style.cssText || undefined; 8641 }, 8642 set: function( elem, value ) { 8643 return ( elem.style.cssText = value + "" ); 8644 } 8645 }; 8646} 8647 8648 8649 8650 8651var rfocusable = /^(?:input|select|textarea|button|object)$/i, 8652 rclickable = /^(?:a|area)$/i; 8653 8654jQuery.fn.extend( { 8655 prop: function( name, value ) { 8656 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 8657 }, 8658 8659 removeProp: function( name ) { 8660 name = jQuery.propFix[ name ] || name; 8661 return this.each( function() { 8662 8663 // try/catch handles cases where IE balks (such as removing a property on window) 8664 try { 8665 this[ name ] = undefined; 8666 delete this[ name ]; 8667 } catch ( e ) {} 8668 } ); 8669 } 8670} ); 8671 8672jQuery.extend( { 8673 prop: function( elem, name, value ) { 8674 var ret, hooks, 8675 nType = elem.nodeType; 8676 8677 // Don't get/set properties on text, comment and attribute nodes 8678 if ( nType === 3 || nType === 8 || nType === 2 ) { 8679 return; 8680 } 8681 8682 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8683 8684 // Fix name and attach hooks 8685 name = jQuery.propFix[ name ] || name; 8686 hooks = jQuery.propHooks[ name ]; 8687 } 8688 8689 if ( value !== undefined ) { 8690 if ( hooks && "set" in hooks && 8691 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8692 return ret; 8693 } 8694 8695 return ( elem[ name ] = value ); 8696 } 8697 8698 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8699 return ret; 8700 } 8701 8702 return elem[ name ]; 8703 }, 8704 8705 propHooks: { 8706 tabIndex: { 8707 get: function( elem ) { 8708 8709 // elem.tabIndex doesn't always return the 8710 // correct value when it hasn't been explicitly set 8711 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 8712 // Use proper attribute retrieval(#12072) 8713 var tabindex = jQuery.find.attr( elem, "tabindex" ); 8714 8715 return tabindex ? 8716 parseInt( tabindex, 10 ) : 8717 rfocusable.test( elem.nodeName ) || 8718 rclickable.test( elem.nodeName ) && elem.href ? 8719 0 : 8720 -1; 8721 } 8722 } 8723 }, 8724 8725 propFix: { 8726 "for": "htmlFor", 8727 "class": "className" 8728 } 8729} ); 8730 8731// Some attributes require a special call on IE 8732// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 8733if ( !support.hrefNormalized ) { 8734 8735 // href/src property should get the full normalized URL (#10299/#12915) 8736 jQuery.each( [ "href", "src" ], function( i, name ) { 8737 jQuery.propHooks[ name ] = { 8738 get: function( elem ) { 8739 return elem.getAttribute( name, 4 ); 8740 } 8741 }; 8742 } ); 8743} 8744 8745// Support: Safari, IE9+ 8746// Accessing the selectedIndex property 8747// forces the browser to respect setting selected 8748// on the option 8749// The getter ensures a default option is selected 8750// when in an optgroup 8751if ( !support.optSelected ) { 8752 jQuery.propHooks.selected = { 8753 get: function( elem ) { 8754 var parent = elem.parentNode; 8755 8756 if ( parent ) { 8757 parent.selectedIndex; 8758 8759 // Make sure that it also works with optgroups, see #5701 8760 if ( parent.parentNode ) { 8761 parent.parentNode.selectedIndex; 8762 } 8763 } 8764 return null; 8765 }, 8766 set: function( elem ) { 8767 var parent = elem.parentNode; 8768 if ( parent ) { 8769 parent.selectedIndex; 8770 8771 if ( parent.parentNode ) { 8772 parent.parentNode.selectedIndex; 8773 } 8774 } 8775 } 8776 }; 8777} 8778 8779jQuery.each( [ 8780 "tabIndex", 8781 "readOnly", 8782 "maxLength", 8783 "cellSpacing", 8784 "cellPadding", 8785 "rowSpan", 8786 "colSpan", 8787 "useMap", 8788 "frameBorder", 8789 "contentEditable" 8790], function() { 8791 jQuery.propFix[ this.toLowerCase() ] = this; 8792} ); 8793 8794// IE6/7 call enctype encoding 8795if ( !support.enctype ) { 8796 jQuery.propFix.enctype = "encoding"; 8797} 8798 8799 8800 8801 8802var rclass = /[\t\r\n\f]/g; 8803 8804function getClass( elem ) { 8805 return jQuery.attr( elem, "class" ) || ""; 8806} 8807 8808jQuery.fn.extend( { 8809 addClass: function( value ) { 8810 var classes, elem, cur, curValue, clazz, j, finalValue, 8811 i = 0; 8812 8813 if ( jQuery.isFunction( value ) ) { 8814 return this.each( function( j ) { 8815 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 8816 } ); 8817 } 8818 8819 if ( typeof value === "string" && value ) { 8820 classes = value.match( rnotwhite ) || []; 8821 8822 while ( ( elem = this[ i++ ] ) ) { 8823 curValue = getClass( elem ); 8824 cur = elem.nodeType === 1 && 8825 ( " " + curValue + " " ).replace( rclass, " " ); 8826 8827 if ( cur ) { 8828 j = 0; 8829 while ( ( clazz = classes[ j++ ] ) ) { 8830 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 8831 cur += clazz + " "; 8832 } 8833 } 8834 8835 // only assign if different to avoid unneeded rendering. 8836 finalValue = jQuery.trim( cur ); 8837 if ( curValue !== finalValue ) { 8838 jQuery.attr( elem, "class", finalValue ); 8839 } 8840 } 8841 } 8842 } 8843 8844 return this; 8845 }, 8846 8847 removeClass: function( value ) { 8848 var classes, elem, cur, curValue, clazz, j, finalValue, 8849 i = 0; 8850 8851 if ( jQuery.isFunction( value ) ) { 8852 return this.each( function( j ) { 8853 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 8854 } ); 8855 } 8856 8857 if ( !arguments.length ) { 8858 return this.attr( "class", "" ); 8859 } 8860 8861 if ( typeof value === "string" && value ) { 8862 classes = value.match( rnotwhite ) || []; 8863 8864 while ( ( elem = this[ i++ ] ) ) { 8865 curValue = getClass( elem ); 8866 8867 // This expression is here for better compressibility (see addClass) 8868 cur = elem.nodeType === 1 && 8869 ( " " + curValue + " " ).replace( rclass, " " ); 8870 8871 if ( cur ) { 8872 j = 0; 8873 while ( ( clazz = classes[ j++ ] ) ) { 8874
8875 // Remove *all* instances 8876 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 8877 cur = cur.replace( " " + clazz + " ", " " ); 8878 } 8879 } 8880 8881 // Only assign if different to avoid unneeded rendering. 8882 finalValue = jQuery.trim( cur ); 8883 if ( curValue !== finalValue ) { 8884 jQuery.attr( elem, "class", finalValue ); 8885 } 8886 } 8887 } 8888 } 8889 8890 return this; 8891 }, 8892 8893 toggleClass: function( value, stateVal ) { 8894 var type = typeof value; 8895 8896 if ( typeof stateVal === "boolean" && type === "string" ) { 8897 return stateVal ? this.addClass( value ) : this.removeClass( value ); 8898 } 8899 8900 if ( jQuery.isFunction( value ) ) { 8901 return this.each( function( i ) { 8902 jQuery( this ).toggleClass( 8903 value.call( this, i, getClass( this ), stateVal ), 8904 stateVal 8905 ); 8906 } ); 8907 } 8908 8909 return this.each( function() { 8910 var className, i, self, classNames; 8911 8912 if ( type === "string" ) { 8913 8914 // Toggle individual class names 8915 i = 0; 8916 self = jQuery( this ); 8917 classNames = value.match( rnotwhite ) || []; 8918 8919 while ( ( className = classNames[ i++ ] ) ) { 8920 8921 // Check each className given, space separated list 8922 if ( self.hasClass( className ) ) { 8923 self.removeClass( className ); 8924 } else { 8925 self.addClass( className ); 8926 } 8927 } 8928 8929 // Toggle whole class name 8930 } else if ( value === undefined || type === "boolean" ) { 8931 className = getClass( this ); 8932 if ( className ) { 8933 8934 // store className if set 8935 jQuery._data( this, "__className__", className ); 8936 } 8937 8938 // If the element has a class name or if we're passed "false", 8939 // then remove the whole classname (if there was one, the above saved it). 8940 // Otherwise bring back whatever was previously saved (if anything), 8941 // falling back to the empty string if nothing was stored. 8942 jQuery.attr( this, "class", 8943 className || value === false ? 8944 "" : 8945 jQuery._data( this, "__className__" ) || "" 8946 ); 8947 } 8948 } ); 8949 }, 8950 8951 hasClass: function( selector ) { 8952 var className, elem, 8953 i = 0; 8954 8955 className = " " + selector + " "; 8956 while ( ( elem = this[ i++ ] ) ) { 8957 if ( elem.nodeType === 1 && 8958 ( " " + getClass( elem ) + " " ).replace( rclass, " " ) 8959 .indexOf( className ) > -1 8960 ) { 8961 return true; 8962 } 8963 } 8964 8965 return false; 8966 } 8967} ); 8968 8969 8970 8971 8972// Return jQuery for attributes-only inclusion 8973 8974 8975jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " + 8976 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 8977 "change select submit keydown keypress keyup error contextmenu" ).split( " " ), 8978 function( i, name ) { 8979 8980 // Handle event binding 8981 jQuery.fn[ name ] = function( data, fn ) { 8982 return arguments.length > 0 ? 8983 this.on( name, null, data, fn ) : 8984 this.trigger( name ); 8985 }; 8986} ); 8987 8988jQuery.fn.extend( { 8989 hover: function( fnOver, fnOut ) { 8990 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 8991 } 8992} ); 8993 8994 8995var location = window.location; 8996 8997var nonce = jQuery.now(); 8998 8999var rquery = ( /\?/ ); 9000 9001 9002 9003var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; 9004 9005jQuery.parseJSON = function( data ) { 9006 9007 // Attempt to parse using the native JSON parser first 9008 if ( window.JSON && window.JSON.parse ) { 9009 9010 // Support: Android 2.3 9011 // Workaround failure to string-cast null input 9012 return window.JSON.parse( data + "" ); 9013 } 9014 9015 var requireNonComma, 9016 depth = null, 9017 str = jQuery.trim( data + "" ); 9018 9019 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains 9020 // after removing valid tokens 9021 return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) { 9022 9023 // Force termination if we see a misplaced comma 9024 if ( requireNonComma && comma ) { 9025 depth = 0; 9026 } 9027 9028 // Perform no more replacements after returning to outermost depth 9029 if ( depth === 0 ) { 9030 return token; 9031 } 9032 9033 // Commas must not follow "[", "{", or "," 9034 requireNonComma = open || comma; 9035 9036 // Determine new depth 9037 // array/object open ("[" or "{"): depth += true - false (increment) 9038 // array/object close ("]" or "}"): depth += false - true (decrement) 9039 // other cases ("," or primitive): depth += true - true (numeric cast) 9040 depth += !close - !open; 9041 9042 // Remove this token 9043 return ""; 9044 } ) ) ? 9045 ( Function( "return " + str ) )() : 9046 jQuery.error( "Invalid JSON: " + data ); 9047}; 9048 9049 9050// Cross-browser xml parsing
9051jQuery.parseXML = function( data ) { 9052 var xml, tmp; 9053 if ( !data || typeof data !== "string" ) { 9054 return null; 9055 } 9056 try { 9057 if ( window.DOMParser ) { // Standard 9058 tmp = new window.DOMParser(); 9059 xml = tmp.parseFromString( data, "text/xml" ); 9060 } else { // IE 9061 xml = new window.ActiveXObject( "Microsoft.XMLDOM" ); 9062 xml.async = "false"; 9063 xml.loadXML( data ); 9064 } 9065 } catch ( e ) { 9066 xml = undefined; 9067 } 9068 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { 9069 jQuery.error( "Invalid XML: " + data ); 9070 } 9071 return xml; 9072}; 9073 9074 9075var 9076 rhash = /#.*$/, 9077 rts = /([?&])_=[^&]*/, 9078 9079 // IE leaves an \r character at EOL 9080 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, 9081 9082 // #7653, #8125, #8152: local protocol detection 9083 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 9084 rnoContent = /^(?:GET|HEAD)$/, 9085 rprotocol = /^\/\//, 9086 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, 9087 9088 /* Prefilters 9089 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 9090 * 2) These are called: 9091 * - BEFORE asking for a transport 9092 * - AFTER param serialization (s.data is a string if s.processData is true) 9093 * 3) key is the dataType 9094 * 4) the catchall symbol "*" can be used 9095 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 9096 */ 9097 prefilters = {}, 9098 9099 /* Transports bindings 9100 * 1) key is the dataType 9101 * 2) the catchall symbol "*" can be used 9102 * 3) selection will start with transport dataType and THEN go to "*" if needed 9103 */ 9104 transports = {}, 9105 9106 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 9107 allTypes = "*/".concat( "*" ), 9108 9109 // Document location 9110 ajaxLocation = location.href, 9111 9112 // Segment location into parts 9113 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 9114 9115// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 9116function addToPrefiltersOrTransports( structure ) { 9117 9118 // dataTypeExpression is optional and defaults to "*" 9119 return function( dataTypeExpression, func ) { 9120 9121 if ( typeof dataTypeExpression !== "string" ) { 9122 func = dataTypeExpression; 9123 dataTypeExpression = "*"; 9124 } 9125 9126 var dataType, 9127 i = 0, 9128 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; 9129 9130 if ( jQuery.isFunction( func ) ) { 9131 9132 // For each dataType in the dataTypeExpression 9133 while ( ( dataType = dataTypes[ i++ ] ) ) { 9134 9135 // Prepend if requested 9136 if ( dataType.charAt( 0 ) === "+" ) { 9137 dataType = dataType.slice( 1 ) || "*"; 9138 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 9139 9140 // Otherwise append 9141 } else { 9142 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 9143 } 9144 } 9145 } 9146 }; 9147} 9148 9149// Base inspection function for prefilters and transports 9150function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 9151 9152 var inspected = {}, 9153 seekingTransport = ( structure === transports ); 9154 9155 function inspect( dataType ) { 9156 var selected; 9157 inspected[ dataType ] = true; 9158 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 9159 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 9160 if ( typeof dataTypeOrTransport === "string" && 9161 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 9162 9163 options.dataTypes.unshift( dataTypeOrTransport ); 9164 inspect( dataTypeOrTransport ); 9165 return false; 9166 } else if ( seekingTransport ) { 9167 return !( selected = dataTypeOrTransport ); 9168 } 9169 } ); 9170 return selected; 9171 } 9172 9173 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 9174} 9175 9176// A special extend for ajax options 9177// that takes "flat" options (not to be deep extended) 9178// Fixes #9887 9179function ajaxExtend( target, src ) { 9180 var deep, key, 9181 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 9182 9183 for ( key in src ) { 9184 if ( src[ key ] !== undefined ) { 9185 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 9186 } 9187 } 9188 if ( deep ) { 9189 jQuery.extend( true, target, deep ); 9190 } 9191 9192 return target; 9193} 9194 9195/* Handles responses to an ajax request: 9196 * - finds the right dataType (mediates between content-type and expected dataType) 9197 * - returns the corresponding response 9198 */ 9199function ajaxHandleResponses( s, jqXHR, responses ) { 9200 var firstDataType, ct, finalDataType, type, 9201 contents = s.contents, 9202 dataTypes = s.dataTypes; 9203 9204 // Remove auto dataType and get content-type in the process 9205 while ( dataTypes[ 0 ] === "*" ) { 9206 dataTypes.shift(); 9207 if ( ct === undefined ) { 9208 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 9209 } 9210 } 9211 9212 // Check if we're dealing with a known content-type 9213 if ( ct ) { 9214 for ( type in contents ) { 9215 if ( contents[ type ] && contents[ type ].test( ct ) ) { 9216 dataTypes.unshift( type ); 9217 break; 9218 } 9219 } 9220 } 9221 9222 // Check to see if we have a response for the expected dataType 9223 if ( dataTypes[ 0 ] in responses ) { 9224 finalDataType = dataTypes[ 0 ]; 9225 } else { 9226
vendor: 5,407 bytes, lines 9227-9456
9227 // Try convertible dataTypes 9228 for ( type in responses ) { 9229 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 9230 finalDataType = type; 9231 break; 9232 } 9233 if ( !firstDataType ) { 9234 firstDataType = type; 9235 } 9236 } 9237 9238 // Or just use first one 9239 finalDataType = finalDataType || firstDataType; 9240 } 9241 9242 // If we found a dataType 9243 // We add the dataType to the list if needed 9244 // and return the corresponding response 9245 if ( finalDataType ) { 9246 if ( finalDataType !== dataTypes[ 0 ] ) { 9247 dataTypes.unshift( finalDataType ); 9248 } 9249 return responses[ finalDataType ]; 9250 } 9251} 9252 9253/* Chain conversions given the request and the original response 9254 * Also sets the responseXXX fields on the jqXHR instance 9255 */ 9256function ajaxConvert( s, response, jqXHR, isSuccess ) { 9257 var conv2, current, conv, tmp, prev, 9258 converters = {}, 9259 9260 // Work with a copy of dataTypes in case we need to modify it for conversion 9261 dataTypes = s.dataTypes.slice(); 9262 9263 // Create converters map with lowercased keys 9264 if ( dataTypes[ 1 ] ) { 9265 for ( conv in s.converters ) { 9266 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 9267 } 9268 } 9269 9270 current = dataTypes.shift(); 9271 9272 // Convert to each sequential dataType 9273 while ( current ) { 9274 9275 if ( s.responseFields[ current ] ) { 9276 jqXHR[ s.responseFields[ current ] ] = response; 9277 } 9278 9279 // Apply the dataFilter if provided 9280 if ( !prev && isSuccess && s.dataFilter ) { 9281 response = s.dataFilter( response, s.dataType ); 9282 } 9283 9284 prev = current; 9285 current = dataTypes.shift(); 9286 9287 if ( current ) { 9288 9289 // There's only work to do if current dataType is non-auto 9290 if ( current === "*" ) { 9291 9292 current = prev; 9293 9294 // Convert response if prev dataType is non-auto and differs from current 9295 } else if ( prev !== "*" && prev !== current ) { 9296 9297 // Seek a direct converter 9298 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 9299 9300 // If none found, seek a pair 9301 if ( !conv ) { 9302 for ( conv2 in converters ) { 9303 9304 // If conv2 outputs current 9305 tmp = conv2.split( " " ); 9306 if ( tmp[ 1 ] === current ) { 9307 9308 // If prev can be converted to accepted input 9309 conv = converters[ prev + " " + tmp[ 0 ] ] || 9310 converters[ "* " + tmp[ 0 ] ]; 9311 if ( conv ) { 9312 9313 // Condense equivalence converters 9314 if ( conv === true ) { 9315 conv = converters[ conv2 ]; 9316 9317 // Otherwise, insert the intermediate dataType 9318 } else if ( converters[ conv2 ] !== true ) { 9319 current = tmp[ 0 ]; 9320 dataTypes.unshift( tmp[ 1 ] ); 9321 } 9322 break; 9323 } 9324 } 9325 } 9326 } 9327 9328 // Apply converter (if not an equivalence) 9329 if ( conv !== true ) { 9330 9331 // Unless errors are allowed to bubble, catch and return them 9332 if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation 9333 response = conv( response ); 9334 } else { 9335 try { 9336 response = conv( response ); 9337 } catch ( e ) { 9338 return { 9339 state: "parsererror", 9340 error: conv ? e : "No conversion from " + prev + " to " + current 9341 }; 9342 } 9343 } 9344 } 9345 } 9346 } 9347 } 9348 9349 return { state: "success", data: response }; 9350} 9351 9352jQuery.extend( { 9353 9354 // Counter for holding the number of active queries 9355 active: 0, 9356 9357 // Last-Modified header cache for next request 9358 lastModified: {}, 9359 etag: {}, 9360 9361 ajaxSettings: { 9362 url: ajaxLocation, 9363 type: "GET", 9364 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 9365 global: true, 9366 processData: true, 9367 async: true, 9368 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9369 /* 9370 timeout: 0, 9371 data: null, 9372 dataType: null, 9373 username: null, 9374 password: null, 9375 cache: null, 9376 throws: false, 9377 traditional: false, 9378 headers: {}, 9379 */ 9380 9381 accepts: { 9382 "*": allTypes, 9383 text: "text/plain", 9384 html: "text/html", 9385 xml: "application/xml, text/xml", 9386 json: "application/json, text/javascript" 9387 }, 9388 9389 contents: { 9390 xml: /\bxml\b/, 9391 html: /\bhtml/, 9392 json: /\bjson\b/ 9393 }, 9394 9395 responseFields: { 9396 xml: "responseXML", 9397 text: "responseText", 9398 json: "responseJSON" 9399 }, 9400 9401 // Data converters 9402 // Keys separate source (or catchall "*") and destination types with a single space 9403 converters: { 9404 9405 // Convert anything to text 9406 "* text": String, 9407 9408 // Text to html (true = no transformation) 9409 "text html": true, 9410 9411 // Evaluate text as a json expression 9412 "text json": jQuery.parseJSON, 9413 9414 // Parse text as xml 9415 "text xml": jQuery.parseXML 9416 }, 9417 9418 // For options that shouldn't be deep extended: 9419 // you can add your own custom options here if 9420 // and when you create one that shouldn't be 9421 // deep extended (see ajaxExtend) 9422 flatOptions: { 9423 url: true, 9424 context: true 9425 } 9426 }, 9427 9428 // Creates a full fledged settings object into target 9429 // with both ajaxSettings and settings fields. 9430 // If target is omitted, writes into ajaxSettings. 9431 ajaxSetup: function( target, settings ) { 9432 return settings ? 9433 9434 // Building a settings object 9435 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 9436 9437 // Extending ajaxSettings 9438 ajaxExtend( jQuery.ajaxSettings, target ); 9439 }, 9440 9441 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 9442 ajaxTransport: addToPrefiltersOrTransports( transports ), 9443 9444 // Main method 9445 ajax: function( url, options ) { 9446 9447 // If url is an object, simulate pre-1.5 signature 9448 if ( typeof url === "object" ) { 9449 options = url; 9450 url = undefined; 9451 } 9452 9453 // Force options to be an object 9454 options = options || {}; 9455 9456 var
9457 9458 // Cross-domain detection vars 9459 parts, 9460 9461 // Loop variable 9462 i, 9463 9464 // URL without anti-cache param 9465 cacheURL, 9466 9467 // Response headers as string 9468 responseHeadersString, 9469 9470 // timeout handle 9471 timeoutTimer, 9472 9473 // To know if global events are to be dispatched 9474 fireGlobals, 9475 9476 transport, 9477 9478 // Response headers 9479 responseHeaders, 9480 9481 // Create the final options object 9482 s = jQuery.ajaxSetup( {}, options ), 9483 9484 // Callbacks context 9485 callbackContext = s.context || s, 9486 9487 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9488 globalEventContext = s.context && 9489 ( callbackContext.nodeType || callbackContext.jquery ) ? 9490 jQuery( callbackContext ) : 9491 jQuery.event, 9492 9493 // Deferreds 9494 deferred = jQuery.Deferred(), 9495 completeDeferred = jQuery.Callbacks( "once memory" ), 9496 9497 // Status-dependent callbacks 9498 statusCode = s.statusCode || {}, 9499 9500 // Headers (they are sent all at once) 9501 requestHeaders = {}, 9502 requestHeadersNames = {}, 9503 9504 // The jqXHR state 9505 state = 0, 9506 9507 // Default abort message 9508 strAbort = "canceled", 9509 9510 // Fake xhr 9511 jqXHR = { 9512 readyState: 0, 9513 9514 // Builds headers hashtable if needed 9515 getResponseHeader: function( key ) { 9516 var match; 9517 if ( state === 2 ) { 9518 if ( !responseHeaders ) { 9519 responseHeaders = {}; 9520 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 9521 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; 9522 } 9523 } 9524 match = responseHeaders[ key.toLowerCase() ]; 9525 } 9526 return match == null ? null : match; 9527 }, 9528 9529 // Raw string 9530 getAllResponseHeaders: function() { 9531 return state === 2 ? responseHeadersString : null; 9532 }, 9533 9534 // Caches the header 9535 setRequestHeader: function( name, value ) { 9536 var lname = name.toLowerCase(); 9537 if ( !state ) { 9538 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 9539 requestHeaders[ name ] = value; 9540 } 9541 return this; 9542 }, 9543 9544 // Overrides response content-type header 9545 overrideMimeType: function( type ) { 9546 if ( !state ) { 9547 s.mimeType = type; 9548 } 9549 return this; 9550 }, 9551 9552 // Status-dependent callbacks 9553 statusCode: function( map ) { 9554 var code; 9555 if ( map ) { 9556 if ( state < 2 ) { 9557 for ( code in map ) { 9558 9559 // Lazy-add the new callback in a way that preserves old ones 9560 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 9561 } 9562 } else { 9563 9564 // Execute the appropriate callbacks 9565 jqXHR.always( map[ jqXHR.status ] ); 9566 } 9567 } 9568 return this; 9569 }, 9570 9571 // Cancel the request 9572 abort: function( statusText ) { 9573 var finalText = statusText || strAbort; 9574 if ( transport ) { 9575 transport.abort( finalText ); 9576 } 9577 done( 0, finalText ); 9578 return this; 9579 } 9580 }; 9581 9582 // Attach deferreds 9583 deferred.promise( jqXHR ).complete = completeDeferred.add; 9584 jqXHR.success = jqXHR.done; 9585 jqXHR.error = jqXHR.fail; 9586 9587 // Remove hash character (#7531: and string promotion) 9588 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 9589 // Handle falsy url in the settings object (#10093: consistency with old signature) 9590 // We also use the url parameter if available 9591 s.url = ( ( url || s.url || ajaxLocation ) + "" ) 9592 .replace( rhash, "" ) 9593 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 9594 9595 // Alias method option to type as per ticket #12004 9596 s.type = options.method || options.type || s.method || s.type; 9597 9598 // Extract dataTypes list 9599 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; 9600 9601 // A cross-domain request is in order when we have a protocol:host:port mismatch 9602 if ( s.crossDomain == null ) { 9603 parts = rurl.exec( s.url.toLowerCase() ); 9604 s.crossDomain = !!( parts && 9605 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || 9606 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== 9607 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) 9608 ); 9609 } 9610 9611 // Convert data if not already a string 9612 if ( s.data && s.processData && typeof s.data !== "string" ) { 9613 s.data = jQuery.param( s.data, s.traditional ); 9614 } 9615 9616 // Apply prefilters 9617 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 9618 9619 // If request was aborted inside a prefilter, stop there 9620 if ( state === 2 ) { 9621 return jqXHR; 9622 } 9623 9624 // We can fire global events as of now if asked to 9625 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 9626 fireGlobals = jQuery.event && s.global; 9627 9628 // Watch for a new set of requests 9629 if ( fireGlobals && jQuery.active++ === 0 ) { 9630 jQuery.event.trigger( "ajaxStart" ); 9631 } 9632 9633 // Uppercase the type 9634 s.type = s.type.toUpperCase(); 9635 9636 // Determine if request has content 9637 s.hasContent = !rnoContent.test( s.type ); 9638 9639 // Save the URL in case we're toying with the If-Modified-Since 9640 // and/or If-None-Match header later on 9641 cacheURL = s.url; 9642 9643 // More options handling for requests with no content 9644 if ( !s.hasContent ) { 9645 9646 // If data is available, append data to url 9647 if ( s.data ) {
9648 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); 9649 9650 // #9682: remove data so that it's not used in an eventual retry 9651 delete s.data; 9652 } 9653 9654 // Add anti-cache in url if needed 9655 if ( s.cache === false ) { 9656 s.url = rts.test( cacheURL ) ? 9657 9658 // If there is already a '_' parameter, set its value 9659 cacheURL.replace( rts, "$1_=" + nonce++ ) : 9660 9661 // Otherwise add one to the end 9662 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; 9663 } 9664 } 9665 9666 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9667 if ( s.ifModified ) { 9668 if ( jQuery.lastModified[ cacheURL ] ) { 9669 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 9670 } 9671 if ( jQuery.etag[ cacheURL ] ) { 9672 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 9673 } 9674 } 9675 9676 // Set the correct header, if data is being sent 9677 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 9678 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 9679 } 9680 9681 // Set the Accepts header for the server, depending on the dataType 9682 jqXHR.setRequestHeader( 9683 "Accept", 9684 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 9685 s.accepts[ s.dataTypes[ 0 ] ] + 9686 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 9687 s.accepts[ "*" ] 9688 ); 9689 9690 // Check for headers option 9691 for ( i in s.headers ) { 9692 jqXHR.setRequestHeader( i, s.headers[ i ] ); 9693 } 9694 9695 // Allow custom headers/mimetypes and early abort 9696 if ( s.beforeSend && 9697 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 9698 9699 // Abort if not done already and return 9700 return jqXHR.abort(); 9701 } 9702 9703 // aborting is no longer a cancellation 9704 strAbort = "abort"; 9705 9706 // Install callbacks on deferreds 9707 for ( i in { success: 1, error: 1, complete: 1 } ) { 9708 jqXHR[ i ]( s[ i ] ); 9709 } 9710 9711 // Get transport 9712 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 9713 9714 // If no transport, we auto-abort 9715 if ( !transport ) { 9716 done( -1, "No Transport" ); 9717 } else { 9718 jqXHR.readyState = 1; 9719 9720 // Send global event 9721 if ( fireGlobals ) { 9722 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 9723 } 9724 9725 // If request was aborted inside ajaxSend, stop there 9726 if ( state === 2 ) { 9727 return jqXHR; 9728 } 9729 9730 // Timeout 9731 if ( s.async && s.timeout > 0 ) { 9732 timeoutTimer = window.setTimeout( function() { 9733 jqXHR.abort( "timeout" ); 9734 }, s.timeout ); 9735 } 9736 9737 try { 9738 state = 1; 9739 transport.send( requestHeaders, done ); 9740 } catch ( e ) { 9741 9742 // Propagate exception as error if not done 9743 if ( state < 2 ) { 9744 done( -1, e ); 9745 9746 // Simply rethrow otherwise 9747 } else { 9748 throw e; 9749 } 9750 } 9751 } 9752 9753 // Callback for when everything is done 9754 function done( status, nativeStatusText, responses, headers ) { 9755 var isSuccess, success, error, response, modified, 9756 statusText = nativeStatusText; 9757 9758 // Called once 9759 if ( state === 2 ) { 9760 return; 9761 } 9762 9763 // State is "done" now 9764 state = 2; 9765 9766 // Clear timeout if it exists 9767 if ( timeoutTimer ) { 9768 window.clearTimeout( timeoutTimer ); 9769 } 9770 9771 // Dereference transport for early garbage collection 9772 // (no matter how long the jqXHR object will be used) 9773 transport = undefined; 9774 9775 // Cache response headers 9776 responseHeadersString = headers || ""; 9777 9778 // Set readyState 9779 jqXHR.readyState = status > 0 ? 4 : 0; 9780 9781 // Determine if successful 9782 isSuccess = status >= 200 && status < 300 || status === 304; 9783 9784 // Get response data 9785 if ( responses ) { 9786 response = ajaxHandleResponses( s, jqXHR, responses ); 9787 } 9788 9789 // Convert no matter what (that way responseXXX fields are always set) 9790 response = ajaxConvert( s, response, jqXHR, isSuccess ); 9791 9792 // If successful, handle type chaining 9793 if ( isSuccess ) { 9794 9795 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9796 if ( s.ifModified ) { 9797 modified = jqXHR.getResponseHeader( "Last-Modified" ); 9798 if ( modified ) { 9799 jQuery.lastModified[ cacheURL ] = modified; 9800 } 9801 modified = jqXHR.getResponseHeader( "etag" ); 9802 if ( modified ) { 9803 jQuery.etag[ cacheURL ] = modified; 9804 } 9805 } 9806 9807 // if no content 9808 if ( status === 204 || s.type === "HEAD" ) { 9809 statusText = "nocontent"; 9810 9811 // if not modified 9812 } else if ( status === 304 ) { 9813 statusText = "notmodified"; 9814 9815 // If we have data, let's convert it 9816 } else { 9817 statusText = response.state; 9818 success = response.data; 9819 error = response.error; 9820 isSuccess = !error; 9821 } 9822 } else { 9823 9824 // We extract error from statusText 9825 // then normalize statusText and status for non-aborts 9826 error = statusText; 9827 if ( status || !statusText ) { 9828 statusText = "error"; 9829 if ( status < 0 ) { 9830 status = 0; 9831 } 9832 } 9833 } 9834 9835 // Set data for the fake xhr object 9836 jqXHR.status = status; 9837 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 9838 9839 // Success/Error 9840 if ( isSuccess ) { 9841 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 9842 } else { 9843 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 9844 } 9845 9846 // Status-dependent callbacks 9847 jqXHR.statusCode( statusCode ); 9848 statusCode = undefined; 9849 9850 if ( fireGlobals ) { 9851 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 9852 [ jqXHR, s, isSuccess ? success : error ] ); 9853 } 9854 9855 // Complete 9856 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 9857 9858 if ( fireGlobals ) { 9859 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 9860 9861 // Handle the global AJAX counter 9862 if ( !( --jQuery.active ) ) { 9863 jQuery.event.trigger( "ajaxStop" ); 9864 } 9865 } 9866 } 9867 9868 return jqXHR; 9869 }, 9870 9871 getJSON: function( url, data, callback ) { 9872 return jQuery.get( url, data, callback, "json" ); 9873 }, 9874 9875 getScript: function( url, callback ) { 9876 return jQuery.get( url, undefined, callback, "script" ); 9877 } 9878} ); 9879 9880jQuery.each( [ "get", "post" ], function( i, method ) { 9881 jQuery[ method ] = function( url, data, callback, type ) { 9882 9883 // shift arguments if data argument was omitted 9884 if ( jQuery.isFunction( data ) ) { 9885 type = type || callback; 9886 callback = data; 9887 data = undefined; 9888 } 9889 9890 // The url can be an options object (which then must have .url) 9891 return jQuery.ajax( jQuery.extend( { 9892 url: url, 9893 type: method, 9894 dataType: type, 9895 data: data, 9896 success: callback 9897 }, jQuery.isPlainObject( url ) && url ) ); 9898 }; 9899} ); 9900 9901 9902jQuery._evalUrl = function( url ) { 9903 return jQuery.ajax( { 9904 url: url, 9905 9906 // Make this explicit, since user can override this through ajaxSetup (#11264) 9907 type: "GET", 9908 dataType: "script", 9909 cache: true, 9910 async: false, 9911 global: false, 9912 "throws": true 9913 } ); 9914}; 9915 9916 9917jQuery.fn.extend( { 9918 wrapAll: function( html ) { 9919 if ( jQuery.isFunction( html ) ) { 9920 return this.each( function( i ) { 9921 jQuery( this ).wrapAll( html.call( this, i ) ); 9922 } ); 9923 } 9924 9925 if ( this[ 0 ] ) { 9926 9927 // The elements to wrap the target around 9928 var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 9929 9930 if ( this[ 0 ].parentNode ) { 9931 wrap.insertBefore( this[ 0 ] ); 9932 } 9933 9934 wrap.map( function() { 9935 var elem = this; 9936 9937 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 9938 elem = elem.firstChild; 9939 } 9940 9941 return elem; 9942 } ).append( this ); 9943 } 9944 9945 return this; 9946 }, 9947 9948 wrapInner: function( html ) { 9949 if ( jQuery.isFunction( html ) ) { 9950 return this.each( function( i ) { 9951 jQuery( this ).wrapInner( html.call( this, i ) ); 9952 } ); 9953 } 9954 9955 return this.each( function() { 9956 var self = jQuery( this ), 9957 contents = self.contents(); 9958 9959 if ( contents.length ) { 9960 contents.wrapAll( html ); 9961 9962 } else { 9963 self.append( html ); 9964 } 9965 } ); 9966 }, 9967 9968 wrap: function( html ) { 9969 var isFunction = jQuery.isFunction( html ); 9970 9971 return this.each( function( i ) { 9972 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); 9973 } ); 9974 }, 9975 9976 unwrap: function() { 9977 return this.parent().each( function() { 9978 if ( !jQuery.nodeName( this, "body" ) ) { 9979 jQuery( this ).replaceWith( this.childNodes ); 9980 } 9981 } ).end(); 9982 } 9983} ); 9984 9985 9986function getDisplay( elem ) { 9987 return elem.style && elem.style.display || jQuery.css( elem, "dis
9987play" ); 9988} 9989 9990function filterHidden( elem ) { 9991 9992 // Disconnected elements are considered hidden 9993 if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) { 9994 return true; 9995 } 9996 while ( elem && elem.nodeType === 1 ) { 9997 if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) { 9998 return true; 9999 } 10000 elem = elem.parentNode; 10001 } 10002 return false; 10003} 10004 10005jQuery.expr.filters.hidden = function( elem ) { 10006 10007 // Support: Opera <= 12.12 10008 // Opera reports offsetWidths and offsetHeights less than zero on some elements 10009 return support.reliableHiddenOffsets() ? 10010 ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 && 10011 !elem.getClientRects().length ) : 10012 filterHidden( elem ); 10013}; 10014 10015jQuery.expr.filters.visible = function( elem ) { 10016 return !jQuery.expr.filters.hidden( elem ); 10017}; 10018 10019 10020 10021 10022var r20 = /%20/g, 10023 rbracket = /\[\]$/, 10024 rCRLF = /\r?\n/g, 10025 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 10026 rsubmittable = /^(?:input|select|textarea|keygen)/i; 10027 10028function buildParams( prefix, obj, traditional, add ) { 10029 var name; 10030 10031 if ( jQuery.isArray( obj ) ) { 10032 10033 // Serialize array item. 10034 jQuery.each( obj, function( i, v ) { 10035 if ( traditional || rbracket.test( prefix ) ) { 10036 10037 // Treat each array item as a scalar. 10038 add( prefix, v ); 10039 10040 } else { 10041 10042 // Item is non-scalar (array or object), encode its numeric index. 10043 buildParams( 10044 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 10045 v, 10046 traditional, 10047 add 10048 ); 10049 } 10050 } ); 10051 10052 } else if ( !traditional && jQuery.type( obj ) === "object" ) { 10053 10054 // Serialize object item. 10055 for ( name in obj ) { 10056 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 10057 } 10058 10059 } else { 10060 10061 // Serialize scalar item. 10062 add( prefix, obj ); 10063 } 10064} 10065 10066// Serialize an array of form elements or a set of 10067// key/values into a query string 10068jQuery.param = function( a, traditional ) { 10069 var prefix, 10070 s = [], 10071 add = function( key, value ) { 10072 10073 // If value is a function, invoke it and return its value 10074 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); 10075 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 10076 }; 10077 10078 // Set traditional to true for jQuery <= 1.3.2 behavior. 10079 if ( traditional === undefined ) { 10080 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; 10081 } 10082 10083 // If an array was passed in, assume that it is an array of form elements. 10084 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 10085 10086 // Serialize the form elements 10087 jQuery.each( a, function() { 10088 add( this.name, this.value ); 10089 } ); 10090 10091 } else { 10092 10093 // If traditional, encode the "old" way (the way 1.3.2 or older 10094 // did it), otherwise encode params recursively. 10095 for ( prefix in a ) { 10096 buildParams( prefix, a[ prefix ], traditional, add ); 10097 } 10098 } 10099 10100 // Return the resulting serialization 10101 return s.join( "&" ).replace( r20, "+" ); 10102}; 10103 10104jQuery.fn.extend( { 10105 serialize: function() { 10106 return jQuery.param( this.serializeArray() ); 10107 }, 10108 serializeArray: function() { 10109 return this.map( function() { 10110 10111 // Can add propHook for "elements" to filter or add form elements 10112 var elements = jQuery.prop( this, "elements" ); 10113 return elements ? jQuery.makeArray( elements ) : this; 10114 } ) 10115 .filter( function() { 10116 var type = this.type; 10117 10118 // Use .is(":disabled") so that fieldset[disabled] works 10119 return this.name && !jQuery( this ).is( ":disabled" ) && 10120 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 10121 ( this.checked || !rcheckableType.test( type ) ); 10122 } ) 10123 .map( function( i, elem ) { 10124 var val = jQuery( this ).val(); 10125 10126 return val == null ? 10127 null : 10128 jQuery.isArray( val ) ? 10129 jQuery.map( val, function( val ) { 10130 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 10131 } ) : 10132 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 10133 } ).get(); 10134 } 10135} ); 10136 10137 10138// Create the request object 10139// (This is still attached to ajaxSettings for backward compatibility) 10140jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ? 10141 10142 // Support: IE6-IE8 10143 function() { 10144 10145 // XHR cannot access local files, always use ActiveX for that case 10146 if ( this.isLocal ) { 10147 return createActiveXHR(); 10148 } 10149
10150 // Support: IE 9-11 10151 // IE seems to error on cross-domain PATCH requests when ActiveX XHR 10152 // is used. In IE 9+ always use the native XHR. 10153 // Note: this condition won't catch Edge as it doesn't define 10154 // document.documentMode but it also doesn't support ActiveX so it won't 10155 // reach this code. 10156 if ( document.documentMode > 8 ) { 10157 return createStandardXHR(); 10158 } 10159 10160 // Support: IE<9 10161 // oldIE XHR does not support non-RFC2616 methods (#13240) 10162 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx 10163 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 10164 // Although this check for six methods instead of eight 10165 // since IE also does not support "trace" and "connect" 10166 return /^(get|post|head|put|delete|options)$/i.test( this.type ) && 10167 createStandardXHR() || createActiveXHR(); 10168 } : 10169 10170 // For all other browsers, use the standard XMLHttpRequest object 10171 createStandardXHR; 10172 10173var xhrId = 0, 10174 xhrCallbacks = {}, 10175 xhrSupported = jQuery.ajaxSettings.xhr(); 10176 10177// Support: IE<10 10178// Open requests must be manually aborted on unload (#5280) 10179// See https://support.microsoft.com/kb/2856746 for more info 10180if ( window.attachEvent ) { 10181 window.attachEvent( "onunload", function() { 10182 for ( var key in xhrCallbacks ) { 10183 xhrCallbacks[ key ]( undefined, true ); 10184 } 10185 } ); 10186} 10187 10188// Determine support properties 10189support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 10190xhrSupported = support.ajax = !!xhrSupported; 10191 10192// Create transport if the browser can provide an xhr 10193if ( xhrSupported ) { 10194 10195 jQuery.ajaxTransport( function( options ) { 10196 10197 // Cross domain only allowed if supported through XMLHttpRequest 10198 if ( !options.crossDomain || support.cors ) { 10199 10200 var callback; 10201 10202 return { 10203 send: function( headers, complete ) { 10204 var i, 10205 xhr = options.xhr(), 10206 id = ++xhrId; 10207 10208 // Open the socket 10209 xhr.open( 10210 options.type, 10211 options.url, 10212 options.async, 10213 options.username, 10214 options.password 10215 ); 10216 10217 // Apply custom fields if provided 10218 if ( options.xhrFields ) { 10219 for ( i in options.xhrFields ) { 10220 xhr[ i ] = options.xhrFields[ i ]; 10221 } 10222 } 10223 10224 // Override mime type if needed 10225 if ( options.mimeType && xhr.overrideMimeType ) { 10226 xhr.overrideMimeType( options.mimeType ); 10227 } 10228 10229 // X-Requested-With header 10230 // For cross-domain requests, seeing as conditions for a preflight are 10231 // akin to a jigsaw puzzle, we simply never set it to be sure. 10232 // (it can always be set on a per-request basis or even using ajaxSetup)
10233 // For same-domain requests, won't change header if already provided. 10234 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 10235 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 10236 } 10237 10238 // Set headers 10239 for ( i in headers ) { 10240 10241 // Support: IE<9 10242 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting 10243 // request header to a null-value. 10244 // 10245 // To keep consistent with other XHR implementations, cast the value 10246 // to string and ignore `undefined`. 10247 if ( headers[ i ] !== undefined ) { 10248 xhr.setRequestHeader( i, headers[ i ] + "" ); 10249 } 10250 } 10251 10252 // Do send the request 10253 // This may raise an exception which is actually 10254 // handled in jQuery.ajax (so no try/catch here) 10255 xhr.send( ( options.hasContent && options.data ) || null ); 10256 10257 // Listener 10258 callback = function( _, isAbort ) { 10259 var status, statusText, responses; 10260 10261 // Was never called and is aborted or complete 10262 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { 10263 10264 // Clean up 10265 delete xhrCallbacks[ id ]; 10266 callback = undefined; 10267 xhr.onreadystatechange = jQuery.noop; 10268 10269 // Abort manually if needed 10270 if ( isAbort ) { 10271 if ( xhr.readyState !== 4 ) { 10272 xhr.abort(); 10273 } 10274 } else { 10275 responses = {}; 10276 status = xhr.status; 10277 10278 // Support: IE<10 10279 // Accessing binary-data responseText throws an exception 10280 // (#11426) 10281 if ( typeof xhr.responseText === "string" ) { 10282 responses.text = xhr.responseText; 10283 } 10284 10285 // Firefox throws an exception when accessing 10286 // statusText for faulty cross-domain requests 10287 try { 10288 statusText = xhr.statusText; 10289 } catch ( e ) { 10290 10291 // We normalize with Webkit giving an empty statusText 10292 statusText = ""; 10293 } 10294 10295 // Filter status for non standard behaviors 10296 10297 // If the request is local and we have data: assume a success 10298 // (success with no data won't get notified, that's the best we 10299 // can do given current implementations) 10300 if ( !status && options.isLocal && !options.crossDomain ) { 10301 status = responses.text ? 200 : 404; 10302 10303 // IE - #1450: sometimes returns 1223 when it should be 204 10304 } else if ( status === 1223 ) { 10305 status = 204; 10306 } 10307 } 10308 } 10309 10310 // Call complete if needed 10311 if ( responses ) { 10312 complete( status, statusText, responses, xhr.getAllResponseHeaders() ); 10313 } 10314 }; 10315 10316 // Do send the request 10317 // `xhr.send` may raise an exception, but it will be 10318 // handled in jQuery.ajax (so no try/catch here) 10319 if ( !options.async ) { 10320 10321 // If we're in sync mode we fire the callback 10322 callback(); 10323 } else if ( xhr.readyState === 4 ) { 10324 10325 // (IE6 & IE7) if it's in cache and has been 10326 // retrieved directly we need to fire the callback 10327 window.setTimeout( callback ); 10328 } else { 10329 10330 // Register the callback, but delay it in case `xhr.send` throws 10331 // Add to the list of active xhr callbacks 10332 xhr.onreadystatechange = xhrCallbacks[ id ] = callback; 10333 } 10334 }, 10335 10336 abort: function() { 10337 if ( callback ) { 10338 callback( undefined, true ); 10339 } 10340 } 10341 }; 10342 } 10343 } ); 10344} 10345 10346// Functions to create xhrs 10347function createStandardXHR() { 10348 try { 10349 return new window.XMLHttpRequest(); 10350 } catch ( e ) {} 10351} 10352 10353function createActiveXHR() { 10354 try { 10355 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); 10356 } catch ( e ) {} 10357} 10358 10359 10360 10361 10362// Install script dataType 10363jQuery.ajaxSetup( { 10364 accepts: { 10365 script: "text/javascript, application/javascript, " + 10366 "application/ecmascript, application/x-ecmascript" 10367 }, 10368 contents: { 10369 script: /\b(?:java|ecma)script\b/ 10370 }, 10371 converters: { 10372 "text script": function( text ) { 10373 jQuery.globalEval( text ); 10374 return text; 10375 } 10376 } 10377} ); 10378 10379// Handle cache's special case and global 10380jQuery.ajaxPrefilter( "script", function( s ) { 10381 if ( s.cache === undefined ) { 10382 s.cache = false; 10383 } 10384 if ( s.crossDomain ) { 10385 s.type = "GET"; 10386 s.global = false;
10387 } 10388} ); 10389 10390// Bind script tag hack transport 10391jQuery.ajaxTransport( "script", function( s ) { 10392 10393 // This transport only deals with cross domain requests 10394 if ( s.crossDomain ) { 10395 10396 var script, 10397 head = document.head || jQuery( "head" )[ 0 ] || document.documentElement; 10398 10399 return { 10400 10401 send: function( _, callback ) { 10402 10403 script = document.createElement( "script" ); 10404 10405 script.async = true; 10406 10407 if ( s.scriptCharset ) { 10408 script.charset = s.scriptCharset; 10409 } 10410 10411 script.src = s.url; 10412 10413 // Attach handlers for all browsers 10414 script.onload = script.onreadystatechange = function( _, isAbort ) { 10415 10416 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { 10417 10418 // Handle memory leak in IE 10419 script.onload = script.onreadystatechange = null; 10420 10421 // Remove the script 10422 if ( script.parentNode ) { 10423 script.parentNode.removeChild( script ); 10424 } 10425 10426 // Dereference the script 10427 script = null; 10428 10429 // Callback if not abort 10430 if ( !isAbort ) { 10431 callback( 200, "success" ); 10432 } 10433 } 10434 }; 10435 10436 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending 10437 // Use native DOM manipulation to avoid our domManip AJAX trickery 10438 head.insertBefore( script, head.firstChild ); 10439 }, 10440 10441 abort: function() { 10442 if ( script ) { 10443 script.onload( undefined, true ); 10444 } 10445 } 10446 }; 10447 } 10448} ); 10449 10450 10451 10452 10453var oldCallbacks = [], 10454 rjsonp = /(=)\?(?=&|$)|\?\?/; 10455 10456// Default jsonp settings 10457jQuery.ajaxSetup( { 10458 jsonp: "callback", 10459 jsonpCallback: function() { 10460 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 10461 this[ callback ] = true; 10462 return callback; 10463 } 10464} ); 10465 10466// Detect, normalize options and install callbacks for jsonp requests 10467jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 10468 10469 var callbackName, overwritten, responseContainer, 10470 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 10471 "url" : 10472 typeof s.data === "string" && 10473 ( s.contentType || "" ) 10474 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 10475 rjsonp.test( s.data ) && "data" 10476 ); 10477 10478 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10479 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 10480 10481 // Get callback name, remembering preexisting value associated with it 10482 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? 10483 s.jsonpCallback() : 10484 s.jsonpCallback; 10485 10486 // Insert callback into url or form data 10487 if ( jsonProp ) { 10488 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 10489 } else if ( s.jsonp !== false ) { 10490 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 10491 } 10492 10493 // Use data converter to retrieve json after script execution 10494 s.converters[ "script json" ] = function() { 10495 if ( !responseContainer ) { 10496 jQuery.error( callbackName + " was not called" ); 10497 } 10498 return responseContainer[ 0 ]; 10499 }; 10500 10501 // force json dataType 10502 s.dataTypes[ 0 ] = "json"; 10503 10504 // Install callback 10505 overwritten = window[ callbackName ]; 10506 window[ callbackName ] = function() { 10507 responseContainer = arguments; 10508 }; 10509 10510 // Clean-up function (fires after converters) 10511 jqXHR.always( function() { 10512 10513 // If previous value didn't exist - remove it 10514 if ( overwritten === undefined ) { 10515 jQuery( window ).removeProp( callbackName ); 10516 10517 // Otherwise restore preexisting value 10518 } else { 10519 window[ callbackName ] = overwritten; 10520 } 10521 10522 // Save back as free 10523 if ( s[ callbackName ] ) { 10524 10525 // make sure that re-using the options doesn't screw things around 10526 s.jsonpCallback = originalSettings.jsonpCallback; 10527 10528 // save the callback name for future use 10529 oldCallbacks.push( callbackName ); 10530 } 10531 10532 // Call if it was a function and we have a response 10533 if ( responseContainer && jQuery.isFunction( overwritten ) ) { 10534 overwritten( responseContainer[ 0 ] ); 10535 } 10536 10537 responseContainer = overwritten = undefined; 10538 } ); 10539 10540 // Delegate to script 10541 return "script"; 10542 } 10543} ); 10544 10545 10546 10547 10548// data: string of html 10549// context (optional): If specified, the fragment will be created in this context, 10550// defaults to document 10551// keepScripts (optional): If true, will include scripts passed in the html string 10552jQuery.parseHTML = function( data, context, keepScripts ) { 10553 if ( !data || typeof data !== "string" ) { 10554 return null; 10555 } 10556 if ( typeof context === "boolean" ) { 10557 keepScripts = context; 10558 context = false;
10559 } 10560 context = context || document; 10561 10562 var parsed = rsingleTag.exec( data ), 10563 scripts = !keepScripts && []; 10564 10565 // Single tag 10566 if ( parsed ) { 10567 return [ context.createElement( parsed[ 1 ] ) ]; 10568 } 10569 10570 parsed = buildFragment( [ data ], context, scripts ); 10571 10572 if ( scripts && scripts.length ) { 10573 jQuery( scripts ).remove(); 10574 } 10575 10576 return jQuery.merge( [], parsed.childNodes ); 10577}; 10578 10579 10580// Keep a copy of the old load method 10581var _load = jQuery.fn.load; 10582 10583/** 10584 * Load a url into a page 10585 */ 10586jQuery.fn.load = function( url, params, callback ) { 10587 if ( typeof url !== "string" && _load ) { 10588 return _load.apply( this, arguments ); 10589 } 10590 10591 var selector, type, response, 10592 self = this, 10593 off = url.indexOf( " " ); 10594 10595 if ( off > -1 ) { 10596 selector = jQuery.trim( url.slice( off, url.length ) ); 10597 url = url.slice( 0, off ); 10598 } 10599 10600 // If it's a function 10601 if ( jQuery.isFunction( params ) ) { 10602 10603 // We assume that it's the callback 10604 callback = params; 10605 params = undefined; 10606 10607 // Otherwise, build a param string 10608 } else if ( params && typeof params === "object" ) { 10609 type = "POST"; 10610 } 10611 10612 // If we have elements to modify, make the request 10613 if ( self.length > 0 ) { 10614 jQuery.ajax( { 10615 url: url, 10616 10617 // If "type" variable is undefined, then "GET" method will be used. 10618 // Make value of this field explicit since 10619 // user can override it through ajaxSetup method 10620 type: type || "GET", 10621 dataType: "html", 10622 data: params 10623 } ).done( function( responseText ) { 10624 10625 // Save response for use in complete callback 10626 response = arguments; 10627 10628 self.html( selector ? 10629 10630 // If a selector was specified, locate the right elements in a dummy div 10631 // Exclude scripts to avoid IE 'Permission Denied' errors 10632 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 10633 10634 // Otherwise use the full result 10635 responseText ); 10636 10637 // If the request succeeds, this function gets "data", "status", "jqXHR" 10638 // but they are ignored because response was set above. 10639 // If it fails, this function gets "jqXHR", "status", "error" 10640 } ).always( callback && function( jqXHR, status ) { 10641 self.each( function() { 10642 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 10643 } ); 10644 } ); 10645 } 10646 10647 return this; 10648}; 10649 10650 10651 10652 10653// Attach a bunch of functions for handling common AJAX events 10654jQuery.each( [ 10655 "ajaxStart", 10656 "ajaxStop", 10657 "ajaxComplete", 10658 "ajaxError", 10659 "ajaxSuccess", 10660 "ajaxSend" 10661], function( i, type ) { 10662 jQuery.fn[ type ] = function( fn ) { 10663 return this.on( type, fn ); 10664 }; 10665} ); 10666 10667 10668 10669 10670jQuery.expr.filters.animated = function( elem ) { 10671 return jQuery.grep( jQuery.timers, function( fn ) { 10672 return elem === fn.elem; 10673 } ).length; 10674}; 10675 10676 10677 10678 10679 10680/** 10681 * Gets a window from an element 10682 */ 10683function getWindow( elem ) { 10684 return jQuery.isWindow( elem ) ? 10685 elem : 10686 elem.nodeType === 9 ? 10687 elem.defaultView || elem.parentWindow : 10688 false; 10689} 10690 10691jQuery.offset = { 10692 setOffset: function( elem, options, i ) { 10693 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 10694 position = jQuery.css( elem, "position" ), 10695 curElem = jQuery( elem ), 10696 props = {}; 10697 10698 // set position first, in-case top/left are set even on static elem 10699 if ( position === "static" ) { 10700 elem.style.position = "relative"; 10701 } 10702 10703 curOffset = curElem.offset(); 10704 curCSSTop = jQuery.css( elem, "top" ); 10705 curCSSLeft = jQuery.css( elem, "left" ); 10706 calculatePosition = ( position === "absolute" || position === "fixed" ) && 10707 jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1; 10708 10709 // need to be able to calculate position if either top or left 10710 // is auto and position is either absolute or fixed 10711 if ( calculatePosition ) { 10712 curPosition = curElem.position(); 10713 curTop = curPosition.top; 10714 curLeft = curPosition.left; 10715 } else { 10716 curTop = parseFloat( curCSSTop ) || 0; 10717 curLeft = parseFloat( curCSSLeft ) || 0; 10718 } 10719 10720 if ( jQuery.isFunction( options ) ) { 10721 10722 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10723 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 10724 } 10725 10726 if ( options.top != null ) { 10727 props.top = ( options.top - curOffset.top ) + curTop; 10728 } 10729 if ( options.left != null ) { 10730 props.left = ( options.left - curOffset.left ) + curLeft; 10731 } 10732 10733 if ( "using" in options ) { 10734 options.using.call( elem, props ); 10735 } else { 10736 curElem.css( props ); 10737 } 10738 } 10739}; 10740 10741jQuery.fn.extend( { 10742 offset: function( options ) { 10743 if ( arguments.length ) { 10744 return options === undefined ? 10745 this : 10746 this.each( function( i ) { 10747 jQuery.offset.setOffset( this, options, i ); 10748 } ); 10749 } 10750 10751 var docElem, win, 10752 box = { top: 0, left: 0 }, 10753 elem = this[ 0 ], 10754 doc = elem && elem.ownerDocument; 10755 10756 if ( !doc ) { 10757 return; 10758 } 10759 10760 docElem = doc.documentElement; 10761 10762 // Make sure it's not a disconnected DOM node 10763 if ( !jQuery.contains( docElem, elem ) ) { 10764 return box; 10765 } 10766 10767 // If we don't have gBCR, just use 0,0 rather than error 10768 // BlackBerry 5, iOS 3 (original iPhone) 10769 if ( typeof elem.getBoundingClientRect !== "undefined" ) { 10770 box = elem.getBoundingClientRect(); 10771 } 10772 win = getWindow( doc ); 10773 return { 10774 top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), 10775 left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) 10776 }; 10777 }, 10778 10779 position: function() { 10780 if ( !this[ 0 ] ) { 10781 return; 10782 } 10783 10784 var offsetParent, offset, 10785 parentOffset = { top: 0, left: 0 }, 10786 elem = this[ 0 ]; 10787 10788 // Fixed elements are offset from window (parentOffset = {top:0, left
10788: 0}, 10789 // because it is its only offset parent 10790 if ( jQuery.css( elem, "position" ) === "fixed" ) { 10791 10792 // we assume that getBoundingClientRect is available when computed position is fixed 10793 offset = elem.getBoundingClientRect(); 10794 } else { 10795 10796 // Get *real* offsetParent 10797 offsetParent = this.offsetParent(); 10798 10799 // Get correct offsets 10800 offset = this.offset(); 10801 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { 10802 parentOffset = offsetParent.offset(); 10803 } 10804 10805 // Add offsetParent borders 10806 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); 10807 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); 10808 } 10809 10810 // Subtract parent offsets and element margins 10811 // note: when an element has margin: auto the offsetLeft and marginLeft 10812 // are the same in Safari causing offset.left to incorrectly be 0 10813 return { 10814 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 10815 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 10816 }; 10817 }, 10818 10819 offsetParent: function() { 10820 return this.map( function() { 10821 var offsetParent = this.offsetParent; 10822 10823 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && 10824 jQuery.css( offsetParent, "position" ) === "static" ) ) { 10825 offsetParent = offsetParent.offsetParent; 10826 } 10827 return offsetParent || documentElement; 10828 } ); 10829 } 10830} ); 10831 10832// Create scrollLeft and scrollTop methods 10833jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 10834 var top = /Y/.test( prop ); 10835 10836 jQuery.fn[ method ] = function( val ) { 10837 return access( this, function( elem, method, val ) { 10838 var win = getWindow( elem ); 10839 10840 if ( val === undefined ) { 10841 return win ? ( prop in win ) ? win[ prop ] : 10842 win.document.documentElement[ method ] : 10843 elem[ method ]; 10844 } 10845 10846 if ( win ) { 10847 win.scrollTo( 10848 !top ? val : jQuery( win ).scrollLeft(), 10849 top ? val : jQuery( win ).scrollTop() 10850 ); 10851 10852 } else { 10853 elem[ method ] = val; 10854 } 10855 }, method, val, arguments.length, null ); 10856 }; 10857} ); 10858 10859// Support: Safari<7-8+, Chrome<37-44+ 10860// Add the top/left cssHooks using jQuery.fn.position 10861// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10862// getComputedStyle returns percent when specified for top/left/bottom/right 10863// rather than make the css module depend on the offset module, we just check for it here 10864jQuery.each( [ "top", "left" ], function( i, prop ) { 10865 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 10866 function( elem, computed ) { 10867 if ( computed ) { 10868 computed = curCSS( elem, prop ); 10869 10870 // if curCSS returns percentage, fallback to offset 10871 return rnumnonpx.test( computed ) ? 10872 jQuery( elem ).position()[ prop ] + "px" : 10873 computed; 10874 } 10875 } 10876 ); 10877} ); 10878 10879 10880// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10881jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 10882 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 10883 function( defaultExtra, funcName ) { 10884 10885 // margin is only for outerHeight, outerWidth 10886 jQuery.fn[ funcName ] = function( margin, value ) { 10887 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 10888 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 10889 10890 return access( this, function( elem, type, value ) { 10891 var doc; 10892 10893 if ( jQuery.isWindow( elem ) ) { 10894 10895 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there 10896 // isn't a whole lot we can do. See pull request at this URL for discussion: 10897 // https://github.com/jquery/jquery/pull/764 10898 return elem.document.documentElement[ "client" + name ]; 10899 } 10900 10901 // Get document width or height 10902 if ( elem.nodeType === 9 ) { 10903 doc = elem.documentElement; 10904 10905 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10906 // whichever is greatest 10907 // unfortunately, this causes bug #3838 in IE6/8 only, 10908 // but there is currently no good, small way to fix it. 10909 return Math.max( 10910 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 10911 elem.body[ "offset" + name ], doc[ "offset" + name ], 10912 doc[ "client" + name ] 10913 ); 10914 } 10915 10916 return value === undefined ? 10917 10918 // Get width or height on the element, requesting but not forcing parseFloat 10919 jQuery.css( elem, type, extra ) : 10920 10921 // Set width or height on the element 10922 jQuery.style( elem, type, value, extra ); 10923 }, type, chainable ? margin : undefined, chainable, null ); 10924 }; 10925 } ); 10926} ); 10927 10928 10929jQuery.fn.extend( { 10930 10931 bind: function( types, data, fn ) { 10932 return this.on( types, null, data, fn ); 10933 }, 10934 unbind: function( types, fn ) { 10935 return this.off( types, null, fn ); 10936 }, 10937 10938 delegate: function( selector, types, data, fn ) { 10939 return this.on( types, selector, data, fn ); 10940 }, 10941 undelegate: function( selector, types, fn ) { 10942 10943 // ( namespace ) or ( selector, types [, fn] ) 10944 return arguments.length === 1 ? 10945 this.off( selector, "**" ) : 10946 this.off( types, selector || "**", fn ); 10947 } 10948} ); 10949 10950// The number of elements contained in the matched element set 10951jQuery.fn.size = function() { 10952 return this.length; 10953}; 10954 10955jQuery.fn.andSelf = jQuery.fn.addBack; 10956 10957 10958 10959 10960// Register as a named AMD module, since jQuery can be concatenated with other 10961// files that may use define, but not via a proper concatenation script that 10962// understands anonymous AMD modules. A named AMD is safest and most robust 10963// way to register. Lowercase jquery is used because AMD module names are 10964// derived from file names, and jQuery is normally delivered in a lowercase 10965// file name. Do this after creating the global so that if an AMD module wants 10966// to call noConflict to hide this version of jQuery, it will work. 10967 10968// Note that for maximum portability, libraries that are not jQuery should 10969// declare themselves as anonymous modules, and avoid setting a global if an 10970// AMD loader is present. jQuery is a special case. For more information, see
10971// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10972 10973if ( typeof define === "function" && define.amd ) { 10974 define( "jquery", [], function() { 10975 return jQuery; 10976 } ); 10977} 10978 10979 10980 10981var 10982 10983 // Map over jQuery in case of overwrite 10984 _jQuery = window.jQuery, 10985 10986 // Map over the $ in case of overwrite 10987 _$ = window.$; 10988 10989jQuery.noConflict = function( deep ) { 10990 if ( window.$ === jQuery ) { 10991 window.$ = _$; 10992 } 10993 10994 if ( deep && window.jQuery === jQuery ) { 10995 window.jQuery = _jQuery; 10996 } 10997 10998 return jQuery; 10999}; 11000 11001// Expose jQuery and $ identifiers, even in 11002// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 11003// and CommonJS for browser emulators (#13566) 11004if ( !noGlobal ) { 11005 window.jQuery = window.$ = jQuery; 11006} 11007 11008return jQuery; 11009})); 11010( function( factory ) { 11011 "use strict"; 11012 11013 if ( typeof define === "function" && define.amd ) { 11014 11015 // AMD. Register as an anonymous module. 11016 define( [ "jquery" ], factory ); 11017 } else { 11018 11019 // Browser globals 11020 factory( jQuery ); 11021 } 11022} )( function( $ ) { 11023"use strict"; 11024 11025$.ui = $.ui || {}; 11026 11027return $.ui.version = "1.13.0"; 11028 11029} ); 11030 11031 11032/*! 11033 * jQuery UI :data 1.13.0 11034 * http://jqueryui.com 11035 * 11036 * Copyright jQuery Foundation and other contributors 11037 * Released under the MIT license. 11038 * http://jquery.org/license 11039 */ 11040 11041//>>label: :data Selector 11042//>>group: Core 11043//>>description: Selects elements which have data stored under the specified key. 11044//>>docs: http://api.jqueryui.com/data-selector/ 11045 11046( function( factory ) { 11047 "use strict"; 11048 11049 if ( typeof define === "function" && define.amd ) { 11050 11051 // AMD. Register as an anonymous module. 11052 define( [ "jquery", "./version" ], factory ); 11053 } else { 11054 11055 // Browser globals 11056 factory( jQuery ); 11057 } 11058} )( function( $ ) { 11059"use strict"; 11060 11061return $.extend( $.expr.pseudos, { 11062 data: $.expr.createPseudo ? 11063 $.expr.createPseudo( function( dataName ) { 11064 return function( elem ) { 11065 return !!$.data( elem, dataName ); 11066 }; 11067 } ) : 11068 11069 // Support: jQuery <1.8 11070 function( elem, i, match ) { 11071 return !!$.data( elem, match[ 3 ] ); 11072 } 11073} ); 11074} ); 11075 11076 11077/*! 11078 * jQuery UI Disable Selection 1.13.0 11079 * http://jqueryui.com 11080 * 11081 * Copyright jQuery Foundation and other contributors 11082 * Released under the MIT license. 11083 * http://jquery.org/license 11084 */ 11085 11086//>>label: disableSelection 11087//>>group: Core 11088//>>description: Disable selection of text content within the set of matched elements. 11089//>>docs: http://api.jqueryui.com/disableSelection/ 11090 11091// This file is deprecated 11092( function( factory ) { 11093 "use strict"; 11094 11095 if ( typeof define === "function" && define.amd ) { 11096 11097 // AMD. Register as an anonymous module. 11098 define( [ "jquery", "./version" ], factory ); 11099 } else { 11100 11101 // Browser globals 11102 factory( jQuery ); 11103 } 11104} )( function( $ ) { 11105"use strict"; 11106 11107return $.fn.extend( { 11108 disableSelection: ( function() { 11109 var eventType = "onselectstart" in document.createElement( "div" ) ? 11110 "selectstart" : 11111 "mousedown"; 11112 11113 return function() { 11114 return this.on( eventType + ".ui-disableSelection", function( event ) { 11115 event.preventDefault(); 11116 } ); 11117 }; 11118 } )(), 11119 11120 enableSelection: function() { 11121 return this.off( ".ui-disableSelection" ); 11122 } 11123} ); 11124 11125} ); 11126 11127 11128/*! 11129 * jQuery UI Focusable 1.13.0 11130 * http://jqueryui.com 11131 * 11132 * Copyright jQuery Foundation and other contributors 11133 * Released under the MIT license. 11134 * http://jquery.org/license 11135 */ 11136 11137//>>label: :focusable Selector 11138//>>group: Core 11139//>>description: Selects elements which can be focused. 11140//>>docs: http://api.jqueryui.com/focusable-selector/ 11141 11142( function( factory ) { 11143 "use strict"; 11144 11145 if ( typeof define === "function" && define.amd ) { 11146 11147 // AMD. Register as an anonymous module. 11148 define( [ "jquery", "./version" ], factory ); 11149 } else { 11150 11151 // Browser globals 11152 factory( jQuery ); 11153 } 11154} )( function( $ ) { 11155"use strict"; 11156 11157// Selectors 11158$.ui.focusable = function( element, hasTabindex ) { 11159 var map, mapName, img, focusableIfVisible, fieldset, 11160 nodeName = element.nodeName.toLowerCase(); 11161 11162 if ( "area" === nodeName ) { 11163 map = element.parentNode; 11164 mapName = map.name; 11165 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 11166 return false; 11167 } 11168 img = $( "img[usemap='#" + mapName + "']" ); 11169 return img.length > 0 && img.is( ":visible" ); 11170 } 11171 11172 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 11173 focusableIfVisible = !element.disabled; 11174
11175 if ( focusableIfVisible ) { 11176 11177 // Form controls within a disabled fieldset are disabled. 11178 // However, controls within the fieldset's legend do not get disabled. 11179 // Since controls generally aren't placed inside legends, we skip 11180 // this portion of the check. 11181 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 11182 if ( fieldset ) { 11183 focusableIfVisible = !fieldset.disabled; 11184 } 11185 } 11186 } else if ( "a" === nodeName ) { 11187 focusableIfVisible = element.href || hasTabindex; 11188 } else { 11189 focusableIfVisible = hasTabindex; 11190 } 11191 11192 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 11193}; 11194 11195// Support: IE 8 only 11196// IE 8 doesn't resolve inherit to visible/hidden for computed values 11197function visible( element ) { 11198 var visibility = element.css( "visibility" ); 11199 while ( visibility === "inherit" ) { 11200 element = element.parent(); 11201 visibility = element.css( "visibility" ); 11202 } 11203 return visibility === "visible"; 11204} 11205 11206$.extend( $.expr.pseudos, { 11207 focusable: function( element ) { 11208 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 11209 } 11210} ); 11211 11212return $.ui.focusable; 11213 11214} ); 11215 11216( function( factory ) { 11217 "use strict"; 11218 11219 if ( typeof define === "function" && define.amd ) { 11220 11221 // AMD. Register as an anonymous module. 11222 define( [ "jquery", "./version" ], factory ); 11223 } else { 11224 11225 // Browser globals 11226 factory( jQuery ); 11227 } 11228} )( function( $ ) { 11229"use strict"; 11230 11231// Support: IE8 Only 11232// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 11233// with a string, so we need to find the proper form. 11234return $.fn._form = function() { 11235 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 11236}; 11237 11238} ); 11239 11240( function( factory ) { 11241 "use strict"; 11242 11243 if ( typeof define === "function" && define.amd ) { 11244 11245 // AMD. Register as an anonymous module. 11246 define( [ "jquery", "./version" ], factory ); 11247 } else { 11248 11249 // Browser globals 11250 factory( jQuery ); 11251 } 11252} )( function( $ ) { 11253"use strict"; 11254 11255// This file is deprecated 11256return $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 11257} ); 11258 11259 11260/*! 11261 * jQuery UI Keycode 1.13.0 11262 * http://jqueryui.com 11263 * 11264 * Copyright jQuery Foundation and other contributors 11265 * Released under the MIT license. 11266 * http://jquery.org/license 11267 */ 11268 11269//>>label: Keycode 11270//>>group: Core 11271//>>description: Provide keycodes as keynames 11272//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 11273 11274( function( factory ) { 11275 "use strict"; 11276 11277 if ( typeof define === "function" && define.amd ) { 11278 11279 // AMD. Register as an anonymous module. 11280 define( [ "jquery", "./version" ], factory ); 11281 } else { 11282 11283 // Browser globals 11284 factory( jQuery ); 11285 } 11286} )( function( $ ) { 11287"use strict"; 11288 11289return $.ui.keyCode = { 11290 BACKSPACE: 8, 11291 COMMA: 188, 11292 DELETE: 46, 11293 DOWN: 40, 11294 END: 35, 11295 ENTER: 13, 11296 ESCAPE: 27, 11297 HOME: 36, 11298 LEFT: 37, 11299 PAGE_DOWN: 34, 11300 PAGE_UP: 33, 11301 PERIOD: 190, 11302 RIGHT: 39, 11303 SPACE: 32, 11304 TAB: 9, 11305 UP: 38 11306}; 11307 11308} ); 11309 11310 11311/*! 11312 * jQuery UI Labels 1.13.0 11313 * http://jqueryui.com 11314 * 11315 * Copyright jQuery Foundation and other contributors 11316 * Released under the MIT license. 11317 * http://jquery.org/license 11318 */ 11319 11320//>>label: labels 11321//>>group: Core 11322//>>description: Find all the labels associated with a given input 11323//>>docs: http://api.jqueryui.com/labels/ 11324 11325( function( factory ) { 11326 "use strict"; 11327 11328 if ( typeof define === "function" && define.amd ) { 11329 11330 // AMD. Register as an anonymous module. 11331 define( [ "jquery", "./version" ], factory ); 11332 } else { 11333 11334 // Browser globals 11335 factory( jQuery ); 11336 } 11337} )( function( $ ) { 11338"use strict"; 11339 11340return $.fn.labels = function() { 11341 var ancestor, selector, id, labels, ancestors; 11342 11343 if ( !this.length ) { 11344 return this.pushStack( [] ); 11345 } 11346 11347 // Check control.labels first 11348 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 11349 return this.pushStack( this[ 0 ].labels ); 11350 } 11351 11352 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 11353 // Above browsers do not support control.labels. Everything below is to support them 11354 // as well as document fragments. control.labels does not work on document fragments 11355 labels = this.eq( 0 ).parents( "label" ); 11356 11357 // Look for the label based on the id 11358 id = this.attr( "id" ); 11359 if ( id ) { 11360 11361 // We don't search against the document in case the element 11362 // is disconnected from the DOM
vendor: 6,202 bytes, lines 11363-11628
11363 ancestor = this.eq( 0 ).parents().last(); 11364 11365 // Get a full set of top level ancestors 11366 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 11367 11368 // Create a selector for the label based on the id 11369 selector = "label[for='" + $.escapeSelector( id ) + "']"; 11370 11371 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 11372 11373 } 11374 11375 // Return whatever we have found for labels 11376 return this.pushStack( labels ); 11377}; 11378 11379} ); 11380 11381 11382/*! 11383 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.0 11384 * http://jqueryui.com 11385 * 11386 * Copyright jQuery Foundation and other contributors 11387 * Released under the MIT license. 11388 * http://jquery.org/license 11389 * 11390 */ 11391 11392//>>label: jQuery 1.8+ Support 11393//>>group: Core 11394//>>description: Support version 1.8.x and newer of jQuery core 11395 11396( function( factory ) { 11397"use strict"; 11398 11399 if ( typeof define === "function" && define.amd ) { 11400 11401 // AMD. Register as an anonymous module. 11402 define( [ "jquery", "./version" ], factory ); 11403 } else { 11404 11405 // Browser globals 11406 factory( jQuery ); 11407 } 11408} )( function( $ ) { 11409"use strict"; 11410 11411// Support: jQuery 1.9.x or older 11412// $.expr[ ":" ] is deprecated. 11413if ( !$.expr.pseudos ) { 11414 $.expr.pseudos = $.expr[ ":" ]; 11415} 11416 11417// Support: jQuery 1.11.x or older 11418// $.unique has been renamed to $.uniqueSort 11419if ( !$.uniqueSort ) { 11420 $.uniqueSort = $.unique; 11421} 11422 11423// Support: jQuery 2.2.x or older. 11424// This method has been defined in jQuery 3.0.0. 11425// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 11426if ( !$.escapeSelector ) { 11427 11428 // CSS string/identifier serialization 11429 // https://drafts.csswg.org/cssom/#common-serializing-idioms 11430 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 11431 11432 var fcssescape = function( ch, asCodePoint ) { 11433 if ( asCodePoint ) { 11434 11435 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 11436 if ( ch === "\0" ) { 11437 return "\uFFFD"; 11438 } 11439 11440 // Control characters and (dependent upon position) numbers get escaped as code points 11441 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 11442 } 11443 11444 // Other potentially-special ASCII characters get backslash-escaped 11445 return "\\" + ch; 11446 }; 11447 11448 $.escapeSelector = function( sel ) { 11449 return ( sel + "" ).replace( rcssescape, fcssescape ); 11450 }; 11451} 11452 11453// Support: jQuery 3.4.x or older 11454// These methods have been defined in jQuery 3.5.0. 11455if ( !$.fn.even || !$.fn.odd ) { 11456 $.fn.extend( { 11457 even: function() { 11458 return this.filter( function( i ) { 11459 return i % 2 === 0; 11460 } ); 11461 }, 11462 odd: function() { 11463 return this.filter( function( i ) { 11464 return i % 2 === 1; 11465 } ); 11466 } 11467 } ); 11468} 11469 11470} ); 11471 11472( function( factory ) { 11473 "use strict"; 11474 11475 if ( typeof define === "function" && define.amd ) { 11476 11477 // AMD. Register as an anonymous module. 11478 define( [ "jquery", "./version" ], factory ); 11479 } else { 11480 11481 // Browser globals 11482 factory( jQuery ); 11483 } 11484} )( function( $ ) { 11485"use strict"; 11486 11487// $.ui.plugin is deprecated. Use $.widget() extensions instead. 11488return $.ui.plugin = { 11489 add: function( module, option, set ) { 11490 var i, 11491 proto = $.ui[ module ].prototype; 11492 for ( i in set ) { 11493 proto.plugins[ i ] = proto.plugins[ i ] || []; 11494 proto.plugins[ i ].push( [ option, set[ i ] ] ); 11495 } 11496 }, 11497 call: function( instance, name, args, allowDisconnected ) { 11498 var i, 11499 set = instance.plugins[ name ]; 11500 11501 if ( !set ) { 11502 return; 11503 } 11504 11505 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 11506 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 11507 return; 11508 } 11509 11510 for ( i = 0; i < set.length; i++ ) { 11511 if ( instance.options[ set[ i ][ 0 ] ] ) { 11512 set[ i ][ 1 ].apply( instance.element, args ); 11513 } 11514 } 11515 } 11516}; 11517 11518} ); 11519 11520( function( factory ) { 11521 "use strict"; 11522 11523 if ( typeof define === "function" && define.amd ) { 11524 11525 // AMD. Register as an anonymous module. 11526 define( [ "jquery", "./version" ], factory ); 11527 } else { 11528 11529 // Browser globals 11530 factory( jQuery ); 11531 } 11532} )( function( $ ) { 11533"use strict"; 11534 11535return $.ui.safeActiveElement = function( document ) { 11536 var activeElement; 11537 11538 // Support: IE 9 only 11539 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 11540 try { 11541 activeElement = document.activeElement; 11542 } catch ( error ) { 11543 activeElement = document.body; 11544 } 11545 11546 // Support: IE 9 - 11 only 11547 // IE may return null instead of an element 11548 // Interestingly, this only seems to occur when NOT in an iframe 11549 if ( !activeElement ) { 11550 activeElement = document.body; 11551 } 11552 11553 // Support: IE 11 only 11554 // IE11 returns a seemingly empty object in some cases when accessing 11555 // document.activeElement from an <iframe> 11556 if ( !activeElement.nodeName ) { 11557 activeElement = document.body; 11558 } 11559 11560 return activeElement; 11561}; 11562 11563} ); 11564 11565( function( factory ) { 11566 "use strict"; 11567 11568 if ( typeof define === "function" && define.amd ) { 11569 11570 // AMD. Register as an anonymous module. 11571 define( [ "jquery", "./version" ], factory ); 11572 } else { 11573 11574 // Browser globals 11575 factory( jQuery ); 11576 } 11577} )( function( $ ) { 11578"use strict"; 11579 11580return $.ui.safeBlur = function( element ) { 11581 11582 // Support: IE9 - 10 only 11583 // If the <body> is blurred, IE will switch windows, see #9420 11584 if ( element && element.nodeName.toLowerCase() !== "body" ) { 11585 $( element ).trigger( "blur" ); 11586 } 11587}; 11588 11589} ); 11590 11591 11592/*! 11593 * jQuery UI Scroll Parent 1.13.0 11594 * http://jqueryui.com 11595 * 11596 * Copyright jQuery Foundation and other contributors 11597 * Released under the MIT license. 11598 * http://jquery.org/license 11599 */ 11600 11601//>>label: scrollParent 11602//>>group: Core 11603//>>description: Get the closest ancestor element that is scrollable. 11604//>>docs: http://api.jqueryui.com/scrollParent/ 11605 11606( function( factory ) { 11607 "use strict"; 11608 11609 if ( typeof define === "function" && define.amd ) { 11610 11611 // AMD. Register as an anonymous module. 11612 define( [ "jquery", "./version" ], factory ); 11613 } else { 11614 11615 // Browser globals 11616 factory( jQuery ); 11617 } 11618} )( function( $ ) { 11619"use strict"; 11620 11621return $.fn.scrollParent = function( includeHidden ) { 11622 var position = this.css( "position" ), 11623 excludeStaticParent = position === "absolute", 11624 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 11625 scrollParent = this.parents().filter( function() { 11626 var parent = $( this ); 11627 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 11628 return false;
11629 } 11630 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 11631 parent.css( "overflow-x" ) ); 11632 } ).eq( 0 ); 11633 11634 return position === "fixed" || !scrollParent.length ? 11635 $( this[ 0 ].ownerDocument || document ) : 11636 scrollParent; 11637}; 11638 11639} ); 11640 11641 11642 11643/*! 11644 * jQuery UI Tabbable 1.13.0 11645 * http://jqueryui.com 11646 * 11647 * Copyright jQuery Foundation and other contributors 11648 * Released under the MIT license. 11649 * http://jquery.org/license 11650 */ 11651 11652//>>label: :tabbable Selector 11653//>>group: Core 11654//>>description: Selects elements which can be tabbed to. 11655//>>docs: http://api.jqueryui.com/tabbable-selector/ 11656 11657( function( factory ) { 11658 "use strict"; 11659 11660 if ( typeof define === "function" && define.amd ) { 11661 11662 // AMD. Register as an anonymous module. 11663 define( [ "jquery", "./version", "./focusable" ], factory ); 11664 } else { 11665 11666 // Browser globals 11667 factory( jQuery ); 11668 } 11669} )( function( $ ) { 11670"use strict"; 11671 11672return $.extend( $.expr.pseudos, { 11673 tabbable: function( element ) { 11674 var tabIndex = $.attr( element, "tabindex" ), 11675 hasTabindex = tabIndex != null; 11676 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 11677 } 11678} ); 11679 11680} ); 11681 11682 11683/*! 11684 * jQuery UI Unique ID 1.13.0 11685 * http://jqueryui.com 11686 * 11687 * Copyright jQuery Foundation and other contributors 11688 * Released under the MIT license. 11689 * http://jquery.org/license 11690 */ 11691 11692//>>label: uniqueId 11693//>>group: Core 11694//>>description: Functions to generate and remove uniqueId's 11695//>>docs: http://api.jqueryui.com/uniqueId/ 11696 11697( function( factory ) { 11698 "use strict"; 11699 11700 if ( typeof define === "function" && define.amd ) { 11701 11702 // AMD. Register as an anonymous module. 11703 define( [ "jquery", "./version" ], factory ); 11704 } else { 11705 11706 // Browser globals 11707 factory( jQuery ); 11708 } 11709} )( function( $ ) { 11710"use strict"; 11711 11712return $.fn.extend( { 11713 uniqueId: ( function() { 11714 var uuid = 0; 11715 11716 return function() { 11717 return this.each( function() { 11718 if ( !this.id ) { 11719 this.id = "ui-id-" + ( ++uuid ); 11720 } 11721 } ); 11722 }; 11723 } )(), 11724 11725 removeUniqueId: function() { 11726 return this.each( function() { 11727 if ( /^ui-id-\d+$/.test( this.id ) ) { 11728 $( this ).removeAttr( "id" ); 11729 } 11730 } ); 11731 } 11732} ); 11733 11734} ); 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751( function( factory ) { 11752 "use strict"; 11753 11754 if ( typeof define === "function" && define.amd ) { 11755 11756 // AMD. Register as an anonymous module. 11757 define( [ "jquery", "./version" ], factory ); 11758 } else { 11759 11760 // Browser globals 11761 factory( jQuery ); 11762 } 11763} )( function( $ ) { 11764 "use strict"; 11765 11766// Create a local jQuery because jQuery Color relies on it and the 11767// global may not exist with AMD and a custom build (#10199). 11768// This module is a noop if used as a regular AMD module. 11769// eslint-disable-next-line no-unused-vars 11770var jQuery = $; 11771 11772} ); 11773/*! 11774 * jQuery Color Animations v2.2.0 11775 * https://github.com/jquery/jquery-color 11776 * 11777 * Copyright OpenJS Foundation and other contributors 11778 * Released under the MIT license. 11779 * http://jquery.org/license 11780 * 11781 * Date: Sun May 10 09:02:36 2020 +0200 11782 */ 11783 11784 11785( function( root, factory ) { 11786 if ( typeof define === "function" && define.amd ) { 11787 11788 // AMD. Register as an anonymous module. 11789 define( [ "jquery" ], factory ); 11790 } else if ( typeof exports === "object" ) { 11791 module.exports = factory( require( "jquery" ) ); 11792 } else { 11793 factory( root.jQuery ); 11794 } 11795} )( this, function( jQuery, undefined ) {
vendor: 16,825 bytes, lines 11795-12494
11795 11796 11797 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 11798 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 11799 11800 class2type = {}, 11801 toString = class2type.toString, 11802 11803 // plusequals test for += 100 -= 100 11804 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 11805 11806 // a set of RE's that can match strings and generate color tuples. 11807 stringParsers = [ { 11808 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 11809 parse: function( execResult ) { 11810 return [ 11811 execResult[ 1 ], 11812 execResult[ 2 ], 11813 execResult[ 3 ], 11814 execResult[ 4 ] 11815 ]; 11816 } 11817 }, { 11818 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 11819 parse: function( execResult ) { 11820 return [ 11821 execResult[ 1 ] * 2.55, 11822 execResult[ 2 ] * 2.55, 11823 execResult[ 3 ] * 2.55, 11824 execResult[ 4 ] 11825 ]; 11826 } 11827 }, { 11828 11829 // this regex ignores A-F because it's compared against an already lowercased string 11830 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 11831 parse: function( execResult ) { 11832 return [ 11833 parseInt( execResult[ 1 ], 16 ), 11834 parseInt( execResult[ 2 ], 16 ), 11835 parseInt( execResult[ 3 ], 16 ), 11836 execResult[ 4 ] ? 11837 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 11838 1 11839 ]; 11840 } 11841 }, { 11842 11843 // this regex ignores A-F because it's compared against an already lowercased string 11844 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 11845 parse: function( execResult ) { 11846 return [ 11847 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 11848 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 11849 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 11850 execResult[ 4 ] ? 11851 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 11852 .toFixed( 2 ) : 11853 1 11854 ]; 11855 } 11856 }, { 11857 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 11858 space: "hsla", 11859 parse: function( execResult ) { 11860 return [ 11861 execResult[ 1 ], 11862 execResult[ 2 ] / 100, 11863 execResult[ 3 ] / 100, 11864 execResult[ 4 ] 11865 ]; 11866 } 11867 } ], 11868 11869 // jQuery.Color( ) 11870 color = jQuery.Color = function( color, green, blue, alpha ) { 11871 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 11872 }, 11873 spaces = { 11874 rgba: { 11875 props: { 11876 red: { 11877 idx: 0, 11878 type: "byte" 11879 }, 11880 green: { 11881 idx: 1, 11882 type: "byte" 11883 }, 11884 blue: { 11885 idx: 2, 11886 type: "byte" 11887 } 11888 } 11889 }, 11890 11891 hsla: { 11892 props: { 11893 hue: { 11894 idx: 0, 11895 type: "degrees" 11896 }, 11897 saturation: { 11898 idx: 1, 11899 type: "percent" 11900 }, 11901 lightness: { 11902 idx: 2, 11903 type: "percent" 11904 } 11905 } 11906 } 11907 }, 11908 propTypes = { 11909 "byte": { 11910 floor: true, 11911 max: 255 11912 }, 11913 "percent": { 11914 max: 1 11915 }, 11916 "degrees": { 11917 mod: 360, 11918 floor: true 11919 } 11920 }, 11921 support = color.support = {}, 11922 11923 // element for support tests 11924 supportElem = jQuery( "<p>" )[ 0 ], 11925 11926 // colors = jQuery.Color.names 11927 colors, 11928 11929 // local aliases of functions called often 11930 each = jQuery.each; 11931 11932// determine rgba support immediately 11933supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 11934support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 11935 11936// define cache name and alpha properties 11937// for rgba and hsla spaces 11938each( spaces, function( spaceName, space ) { 11939 space.cache = "_" + spaceName; 11940 space.props.alpha = { 11941 idx: 3, 11942 type: "percent", 11943 def: 1 11944 }; 11945} ); 11946 11947// Populate the class2type map 11948jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 11949 function( _i, name ) { 11950 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 11951 } ); 11952 11953function getType( obj ) { 11954 if ( obj == null ) { 11955 return obj + ""; 11956 } 11957 11958 return typeof obj === "object" ? 11959 class2type[ toString.call( obj ) ] || "object" : 11960 typeof obj; 11961} 11962 11963function clamp( value, prop, allowEmpty ) { 11964 var type = propTypes[ prop.type ] || {}; 11965 11966 if ( value == null ) { 11967 return ( allowEmpty || !prop.def ) ? null : prop.def; 11968 } 11969 11970 // ~~ is an short way of doing floor for positive numbers 11971 value = type.floor ? ~~value : parseFloat( value ); 11972 11973 // IE will pass in empty strings as value for alpha, 11974 // which will hit this case 11975 if ( isNaN( value ) ) { 11976 return prop.def; 11977 } 11978 11979 if ( type.mod ) { 11980 11981 // we add mod before modding to make sure that negatives values 11982 // get converted properly: -10 -> 350 11983 return ( value + type.mod ) % type.mod; 11984 } 11985 11986 // for now all property types without mod have min and max 11987 return Math.min( type.max, Math.max( 0, value ) ); 11988} 11989 11990function stringParse( string ) { 11991 var inst = color(), 11992 rgba = inst._rgba = []; 11993 11994 string = string.toLowerCase(); 11995 11996 each( stringParsers, function( _i, parser ) { 11997 var parsed, 11998 match = parser.re.exec( string ), 11999 values = match && parser.parse( match ), 12000 spaceName = parser.space || "rgba"; 12001 12002 if ( values ) { 12003 parsed = inst[ spaceName ]( values ); 12004 12005 // if this was an rgba parse the assignment might happen twice 12006 // oh well.... 12007 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12008 rgba = inst._rgba = parsed._rgba; 12009 12010 // exit each( stringParsers ) here because we matched 12011 return false; 12012 } 12013 } ); 12014 12015 // Found a stringParser that handled it 12016 if ( rgba.length ) { 12017 12018 // if this came from a parsed string, force "transparent" when alpha is 0 12019 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12020 if ( rgba.join() === "0,0,0,0" ) { 12021 jQuery.extend( rgba, colors.transparent ); 12022 } 12023 return inst; 12024 } 12025 12026 // named colors 12027 return colors[ string ]; 12028} 12029 12030color.fn = jQuery.extend( color.prototype, { 12031 parse: function( red, green, blue, alpha ) { 12032 if ( red === undefined ) { 12033 this._rgba = [ null, null, null, null ]; 12034 return this; 12035 } 12036 if ( red.jquery || red.nodeType ) { 12037 red = jQuery( red ).css( green ); 12038 green = undefined; 12039 } 12040 12041 var inst = this, 12042 type = getType( red ), 12043 rgba = this._rgba = []; 12044 12045 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12046 if ( green !== undefined ) { 12047 red = [ red, green, blue, alpha ]; 12048 type = "array"; 12049 } 12050 12051 if ( type === "string" ) { 12052 return this.parse( stringParse( red ) || colors._default ); 12053 } 12054 12055 if ( type === "array" ) { 12056 each( spaces.rgba.props, function( _key, prop ) { 12057 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 12058 } ); 12059 return this; 12060 } 12061 12062 if ( type === "object" ) { 12063 if ( red instanceof color ) { 12064 each( spaces, function( _spaceName, space ) { 12065 if ( red[ space.cache ] ) { 12066 inst[ space.cache ] = red[ space.cache ].slice(); 12067 } 12068 } ); 12069 } else { 12070 each( spaces, function( _spaceName, space ) { 12071 var cache = space.cache; 12072 each( space.props, function( key, prop ) { 12073 12074 // if the cache doesn't exist, and we know how to convert 12075 if ( !inst[ cache ] && space.to ) { 12076 12077 // if the value was null, we don't need to copy it 12078 // if the key was alpha, we don't need to copy it either 12079 if ( key === "alpha" || red[ key ] == null ) { 12080 return; 12081 } 12082 inst[ cache ] = space.to( inst._rgba ); 12083 } 12084 12085 // this is the only case where we allow nulls for ALL properties. 12086 // call clamp with alwaysAllowEmpty 12087 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 12088 } ); 12089 12090 // everything defined but alpha? 12091 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 12092 12093 // use the default of 1 12094 if ( inst[ cache ][ 3 ] == null ) { 12095 inst[ cache ][ 3 ] = 1; 12096 } 12097 12098 if ( space.from ) { 12099 inst._rgba = space.from( inst[ cache ] ); 12100 } 12101 } 12102 } ); 12103 } 12104 return this; 12105 } 12106 }, 12107 is: function( compare ) { 12108 var is = color( compare ), 12109 same = true, 12110 inst = this; 12111 12112 each( spaces, function( _, space ) { 12113 var localCache, 12114 isCache = is[ space.cache ]; 12115 if ( isCache ) { 12116 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 12117 each( space.props, function( _, prop ) { 12118 if ( isCache[ prop.idx ] != null ) { 12119 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 12120 return same; 12121 } 12122 } ); 12123 } 12124 return same; 12125 } ); 12126 return same; 12127 }, 12128 _space: function() { 12129 var used = [], 12130 inst = this; 12131 each( spaces, function( spaceName, space ) { 12132 if ( inst[ space.cache ] ) { 12133 used.push( spaceName ); 12134 } 12135 } ); 12136 return used.pop(); 12137 }, 12138 transition: function( other, distance ) { 12139 var end = color( other ), 12140 spaceName = end._space(), 12141 space = spaces[ spaceName ], 12142 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 12143 start = startColor[ space.cache ] || space.to( startColor._rgba ), 12144 result = start.slice(); 12145 12146 end = end[ space.cache ]; 12147 each( space.props, function( _key, prop ) { 12148 var index = prop.idx, 12149 startValue = start[ index ], 12150 endValue = end[ index ], 12151 type = propTypes[ prop.type ] || {}; 12152 12153 // if null, don't override start value 12154 if ( endValue === null ) { 12155 return; 12156 } 12157 12158 // if null - use end 12159 if ( startValue === null ) { 12160 result[ index ] = endValue; 12161 } else { 12162 if ( type.mod ) { 12163 if ( endValue - startValue > type.mod / 2 ) { 12164 startValue += type.mod; 12165 } else if ( startValue - endValue > type.mod / 2 ) { 12166 startValue -= type.mod; 12167 } 12168 } 12169 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 12170 } 12171 } ); 12172 return this[ spaceName ]( result ); 12173 }, 12174 blend: function( opaque ) { 12175 12176 // if we are already opaque - return ourself 12177 if ( this._rgba[ 3 ] === 1 ) { 12178 return this; 12179 } 12180 12181 var rgb = this._rgba.slice(), 12182 a = rgb.pop(), 12183 blend = color( opaque )._rgba; 12184 12185 return color( jQuery.map( rgb, function( v, i ) { 12186 return ( 1 - a ) * blend[ i ] + a * v; 12187 } ) ); 12188 }, 12189 toRgbaString: function() { 12190 var prefix = "rgba(", 12191 rgba = jQuery.map( this._rgba, function( v, i ) { 12192 if ( v != null ) { 12193 return v; 12194 } 12195 return i > 2 ? 1 : 0; 12196 } ); 12197 12198 if ( rgba[ 3 ] === 1 ) { 12199 rgba.pop(); 12200 prefix = "rgb("; 12201 } 12202 12203 return prefix + rgba.join() + ")"; 12204 }, 12205 toHslaString: function() { 12206 var prefix = "hsla(", 12207 hsla = jQuery.map( this.hsla(), function( v, i ) { 12208 if ( v == null ) { 12209 v = i > 2 ? 1 : 0; 12210 } 12211 12212 // catch 1 and 2 12213 if ( i && i < 3 ) { 12214 v = Math.round( v * 100 ) + "%"; 12215 } 12216 return v; 12217 } ); 12218 12219 if ( hsla[ 3 ] === 1 ) { 12220 hsla.pop(); 12221 prefix = "hsl("; 12222 } 12223 return prefix + hsla.join() + ")"; 12224 }, 12225 toHexString: function( includeAlpha ) { 12226 var rgba = this._rgba.slice(), 12227 alpha = rgba.pop(); 12228 12229 if ( includeAlpha ) { 12230 rgba.push( ~~( alpha * 255 ) ); 12231 } 12232 12233 return "#" + jQuery.map( rgba, function( v ) { 12234 12235 // default to 0 when nulls exist 12236 v = ( v || 0 ).toString( 16 ); 12237 return v.length === 1 ? "0" + v : v; 12238 } ).join( "" ); 12239 }, 12240 toString: function() { 12241 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 12242 } 12243} ); 12244color.fn.parse.prototype = color.fn; 12245 12246// hsla conversions adapted from: 12247// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 12248 12249function hue2rgb( p, q, h ) { 12250 h = ( h + 1 ) % 1; 12251 if ( h * 6 < 1 ) { 12252 return p + ( q - p ) * h * 6; 12253 } 12254 if ( h * 2 < 1 ) { 12255 return q; 12256 } 12257 if ( h * 3 < 2 ) { 12258 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 12259 } 12260 return p; 12261} 12262 12263spaces.hsla.to = function( rgba ) { 12264 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 12265 return [ null, null, null, rgba[ 3 ] ]; 12266 } 12267 var r = rgba[ 0 ] / 255, 12268 g = rgba[ 1 ] / 255, 12269 b = rgba[ 2 ] / 255, 12270 a = rgba[ 3 ], 12271 max = Math.max( r, g, b ), 12272 min = Math.min( r, g, b ), 12273 diff = max - min, 12274 add = max + min, 12275 l = add * 0.5, 12276 h, s; 12277 12278 if ( min === max ) { 12279 h = 0; 12280 } else if ( r === max ) { 12281 h = ( 60 * ( g - b ) / diff ) + 360; 12282 } else if ( g === max ) { 12283 h = ( 60 * ( b - r ) / diff ) + 120; 12284 } else { 12285 h = ( 60 * ( r - g ) / diff ) + 240; 12286 } 12287 12288 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 12289 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 12290 if ( diff === 0 ) { 12291 s = 0; 12292 } else if ( l <= 0.5 ) { 12293 s = diff / add; 12294 } else { 12295 s = diff / ( 2 - add ); 12296 } 12297 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 12298}; 12299 12300spaces.hsla.from = function( hsla ) { 12301 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 12302 return [ null, null, null, hsla[ 3 ] ]; 12303 } 12304 var h = hsla[ 0 ] / 360, 12305 s = hsla[ 1 ], 12306 l = hsla[ 2 ], 12307 a = hsla[ 3 ], 12308 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 12309 p = 2 * l - q; 12310 12311 return [ 12312 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 12313 Math.round( hue2rgb( p, q, h ) * 255 ), 12314 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 12315 a 12316 ]; 12317}; 12318 12319 12320each( spaces, function( spaceName, space ) { 12321 var props = space.props, 12322 cache = space.cache, 12323 to = space.to, 12324 from = space.from; 12325 12326 // makes rgba() and hsla() 12327 color.fn[ spaceName ] = function( value ) { 12328 12329 // generate a cache for this space if it doesn't exist 12330 if ( to && !this[ cache ] ) { 12331 this[ cache ] = to( this._rgba ); 12332 } 12333 if ( value === undefined ) { 12334 return this[ cache ].slice(); 12335 } 12336 12337 var ret, 12338 type = getType( value ), 12339 arr = ( type === "array" || type === "object" ) ? value : arguments, 12340 local = this[ cache ].slice(); 12341 12342 each( props, function( key, prop ) { 12343 var val = arr[ type === "object" ? key : prop.idx ]; 12344 if ( val == null ) { 12345 val = local[ prop.idx ]; 12346 } 12347 local[ prop.idx ] = clamp( val, prop ); 12348 } ); 12349 12350 if ( from ) { 12351 ret = color( from( local ) ); 12352 ret[ cache ] = local; 12353 return ret; 12354 } else { 12355 return color( local ); 12356 } 12357 }; 12358 12359 // makes red() green() blue() alpha() hue() saturation() lightness() 12360 each( props, function( key, prop ) { 12361 12362 // alpha is included in more than one space 12363 if ( color.fn[ key ] ) { 12364 return; 12365 } 12366 color.fn[ key ] = function( value ) { 12367 var local, cur, match, fn, 12368 vtype = getType( value ); 12369 12370 if ( key === "alpha" ) { 12371 fn = this._hsla ? "hsla" : "rgba"; 12372 } else { 12373 fn = spaceName; 12374 } 12375 local = this[ fn ](); 12376 cur = local[ prop.idx ]; 12377 12378 if ( vtype === "undefined" ) { 12379 return cur; 12380 } 12381 12382 if ( vtype === "function" ) { 12383 value = value.call( this, cur ); 12384 vtype = getType( value ); 12385 } 12386 if ( value == null && prop.empty ) { 12387 return this; 12388 } 12389 if ( vtype === "string" ) { 12390 match = rplusequals.exec( value ); 12391 if ( match ) { 12392 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 12393 } 12394 } 12395 local[ prop.idx ] = value; 12396 return this[ fn ]( local ); 12397 }; 12398 } ); 12399} ); 12400 12401// add cssHook and .fx.step function for each named hook. 12402// accept a space separated string of properties 12403color.hook = function( hook ) { 12404 var hooks = hook.split( " " ); 12405 each( hooks, function( _i, hook ) { 12406 jQuery.cssHooks[ hook ] = { 12407 set: function( elem, value ) { 12408 var parsed, curElem, 12409 backgroundColor = ""; 12410 12411 if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 12412 value = color( parsed || value ); 12413 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 12414 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 12415 while ( 12416 ( backgroundColor === "" || backgroundColor === "transparent" ) && 12417 curElem && curElem.style 12418 ) { 12419 try { 12420 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 12421 curElem = curElem.parentNode; 12422 } catch ( e ) { 12423 } 12424 } 12425 12426 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 12427 backgroundColor : 12428 "_default" ); 12429 } 12430 12431 value = value.toRgbaString(); 12432 } 12433 try { 12434 elem.style[ hook ] = value; 12435 } catch ( e ) { 12436 12437 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 12438 } 12439 } 12440 }; 12441 jQuery.fx.step[ hook ] = function( fx ) { 12442 if ( !fx.colorInit ) { 12443 fx.start = color( fx.elem, hook ); 12444 fx.end = color( fx.end ); 12445 fx.colorInit = true; 12446 } 12447 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 12448 }; 12449 } ); 12450 12451}; 12452 12453color.hook( stepHooks ); 12454 12455jQuery.cssHooks.borderColor = { 12456 expand: function( value ) { 12457 var expanded = {}; 12458 12459 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 12460 expanded[ "border" + part + "Color" ] = value; 12461 } ); 12462 return expanded; 12463 } 12464}; 12465 12466// Basic color names only. 12467// Usage of any of the other color names requires adding yourself or including 12468// jquery.color.svg-names.js. 12469colors = jQuery.Color.names = { 12470 12471 // 4.1. Basic color keywords 12472 aqua: "#00ffff", 12473 black: "#000000", 12474 blue: "#0000ff", 12475 fuchsia: "#ff00ff", 12476 gray: "#808080", 12477 green: "#008000", 12478 lime: "#00ff00", 12479 maroon: "#800000", 12480 navy: "#000080", 12481 olive: "#808000", 12482 purple: "#800080", 12483 red: "#ff0000", 12484 silver: "#c0c0c0", 12485 teal: "#008080", 12486 white: "#ffffff", 12487 yellow: "#ffff00", 12488 12489 // 4.2.3. "transparent" color keyword 12490 transparent: [ null, null, null, 0 ], 12491 12492 _default: "#ffffff" 12493}; 12494
12495} ); 12496 12497 12498 12499 12500/*! 12501 * jQuery UI Effects 1.13.0 12502 * http://jqueryui.com 12503 * 12504 * Copyright jQuery Foundation and other contributors 12505 * Released under the MIT license. 12506 * http://jquery.org/license 12507 */ 12508 12509//>>label: Effects Core 12510//>>group: Effects 12511/* eslint-disable max-len */ 12512//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 12513/* eslint-enable max-len */ 12514//>>docs: http://api.jqueryui.com/category/effects-core/ 12515//>>demos: http://jqueryui.com/effect/ 12516 12517( function( factory ) { 12518 "use strict"; 12519 12520 if ( typeof define === "function" && define.amd ) { 12521 12522 // AMD. Register as an anonymous module. 12523 define( [ 12524 "jquery", 12525 "./jquery-var-for-color", 12526 "./vendor/jquery-color/jquery.color", 12527 "./version" 12528 ], factory ); 12529 } else { 12530 12531 // Browser globals 12532 factory( jQuery ); 12533 } 12534} )( function( $ ) { 12535"use strict";
vendor: 9,460 bytes, lines 12535-12904
12535 12536 12537var dataSpace = "ui-effects-", 12538 dataSpaceStyle = "ui-effects-style", 12539 dataSpaceAnimated = "ui-effects-animated"; 12540 12541$.effects = { 12542 effect: {} 12543}; 12544 12545/******************************************************************************/ 12546/****************************** CLASS ANIMATIONS ******************************/ 12547/******************************************************************************/ 12548( function() { 12549 12550var classAnimationActions = [ "add", "remove", "toggle" ], 12551 shorthandStyles = { 12552 border: 1, 12553 borderBottom: 1, 12554 borderColor: 1, 12555 borderLeft: 1, 12556 borderRight: 1, 12557 borderTop: 1, 12558 borderWidth: 1, 12559 margin: 1, 12560 padding: 1 12561 }; 12562 12563$.each( 12564 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 12565 function( _, prop ) { 12566 $.fx.step[ prop ] = function( fx ) { 12567 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 12568 jQuery.style( fx.elem, prop, fx.end ); 12569 fx.setAttr = true; 12570 } 12571 }; 12572 } 12573); 12574 12575function camelCase( string ) { 12576 return string.replace( /-([\da-z])/gi, function( all, letter ) { 12577 return letter.toUpperCase(); 12578 } ); 12579} 12580 12581function getElementStyles( elem ) { 12582 var key, len, 12583 style = elem.ownerDocument.defaultView ? 12584 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 12585 elem.currentStyle, 12586 styles = {}; 12587 12588 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 12589 len = style.length; 12590 while ( len-- ) { 12591 key = style[ len ]; 12592 if ( typeof style[ key ] === "string" ) { 12593 styles[ camelCase( key ) ] = style[ key ]; 12594 } 12595 } 12596 12597 // Support: Opera, IE <9 12598 } else { 12599 for ( key in style ) { 12600 if ( typeof style[ key ] === "string" ) { 12601 styles[ key ] = style[ key ]; 12602 } 12603 } 12604 } 12605 12606 return styles; 12607} 12608 12609function styleDifference( oldStyle, newStyle ) { 12610 var diff = {}, 12611 name, value; 12612 12613 for ( name in newStyle ) { 12614 value = newStyle[ name ]; 12615 if ( oldStyle[ name ] !== value ) { 12616 if ( !shorthandStyles[ name ] ) { 12617 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 12618 diff[ name ] = value; 12619 } 12620 } 12621 } 12622 } 12623 12624 return diff; 12625} 12626 12627// Support: jQuery <1.8 12628if ( !$.fn.addBack ) { 12629 $.fn.addBack = function( selector ) { 12630 return this.add( selector == null ? 12631 this.prevObject : this.prevObject.filter( selector ) 12632 ); 12633 }; 12634} 12635 12636$.effects.animateClass = function( value, duration, easing, callback ) { 12637 var o = $.speed( duration, easing, callback ); 12638 12639 return this.queue( function() { 12640 var animated = $( this ), 12641 baseClass = animated.attr( "class" ) || "", 12642 applyClassChange, 12643 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 12644 12645 // Map the animated objects to store the original styles. 12646 allAnimations = allAnimations.map( function() { 12647 var el = $( this ); 12648 return { 12649 el: el, 12650 start: getElementStyles( this ) 12651 }; 12652 } ); 12653 12654 // Apply class change 12655 applyClassChange = function() { 12656 $.each( classAnimationActions, function( i, action ) { 12657 if ( value[ action ] ) { 12658 animated[ action + "Class" ]( value[ action ] ); 12659 } 12660 } ); 12661 }; 12662 applyClassChange(); 12663 12664 // Map all animated objects again - calculate new styles and diff 12665 allAnimations = allAnimations.map( function() { 12666 this.end = getElementStyles( this.el[ 0 ] ); 12667 this.diff = styleDifference( this.start, this.end ); 12668 return this; 12669 } ); 12670 12671 // Apply original class 12672 animated.attr( "class", baseClass ); 12673 12674 // Map all animated objects again - this time collecting a promise 12675 allAnimations = allAnimations.map( function() { 12676 var styleInfo = this, 12677 dfd = $.Deferred(), 12678 opts = $.extend( {}, o, { 12679 queue: false, 12680 complete: function() { 12681 dfd.resolve( styleInfo ); 12682 } 12683 } ); 12684 12685 this.el.animate( this.diff, opts ); 12686 return dfd.promise(); 12687 } ); 12688 12689 // Once all animations have completed: 12690 $.when.apply( $, allAnimations.get() ).done( function() { 12691 12692 // Set the final class 12693 applyClassChange(); 12694 12695 // For each animated element, 12696 // clear all css properties that were animated 12697 $.each( arguments, function() { 12698 var el = this.el; 12699 $.each( this.diff, function( key ) { 12700 el.css( key, "" ); 12701 } ); 12702 } ); 12703 12704 // This is guarnteed to be there if you use jQuery.speed() 12705 // it also handles dequeuing the next anim... 12706 o.complete.call( animated[ 0 ] ); 12707 } ); 12708 } ); 12709}; 12710 12711$.fn.extend( { 12712 addClass: ( function( orig ) { 12713 return function( classNames, speed, easing, callback ) { 12714 return speed ? 12715 $.effects.animateClass.call( this, 12716 { add: classNames }, speed, easing, callback ) : 12717 orig.apply( this, arguments ); 12718 }; 12719 } )( $.fn.addClass ), 12720 12721 removeClass: ( function( orig ) { 12722 return function( classNames, speed, easing, callback ) { 12723 return arguments.length > 1 ? 12724 $.effects.animateClass.call( this, 12725 { remove: classNames }, speed, easing, callback ) : 12726 orig.apply( this, arguments ); 12727 }; 12728 } )( $.fn.removeClass ), 12729 12730 toggleClass: ( function( orig ) { 12731 return function( classNames, force, speed, easing, callback ) { 12732 if ( typeof force === "boolean" || force === undefined ) { 12733 if ( !speed ) { 12734 12735 // Without speed parameter 12736 return orig.apply( this, arguments ); 12737 } else { 12738 return $.effects.animateClass.call( this, 12739 ( force ? { add: classNames } : { remove: classNames } ), 12740 speed, easing, callback ); 12741 } 12742 } else { 12743 12744 // Without force parameter 12745 return $.effects.animateClass.call( this, 12746 { toggle: classNames }, force, speed, easing ); 12747 } 12748 }; 12749 } )( $.fn.toggleClass ), 12750 12751 switchClass: function( remove, add, speed, easing, callback ) { 12752 return $.effects.animateClass.call( this, { 12753 add: add, 12754 remove: remove 12755 }, speed, easing, callback ); 12756 } 12757} ); 12758 12759} )(); 12760 12761/******************************************************************************/ 12762/*********************************** EFFECTS **********************************/ 12763/******************************************************************************/ 12764 12765( function() { 12766 12767if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 12768 $.expr.pseudos.animated = ( function( orig ) { 12769 return function( elem ) { 12770 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 12771 }; 12772 } )( $.expr.pseudos.animated ); 12773} 12774 12775if ( $.uiBackCompat !== false ) { 12776 $.extend( $.effects, { 12777 12778 // Saves a set of properties in a data storage 12779 save: function( element, set ) { 12780 var i = 0, length = set.length; 12781 for ( ; i < length; i++ ) { 12782 if ( set[ i ] !== null ) { 12783 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 12784 } 12785 } 12786 }, 12787 12788 // Restores a set of previously saved properties from a data storage 12789 restore: function( element, set ) { 12790 var val, i = 0, length = set.length; 12791 for ( ; i < length; i++ ) { 12792 if ( set[ i ] !== null ) { 12793 val = element.data( dataSpace + set[ i ] ); 12794 element.css( set[ i ], val ); 12795 } 12796 } 12797 }, 12798 12799 setMode: function( el, mode ) { 12800 if ( mode === "toggle" ) { 12801 mode = el.is( ":hidden" ) ? "show" : "hide"; 12802 } 12803 return mode; 12804 }, 12805 12806 // Wraps the element around a wrapper that copies position properties 12807 createWrapper: function( element ) { 12808 12809 // If the element is already wrapped, return it 12810 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 12811 return element.parent(); 12812 } 12813 12814 // Wrap the element 12815 var props = { 12816 width: element.outerWidth( true ), 12817 height: element.outerHeight( true ), 12818 "float": element.css( "float" ) 12819 }, 12820 wrapper = $( "<div></div>" ) 12821 .addClass( "ui-effects-wrapper" ) 12822 .css( { 12823 fontSize: "100%", 12824 background: "transparent", 12825 border: "none", 12826 margin: 0, 12827 padding: 0 12828 } ), 12829 12830 // Store the size in case width/height are defined in % - Fixes #5245 12831 size = { 12832 width: element.width(), 12833 height: element.height() 12834 }, 12835 active = document.activeElement; 12836 12837 // Support: Firefox 12838 // Firefox incorrectly exposes anonymous content 12839 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 12840 try { 12841 // eslint-disable-next-line no-unused-expressions 12842 active.id; 12843 } catch ( e ) { 12844 active = document.body; 12845 } 12846 12847 element.wrap( wrapper ); 12848 12849 // Fixes #7595 - Elements lose focus when wrapped. 12850 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 12851 $( active ).trigger( "focus" ); 12852 } 12853 12854 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 12855 // lose the reference to the wrapped element 12856 wrapper = element.parent(); 12857 12858 // Transfer positioning properties to the wrapper 12859 if ( element.css( "position" ) === "static" ) { 12860 wrapper.css( { position: "relative" } ); 12861 element.css( { position: "relative" } ); 12862 } else { 12863 $.extend( props, { 12864 position: element.css( "position" ), 12865 zIndex: element.css( "z-index" ) 12866 } ); 12867 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 12868 props[ pos ] = element.css( pos ); 12869 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 12870 props[ pos ] = "auto"; 12871 } 12872 } ); 12873 element.css( { 12874 position: "relative", 12875 top: 0, 12876 left: 0, 12877 right: "auto", 12878 bottom: "auto" 12879 } ); 12880 } 12881 element.css( size ); 12882 12883 return wrapper.css( props ).show(); 12884 }, 12885 12886 removeWrapper: function( element ) { 12887 var active = document.activeElement; 12888 12889 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 12890 element.parent().replaceWith( element ); 12891 12892 // Fixes #7595 - Elements lose focus when wrapped. 12893 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 12894 $( active ).trigger( "focus" ); 12895 } 12896 } 12897 12898 return element; 12899 } 12900 } ); 12901} 12902 12903$.extend( $.effects, { 12904 version: "1.13.
vendor: 2,055 bytes, lines 12904-12999
129040", 12905 12906 define: function( name, mode, effect ) { 12907 if ( !effect ) { 12908 effect = mode; 12909 mode = "effect"; 12910 } 12911 12912 $.effects.effect[ name ] = effect; 12913 $.effects.effect[ name ].mode = mode; 12914 12915 return effect; 12916 }, 12917 12918 scaledDimensions: function( element, percent, direction ) { 12919 if ( percent === 0 ) { 12920 return { 12921 height: 0, 12922 width: 0, 12923 outerHeight: 0, 12924 outerWidth: 0 12925 }; 12926 } 12927 12928 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 12929 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 12930 12931 return { 12932 height: element.height() * y, 12933 width: element.width() * x, 12934 outerHeight: element.outerHeight() * y, 12935 outerWidth: element.outerWidth() * x 12936 }; 12937 12938 }, 12939 12940 clipToBox: function( animation ) { 12941 return { 12942 width: animation.clip.right - animation.clip.left, 12943 height: animation.clip.bottom - animation.clip.top, 12944 left: animation.clip.left, 12945 top: animation.clip.top 12946 }; 12947 }, 12948 12949 // Injects recently queued functions to be first in line (after "inprogress") 12950 unshift: function( element, queueLength, count ) { 12951 var queue = element.queue(); 12952 12953 if ( queueLength > 1 ) { 12954 queue.splice.apply( queue, 12955 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 12956 } 12957 element.dequeue(); 12958 }, 12959 12960 saveStyle: function( element ) { 12961 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 12962 }, 12963 12964 restoreStyle: function( element ) { 12965 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 12966 element.removeData( dataSpaceStyle ); 12967 }, 12968 12969 mode: function( element, mode ) { 12970 var hidden = element.is( ":hidden" ); 12971 12972 if ( mode === "toggle" ) { 12973 mode = hidden ? "show" : "hide"; 12974 } 12975 if ( hidden ? mode === "hide" : mode === "show" ) { 12976 mode = "none"; 12977 } 12978 return mode; 12979 }, 12980 12981 // Translates a [top,left] array into a baseline value 12982 getBaseline: function( origin, original ) { 12983 var y, x; 12984 12985 switch ( origin[ 0 ] ) { 12986 case "top": 12987 y = 0; 12988 break; 12989 case "middle": 12990 y = 0.5; 12991 break; 12992 case "bottom": 12993 y = 1; 12994 break; 12995 default: 12996 y = origin[ 0 ] / original.height; 12997 } 12998 12999 switch ( origin[ 1 ] ) {
13000 case "left": 13001 x = 0; 13002 break; 13003 case "center": 13004 x = 0.5; 13005 break; 13006 case "right": 13007 x = 1; 13008 break; 13009 default: 13010 x = origin[ 1 ] / original.width; 13011 } 13012 13013 return { 13014 x: x, 13015 y: y 13016 }; 13017 }, 13018 13019 // Creates a placeholder element so that the original element can be made absolute 13020 createPlaceholder: function( element ) { 13021 var placeholder, 13022 cssPosition = element.css( "position" ), 13023 position = element.position(); 13024 13025 // Lock in margins first to account for form elements, which 13026 // will change margin if you explicitly set height 13027 // see: http
vendor: 10,558 bytes, lines 13027-13421
13027://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 13028 // Support: Safari 13029 element.css( { 13030 marginTop: element.css( "marginTop" ), 13031 marginBottom: element.css( "marginBottom" ), 13032 marginLeft: element.css( "marginLeft" ), 13033 marginRight: element.css( "marginRight" ) 13034 } ) 13035 .outerWidth( element.outerWidth() ) 13036 .outerHeight( element.outerHeight() ); 13037 13038 if ( /^(static|relative)/.test( cssPosition ) ) { 13039 cssPosition = "absolute"; 13040 13041 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 13042 13043 // Convert inline to inline block to account for inline elements 13044 // that turn to inline block based on content (like img) 13045 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 13046 "inline-block" : 13047 "block", 13048 visibility: "hidden", 13049 13050 // Margins need to be set to account for margin collapse 13051 marginTop: element.css( "marginTop" ), 13052 marginBottom: element.css( "marginBottom" ), 13053 marginLeft: element.css( "marginLeft" ), 13054 marginRight: element.css( "marginRight" ), 13055 "float": element.css( "float" ) 13056 } ) 13057 .outerWidth( element.outerWidth() ) 13058 .outerHeight( element.outerHeight() ) 13059 .addClass( "ui-effects-placeholder" ); 13060 13061 element.data( dataSpace + "placeholder", placeholder ); 13062 } 13063 13064 element.css( { 13065 position: cssPosition, 13066 left: position.left, 13067 top: position.top 13068 } ); 13069 13070 return placeholder; 13071 }, 13072 13073 removePlaceholder: function( element ) { 13074 var dataKey = dataSpace + "placeholder", 13075 placeholder = element.data( dataKey ); 13076 13077 if ( placeholder ) { 13078 placeholder.remove(); 13079 element.removeData( dataKey ); 13080 } 13081 }, 13082 13083 // Removes a placeholder if it exists and restores 13084 // properties that were modified during placeholder creation 13085 cleanUp: function( element ) { 13086 $.effects.restoreStyle( element ); 13087 $.effects.removePlaceholder( element ); 13088 }, 13089 13090 setTransition: function( element, list, factor, value ) { 13091 value = value || {}; 13092 $.each( list, function( i, x ) { 13093 var unit = element.cssUnit( x ); 13094 if ( unit[ 0 ] > 0 ) { 13095 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13096 } 13097 } ); 13098 return value; 13099 } 13100} ); 13101 13102// Return an effect options object for the given parameters: 13103function _normalizeArguments( effect, options, speed, callback ) { 13104 13105 // Allow passing all options as the first parameter 13106 if ( $.isPlainObject( effect ) ) { 13107 options = effect; 13108 effect = effect.effect; 13109 } 13110 13111 // Convert to an object 13112 effect = { effect: effect }; 13113 13114 // Catch (effect, null, ...) 13115 if ( options == null ) { 13116 options = {}; 13117 } 13118 13119 // Catch (effect, callback) 13120 if ( typeof options === "function" ) { 13121 callback = options; 13122 speed = null; 13123 options = {}; 13124 } 13125 13126 // Catch (effect, speed, ?) 13127 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13128 callback = speed; 13129 speed = options; 13130 options = {}; 13131 } 13132 13133 // Catch (effect, options, callback) 13134 if ( typeof speed === "function" ) { 13135 callback = speed; 13136 speed = null; 13137 } 13138 13139 // Add options to effect 13140 if ( options ) { 13141 $.extend( effect, options ); 13142 } 13143 13144 speed = speed || options.duration; 13145 effect.duration = $.fx.off ? 0 : 13146 typeof speed === "number" ? speed : 13147 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13148 $.fx.speeds._default; 13149 13150 effect.complete = callback || options.complete; 13151 13152 return effect; 13153} 13154 13155function standardAnimationOption( option ) { 13156 13157 // Valid standard speeds (nothing, number, named speed) 13158 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 13159 return true; 13160 } 13161 13162 // Invalid strings - treat as "normal" speed 13163 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 13164 return true; 13165 } 13166 13167 // Complete callback 13168 if ( typeof option === "function" ) { 13169 return true; 13170 } 13171 13172 // Options hash (but not naming an effect) 13173 if ( typeof option === "object" && !option.effect ) { 13174 return true; 13175 } 13176 13177 // Didn't match any standard API 13178 return false; 13179} 13180 13181$.fn.extend( { 13182 effect: function( /* effect, options, speed, callback */ ) { 13183 var args = _normalizeArguments.apply( this, arguments ), 13184 effectMethod = $.effects.effect[ args.effect ], 13185 defaultMode = effectMethod.mode, 13186 queue = args.queue, 13187 queueName = queue || "fx", 13188 complete = args.complete, 13189 mode = args.mode, 13190 modes = [], 13191 prefilter = function( next ) { 13192 var el = $( this ), 13193 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 13194 13195 // Sentinel for duck-punching the :animated pseudo-selector 13196 el.data( dataSpaceAnimated, true ); 13197 13198 // Save effect mode for later use, 13199 // we can't just call $.effects.mode again later, 13200 // as the .show() below destroys the initial state 13201 modes.push( normalizedMode ); 13202 13203 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 13204 if ( defaultMode && ( normalizedMode === "show" || 13205 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 13206 el.show(); 13207 } 13208 13209 if ( !defaultMode || normalizedMode !== "none" ) { 13210 $.effects.saveStyle( el ); 13211 } 13212 13213 if ( typeof next === "function" ) { 13214 next(); 13215 } 13216 }; 13217 13218 if ( $.fx.off || !effectMethod ) { 13219 13220 // Delegate to the original method (e.g., .show()) if possible 13221 if ( mode ) { 13222 return this[ mode ]( args.duration, complete ); 13223 } else { 13224 return this.each( function() { 13225 if ( complete ) { 13226 complete.call( this ); 13227 } 13228 } ); 13229 } 13230 } 13231 13232 function run( next ) { 13233 var elem = $( this ); 13234 13235 function cleanup() { 13236 elem.removeData( dataSpaceAnimated ); 13237 13238 $.effects.cleanUp( elem ); 13239 13240 if ( args.mode === "hide" ) { 13241 elem.hide(); 13242 } 13243 13244 done(); 13245 } 13246 13247 function done() { 13248 if ( typeof complete === "function" ) { 13249 complete.call( elem[ 0 ] ); 13250 } 13251 13252 if ( typeof next === "function" ) { 13253 next(); 13254 } 13255 } 13256 13257 // Override mode option on a per element basis, 13258 // as toggle can be either show or hide depending on element state 13259 args.mode = modes.shift(); 13260 13261 if ( $.uiBackCompat !== false && !defaultMode ) { 13262 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13263 13264 // Call the core method to track "olddisplay" properly 13265 elem[ mode ](); 13266 done(); 13267 } else { 13268 effectMethod.call( elem[ 0 ], args, done ); 13269 } 13270 } else { 13271 if ( args.mode === "none" ) { 13272 13273 // Call the core method to track "olddisplay" properly 13274 elem[ mode ](); 13275 done(); 13276 } else { 13277 effectMethod.call( elem[ 0 ], args, cleanup ); 13278 } 13279 } 13280 } 13281 13282 // Run prefilter on all elements first to ensure that 13283 // any showing or hiding happens before placeholder creation, 13284 // which ensures that any layout changes are correctly captured. 13285 return queue === false ? 13286 this.each( prefilter ).each( run ) : 13287 this.queue( queueName, prefilter ).queue( queueName, run ); 13288 }, 13289 13290 show: ( function( orig ) { 13291 return function( option ) { 13292 if ( standardAnimationOption( option ) ) { 13293 return orig.apply( this, arguments ); 13294 } else { 13295 var args = _normalizeArguments.apply( this, arguments ); 13296 args.mode = "show"; 13297 return this.effect.call( this, args ); 13298 } 13299 }; 13300 } )( $.fn.show ), 13301 13302 hide: ( function( orig ) { 13303 return function( option ) { 13304 if ( standardAnimationOption( option ) ) { 13305 return orig.apply( this, arguments ); 13306 } else { 13307 var args = _normalizeArguments.apply( this, arguments ); 13308 args.mode = "hide"; 13309 return this.effect.call( this, args ); 13310 } 13311 }; 13312 } )( $.fn.hide ), 13313 13314 toggle: ( function( orig ) { 13315 return function( option ) { 13316 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 13317 return orig.apply( this, arguments ); 13318 } else { 13319 var args = _normalizeArguments.apply( this, arguments ); 13320 args.mode = "toggle"; 13321 return this.effect.call( this, args ); 13322 } 13323 }; 13324 } )( $.fn.toggle ), 13325 13326 cssUnit: function( key ) { 13327 var style = this.css( key ), 13328 val = []; 13329 13330 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13331 if ( style.indexOf( unit ) > 0 ) { 13332 val = [ parseFloat( style ), unit ]; 13333 } 13334 } ); 13335 return val; 13336 }, 13337 13338 cssClip: function( clipObj ) { 13339 if ( clipObj ) { 13340 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 13341 clipObj.bottom + "px " + clipObj.left + "px)" ); 13342 } 13343 return parseClip( this.css( "clip" ), this ); 13344 }, 13345 13346 transfer: function( options, done ) { 13347 var element = $( this ), 13348 target = $( options.to ), 13349 targetFixed = target.css( "position" ) === "fixed", 13350 body = $( "body" ), 13351 fixTop = targetFixed ? body.scrollTop() : 0, 13352 fixLeft = targetFixed ? body.scrollLeft() : 0, 13353 endPosition = target.offset(), 13354 animation = { 13355 top: endPosition.top - fixTop, 13356 left: endPosition.left - fixLeft, 13357 height: target.innerHeight(), 13358 width: target.innerWidth() 13359 }, 13360 startPosition = element.offset(), 13361 transfer = $( "<div class='ui-effects-transfer'></div>" ); 13362 13363 transfer 13364 .appendTo( "body" ) 13365 .addClass( options.className ) 13366 .css( { 13367 top: startPosition.top - fixTop, 13368 left: startPosition.left - fixLeft, 13369 height: element.innerHeight(), 13370 width: element.innerWidth(), 13371 position: targetFixed ? "fixed" : "absolute" 13372 } ) 13373 .animate( animation, options.duration, options.easing, function() { 13374 transfer.remove(); 13375 if ( typeof done === "function" ) { 13376 done(); 13377 } 13378 } ); 13379 } 13380} ); 13381 13382function parseClip( str, element ) { 13383 var outerWidth = element.outerWidth(), 13384 outerHeight = element.outerHeight(), 13385 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, 13386 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 13387 13388 return { 13389 top: parseFloat( values[ 1 ] ) || 0, 13390 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 13391 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 13392 left: parseFloat( values[ 4 ] ) || 0 13393 }; 13394} 13395 13396$.fx.step.clip = function( fx ) { 13397 if ( !fx.clipInit ) { 13398 fx.start = $( fx.elem ).cssClip(); 13399 if ( typeof fx.end === "string" ) { 13400 fx.end = parseClip( fx.end, fx.elem ); 13401 } 13402 fx.clipInit = true; 13403 } 13404 13405 $( fx.elem ).cssClip( { 13406 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 13407 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 13408 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 13409 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 13410 } ); 13411}; 13412 13413} )(); 13414 13415/******************************************************************************/ 13416/*********************************** EASING ***********************************/ 13417/******************************************************************************/ 13418 13419( function() { 13420 13421// Based on easing equations from Robert Penner (http://
vendor: 9,574 bytes, lines 13421-13795
13421www.robertpenner.com/easing) 13422 13423var baseEasings = {}; 13424 13425$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13426 baseEasings[ name ] = function( p ) { 13427 return Math.pow( p, i + 2 ); 13428 }; 13429} ); 13430 13431$.extend( baseEasings, { 13432 Sine: function( p ) { 13433 return 1 - Math.cos( p * Math.PI / 2 ); 13434 }, 13435 Circ: function( p ) { 13436 return 1 - Math.sqrt( 1 - p * p ); 13437 }, 13438 Elastic: function( p ) { 13439 return p === 0 || p === 1 ? p : 13440 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 13441 }, 13442 Back: function( p ) { 13443 return p * p * ( 3 * p - 2 ); 13444 }, 13445 Bounce: function( p ) { 13446 var pow2, 13447 bounce = 4; 13448 13449 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 13450 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 13451 } 13452} ); 13453 13454$.each( baseEasings, function( name, easeIn ) { 13455 $.easing[ "easeIn" + name ] = easeIn; 13456 $.easing[ "easeOut" + name ] = function( p ) { 13457 return 1 - easeIn( 1 - p ); 13458 }; 13459 $.easing[ "easeInOut" + name ] = function( p ) { 13460 return p < 0.5 ? 13461 easeIn( p * 2 ) / 2 : 13462 1 - easeIn( p * -2 + 2 ) / 2; 13463 }; 13464} ); 13465 13466} )(); 13467 13468return $.effects; 13469 13470} ); 13471 13472 13473 13474/*! 13475 * jQuery UI Form Reset Mixin 1.13.0 13476 * http://jqueryui.com 13477 * 13478 * Copyright jQuery Foundation and other contributors 13479 * Released under the MIT license. 13480 * http://jquery.org/license 13481 */ 13482 13483//>>label: Form Reset Mixin 13484//>>group: Core 13485//>>description: Refresh input widgets when their form is reset 13486//>>docs: http://api.jqueryui.com/form-reset-mixin/ 13487 13488( function( factory ) { 13489 "use strict"; 13490 13491 if ( typeof define === "function" && define.amd ) { 13492 13493 // AMD. Register as an anonymous module. 13494 define( [ 13495 "jquery", 13496 "./form", 13497 "./version" 13498 ], factory ); 13499 } else { 13500 13501 // Browser globals 13502 factory( jQuery ); 13503 } 13504} )( function( $ ) { 13505"use strict"; 13506 13507return $.ui.formResetMixin = { 13508 _formResetHandler: function() { 13509 var form = $( this ); 13510 13511 // Wait for the form reset to actually happen before refreshing 13512 setTimeout( function() { 13513 var instances = form.data( "ui-form-reset-instances" ); 13514 $.each( instances, function() { 13515 this.refresh(); 13516 } ); 13517 } ); 13518 }, 13519 13520 _bindFormResetHandler: function() { 13521 this.form = this.element._form(); 13522 if ( !this.form.length ) { 13523 return; 13524 } 13525 13526 var instances = this.form.data( "ui-form-reset-instances" ) || []; 13527 if ( !instances.length ) { 13528 13529 // We don't use _on() here because we use a single event handler per form 13530 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 13531 } 13532 instances.push( this ); 13533 this.form.data( "ui-form-reset-instances", instances ); 13534 }, 13535 13536 _unbindFormResetHandler: function() { 13537 if ( !this.form.length ) { 13538 return; 13539 } 13540 13541 var instances = this.form.data( "ui-form-reset-instances" ); 13542 instances.splice( $.inArray( this, instances ), 1 ); 13543 if ( instances.length ) { 13544 this.form.data( "ui-form-reset-instances", instances ); 13545 } else { 13546 this.form 13547 .removeData( "ui-form-reset-instances" ) 13548 .off( "reset.ui-form-reset" ); 13549 } 13550 } 13551}; 13552 13553} ); 13554 13555 13556/*! 13557 * jQuery UI Position 1.13.0 13558 * http://jqueryui.com 13559 * 13560 * Copyright jQuery Foundation and other contributors 13561 * Released under the MIT license. 13562 * http://jquery.org/license 13563 * 13564 * http://api.jqueryui.com/position/ 13565 */ 13566 13567//>>label: Position 13568//>>group: Core 13569//>>description: Positions elements relative to other elements. 13570//>>docs: http://api.jqueryui.com/position/ 13571//>>demos: http://jqueryui.com/position/ 13572 13573( function( factory ) { 13574 "use strict"; 13575 13576 if ( typeof define === "function" && define.amd ) { 13577 13578 // AMD. Register as an anonymous module. 13579 define( [ "jquery", "./version" ], factory ); 13580 } else { 13581 13582 // Browser globals 13583 factory( jQuery ); 13584 } 13585} )( function( $ ) { 13586"use strict"; 13587 13588( function() { 13589var cachedScrollbarWidth, 13590 max = Math.max, 13591 abs = Math.abs, 13592 rhorizontal = /left|center|right/, 13593 rvertical = /top|center|bottom/, 13594 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 13595 rposition = /^\w+/, 13596 rpercent = /%$/, 13597 _position = $.fn.position; 13598 13599function getOffsets( offsets, width, height ) { 13600 return [ 13601 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 13602 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 13603 ]; 13604} 13605 13606function parseCss( element, property ) { 13607 return parseInt( $.css( element, property ), 10 ) || 0; 13608} 13609 13610function isWindow( obj ) { 13611 return obj != null && obj === obj.window; 13612} 13613 13614function getDimensions( elem ) { 13615 var raw = elem[ 0 ]; 13616 if ( raw.nodeType === 9 ) { 13617 return { 13618 width: elem.width(), 13619 height: elem.height(), 13620 offset: { top: 0, left: 0 } 13621 }; 13622 } 13623 if ( isWindow( raw ) ) { 13624 return { 13625 width: elem.width(), 13626 height: elem.height(), 13627 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 13628 }; 13629 } 13630 if ( raw.preventDefault ) { 13631 return { 13632 width: 0, 13633 height: 0, 13634 offset: { top: raw.pageY, left: raw.pageX } 13635 }; 13636 } 13637 return { 13638 width: elem.outerWidth(), 13639 height: elem.outerHeight(), 13640 offset: elem.offset() 13641 }; 13642} 13643 13644$.position = { 13645 scrollbarWidth: function() { 13646 if ( cachedScrollbarWidth !== undefined ) { 13647 return cachedScrollbarWidth; 13648 } 13649 var w1, w2, 13650 div = $( "<div style=" + 13651 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 13652 "<div style='height:300px;width:auto;'></div></div>" ), 13653 innerDiv = div.children()[ 0 ]; 13654 13655 $( "body" ).append( div ); 13656 w1 = innerDiv.offsetWidth; 13657 div.css( "overflow", "scroll" ); 13658 13659 w2 = innerDiv.offsetWidth; 13660 13661 if ( w1 === w2 ) { 13662 w2 = div[ 0 ].clientWidth; 13663 } 13664 13665 div.remove(); 13666 13667 return ( cachedScrollbarWidth = w1 - w2 ); 13668 }, 13669 getScrollInfo: function( within ) { 13670 var overflowX = within.isWindow || within.isDocument ? "" : 13671 within.element.css( "overflow-x" ), 13672 overflowY = within.isWindow || within.isDocument ? "" : 13673 within.element.css( "overflow-y" ), 13674 hasOverflowX = overflowX === "scroll" || 13675 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 13676 hasOverflowY = overflowY === "scroll" || 13677 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 13678 return { 13679 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 13680 height: hasOverflowX ? $.position.scrollbarWidth() : 0 13681 }; 13682 }, 13683 getWithinInfo: function( element ) { 13684 var withinElement = $( element || window ), 13685 isElemWindow = isWindow( withinElement[ 0 ] ), 13686 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 13687 hasOffset = !isElemWindow && !isDocument; 13688 return { 13689 element: withinElement, 13690 isWindow: isElemWindow, 13691 isDocument: isDocument, 13692 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 13693 scrollLeft: withinElement.scrollLeft(), 13694 scrollTop: withinElement.scrollTop(), 13695 width: withinElement.outerWidth(), 13696 height: withinElement.outerHeight() 13697 }; 13698 } 13699}; 13700 13701$.fn.position = function( options ) { 13702 if ( !options || !options.of ) { 13703 return _position.apply( this, arguments ); 13704 } 13705 13706 // Make a copy, we don't want to modify arguments 13707 options = $.extend( {}, options ); 13708 13709 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 13710 13711 // Make sure string options are treated as CSS selectors 13712 target = typeof options.of === "string" ? 13713 $( document ).find( options.of ) : 13714 $( options.of ), 13715 13716 within = $.position.getWithinInfo( options.within ), 13717 scrollInfo = $.position.getScrollInfo( within ), 13718 collision = ( options.collision || "flip" ).split( " " ), 13719 offsets = {}; 13720 13721 dimensions = getDimensions( target ); 13722 if ( target[ 0 ].preventDefault ) { 13723 13724 // Force left top to allow flipping 13725 options.at = "left top"; 13726 } 13727 targetWidth = dimensions.width; 13728 targetHeight = dimensions.height; 13729 targetOffset = dimensions.offset; 13730 13731 // Clone to reuse original targetOffset later 13732 basePosition = $.extend( {}, targetOffset ); 13733 13734 // Force my and at to have valid horizontal and vertical positions 13735 // if a value is missing or invalid, it will be converted to center 13736 $.each( [ "my", "at" ], function() { 13737 var pos = ( options[ this ] || "" ).split( " " ), 13738 horizontalOffset, 13739 verticalOffset; 13740 13741 if ( pos.length === 1 ) { 13742 pos = rhorizontal.test( pos[ 0 ] ) ? 13743 pos.concat( [ "center" ] ) : 13744 rvertical.test( pos[ 0 ] ) ? 13745 [ "center" ].concat( pos ) : 13746 [ "center", "center" ]; 13747 } 13748 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 13749 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 13750 13751 // Calculate offsets 13752 horizontalOffset = roffset.exec( pos[ 0 ] ); 13753 verticalOffset = roffset.exec( pos[ 1 ] ); 13754 offsets[ this ] = [ 13755 horizontalOffset ? horizontalOffset[ 0 ] : 0, 13756 verticalOffset ? verticalOffset[ 0 ] : 0 13757 ]; 13758 13759 // Reduce to just the positions without the offsets 13760 options[ this ] = [ 13761 rposition.exec( pos[ 0 ] )[ 0 ], 13762 rposition.exec( pos[ 1 ] )[ 0 ] 13763 ]; 13764 } ); 13765 13766 // Normalize collision option 13767 if ( collision.length === 1 ) { 13768 collision[ 1 ] = collision[ 0 ]; 13769 } 13770 13771 if ( options.at[ 0 ] === "right" ) { 13772 basePosition.left += targetWidth; 13773 } else if ( options.at[ 0 ] === "center" ) { 13774 basePosition.left += targetWidth / 2; 13775 } 13776 13777 if ( options.at[ 1 ] === "bottom" ) { 13778 basePosition.top += targetHeight; 13779 } else if ( options.at[ 1 ] === "center" ) { 13780 basePosition.top += targetHeight / 2; 13781 } 13782 13783 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 13784 basePosition.left += atOffset[ 0 ]; 13785 basePosition.top += atOffset[ 1 ]; 13786 13787 return this.each( function() { 13788 var collisionPosition, using, 13789 elem = $( this ), 13790 elemWidth = elem.outerWidth(), 13791 elemHeight = elem.outerHeight(), 13792 marginLeft = parseCss( this, "marginLeft" ), 13793 marginTop = parseCss( this, "marginTop" ), 13794 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 13795 scrollInfo.width,
vendor: 10,575 bytes, lines 13796-14148
13796 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 13797 scrollInfo.height, 13798 position = $.extend( {}, basePosition ), 13799 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 13800 13801 if ( options.my[ 0 ] === "right" ) { 13802 position.left -= elemWidth; 13803 } else if ( options.my[ 0 ] === "center" ) { 13804 position.left -= elemWidth / 2; 13805 } 13806 13807 if ( options.my[ 1 ] === "bottom" ) { 13808 position.top -= elemHeight; 13809 } else if ( options.my[ 1 ] === "center" ) { 13810 position.top -= elemHeight / 2; 13811 } 13812 13813 position.left += myOffset[ 0 ]; 13814 position.top += myOffset[ 1 ]; 13815 13816 collisionPosition = { 13817 marginLeft: marginLeft, 13818 marginTop: marginTop 13819 }; 13820 13821 $.each( [ "left", "top" ], function( i, dir ) { 13822 if ( $.ui.position[ collision[ i ] ] ) { 13823 $.ui.position[ collision[ i ] ][ dir ]( position, { 13824 targetWidth: targetWidth, 13825 targetHeight: targetHeight, 13826 elemWidth: elemWidth, 13827 elemHeight: elemHeight, 13828 collisionPosition: collisionPosition, 13829 collisionWidth: collisionWidth, 13830 collisionHeight: collisionHeight, 13831 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 13832 my: options.my, 13833 at: options.at, 13834 within: within, 13835 elem: elem 13836 } ); 13837 } 13838 } ); 13839 13840 if ( options.using ) { 13841 13842 // Adds feedback as second argument to using callback, if present 13843 using = function( props ) { 13844 var left = targetOffset.left - position.left, 13845 right = left + targetWidth - elemWidth, 13846 top = targetOffset.top - position.top, 13847 bottom = top + targetHeight - elemHeight, 13848 feedback = { 13849 target: { 13850 element: target, 13851 left: targetOffset.left, 13852 top: targetOffset.top, 13853 width: targetWidth, 13854 height: targetHeight 13855 }, 13856 element: { 13857 element: elem, 13858 left: position.left, 13859 top: position.top, 13860 width: elemWidth, 13861 height: elemHeight 13862 }, 13863 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 13864 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 13865 }; 13866 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 13867 feedback.horizontal = "center"; 13868 } 13869 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 13870 feedback.vertical = "middle"; 13871 } 13872 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 13873 feedback.important = "horizontal"; 13874 } else { 13875 feedback.important = "vertical"; 13876 } 13877 options.using.call( this, props, feedback ); 13878 }; 13879 } 13880 13881 elem.offset( $.extend( position, { using: using } ) ); 13882 } ); 13883}; 13884 13885$.ui.position = { 13886 fit: { 13887 left: function( position, data ) { 13888 var within = data.within, 13889 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 13890 outerWidth = within.width, 13891 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 13892 overLeft = withinOffset - collisionPosLeft, 13893 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 13894 newOverRight; 13895 13896 // Element is wider than within 13897 if ( data.collisionWidth > outerWidth ) { 13898 13899 // Element is initially over the left side of within 13900 if ( overLeft > 0 && overRight <= 0 ) { 13901 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 13902 withinOffset; 13903 position.left += overLeft - newOverRight; 13904 13905 // Element is initially over right side of within 13906 } else if ( overRight > 0 && overLeft <= 0 ) { 13907 position.left = withinOffset; 13908 13909 // Element is initially over both left and right sides of within 13910 } else { 13911 if ( overLeft > overRight ) { 13912 position.left = withinOffset + outerWidth - data.collisionWidth; 13913 } else { 13914 position.left = withinOffset; 13915 } 13916 } 13917 13918 // Too far left -> align with left edge 13919 } else if ( overLeft > 0 ) { 13920 position.left += overLeft; 13921 13922 // Too far right -> align with right edge 13923 } else if ( overRight > 0 ) { 13924 position.left -= overRight; 13925 13926 // Adjust based on position and margin 13927 } else { 13928 position.left = max( position.left - collisionPosLeft, position.left ); 13929 } 13930 }, 13931 top: function( position, data ) { 13932 var within = data.within, 13933 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 13934 outerHeight = data.within.height, 13935 collisionPosTop = position.top - data.collisionPosition.marginTop, 13936 overTop = withinOffset - collisionPosTop, 13937 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 13938 newOverBottom; 13939 13940 // Element is taller than within 13941 if ( data.collisionHeight > outerHeight ) { 13942 13943 // Element is initially over the top of within 13944 if ( overTop > 0 && overBottom <= 0 ) { 13945 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 13946 withinOffset; 13947 position.top += overTop - newOverBottom; 13948 13949 // Element is initially over bottom of within 13950 } else if ( overBottom > 0 && overTop <= 0 ) { 13951 position.top = withinOffset; 13952 13953 // Element is initially over both top and bottom of within 13954 } else { 13955 if ( overTop > overBottom ) { 13956 position.top = withinOffset + outerHeight - data.collisionHeight; 13957 } else { 13958 position.top = withinOffset; 13959 } 13960 } 13961 13962 // Too far up -> align with top 13963 } else if ( overTop > 0 ) { 13964 position.top += overTop; 13965 13966 // Too far down -> align with bottom edge 13967 } else if ( overBottom > 0 ) { 13968 position.top -= overBottom; 13969 13970 // Adjust based on position and margin 13971 } else { 13972 position.top = max( position.top - collisionPosTop, position.top ); 13973 } 13974 } 13975 }, 13976 flip: { 13977 left: function( position, data ) { 13978 var within = data.within, 13979 withinOffset = within.offset.left + within.scrollLeft, 13980 outerWidth = within.width, 13981 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 13982 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 13983 overLeft = collisionPosLeft - offsetLeft, 13984 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 13985 myOffset = data.my[ 0 ] === "left" ? 13986 -data.elemWidth : 13987 data.my[ 0 ] === "right" ? 13988 data.elemWidth : 13989 0, 13990 atOffset = data.at[ 0 ] === "left" ? 13991 data.targetWidth : 13992 data.at[ 0 ] === "right" ? 13993 -data.targetWidth : 13994 0, 13995 offset = -2 * data.offset[ 0 ], 13996 newOverRight, 13997 newOverLeft; 13998 13999 if ( overLeft < 0 ) { 14000 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 14001 outerWidth - withinOffset; 14002 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 14003 position.left += myOffset + atOffset + offset; 14004 } 14005 } else if ( overRight > 0 ) { 14006 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 14007 atOffset + offset - offsetLeft; 14008 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 14009 position.left += myOffset + atOffset + offset; 14010 } 14011 } 14012 }, 14013 top: function( position, data ) { 14014 var within = data.within, 14015 withinOffset = within.offset.top + within.scrollTop, 14016 outerHeight = within.height, 14017 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 14018 collisionPosTop = position.top - data.collisionPosition.marginTop, 14019 overTop = collisionPosTop - offsetTop, 14020 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 14021 top = data.my[ 1 ] === "top", 14022 myOffset = top ? 14023 -data.elemHeight : 14024 data.my[ 1 ] === "bottom" ? 14025 data.elemHeight : 14026 0, 14027 atOffset = data.at[ 1 ] === "top" ? 14028 data.targetHeight : 14029 data.at[ 1 ] === "bottom" ? 14030 -data.targetHeight : 14031 0, 14032 offset = -2 * data.offset[ 1 ], 14033 newOverTop, 14034 newOverBottom; 14035 if ( overTop < 0 ) { 14036 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 14037 outerHeight - withinOffset; 14038 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 14039 position.top += myOffset + atOffset + offset; 14040 } 14041 } else if ( overBottom > 0 ) { 14042 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 14043 offset - offsetTop; 14044 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 14045 position.top += myOffset + atOffset + offset; 14046 } 14047 } 14048 } 14049 }, 14050 flipfit: { 14051 left: function() { 14052 $.ui.position.flip.left.apply( this, arguments ); 14053 $.ui.position.fit.left.apply( this, arguments ); 14054 }, 14055 top: function() { 14056 $.ui.position.flip.top.apply( this, arguments ); 14057 $.ui.position.fit.top.apply( this, arguments ); 14058 } 14059 } 14060}; 14061 14062} )(); 14063 14064return $.ui.position; 14065 14066} ); 14067 14068 14069/*! 14070 * jQuery UI Widget 1.13.0 14071 * http://jqueryui.com 14072 * 14073 * Copyright jQuery Foundation and other contributors 14074 * Released under the MIT license. 14075 * http://jquery.org/license 14076 */ 14077 14078//>>label: Widget 14079//>>group: Core 14080//>>description: Provides a factory for creating stateful widgets with a common API. 14081//>>docs: http://api.jqueryui.com/jQuery.widget/ 14082//>>demos: http://jqueryui.com/widget/ 14083 14084( function( factory ) { 14085 "use strict"; 14086 14087 if ( typeof define === "function" && define.amd ) { 14088 14089 // AMD. Register as an anonymous module. 14090 define( [ "jquery", "./version" ], factory ); 14091 } else { 14092 14093 // Browser globals 14094 factory( jQuery ); 14095 } 14096} )( function( $ ) { 14097"use strict"; 14098 14099var widgetUuid = 0; 14100var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 14101var widgetSlice = Array.prototype.slice; 14102 14103$.cleanData = ( function( orig ) { 14104 return function( elems ) { 14105 var events, elem, i; 14106 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 14107 14108 // Only trigger remove when necessary to save time 14109 events = $._data( elem, "events" ); 14110 if ( events && events.remove ) { 14111 $( elem ).triggerHandler( "remove" ); 14112 } 14113 } 14114 orig( elems ); 14115 }; 14116} )( $.cleanData ); 14117 14118$.widget = function( name, base, prototype ) { 14119 var existingConstructor, constructor, basePrototype; 14120 14121 // ProxiedPrototype allows the provided prototype to remain unmodified 14122 // so that it can be used as a mixin for multiple widgets (#8876) 14123 var proxiedPrototype = {}; 14124 14125 var namespace = name.split( "." )[ 0 ]; 14126 name = name.split( "." )[ 1 ]; 14127 var fullName = namespace + "-" + name; 14128 14129 if ( !prototype ) { 14130 prototype = base; 14131 base = $.Widget; 14132 } 14133 14134 if ( Array.isArray( prototype ) ) { 14135 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 14136 } 14137 14138 // Create selector for plugin 14139 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 14140 return !!$.data( elem, fullName ); 14141 }; 14142 14143 $[ namespace ] = $[ namespace ] || {}; 14144 existingConstructor = $[ namespace ][ name ]; 14145 constructor = $[ namespace ][ name ] = function( options, element ) { 14146 14147 // Allow instantiation without "new" keyword 14148 if (
vendor: 11,136 bytes, lines 14148-14570
14148 !this._createWidget ) { 14149 return new constructor( options, element ); 14150 } 14151 14152 // Allow instantiation without initializing for simple inheritance 14153 // must use "new" keyword (the code above always passes args) 14154 if ( arguments.length ) { 14155 this._createWidget( options, element ); 14156 } 14157 }; 14158 14159 // Extend with the existing constructor to carry over any static properties 14160 $.extend( constructor, existingConstructor, { 14161 version: prototype.version, 14162 14163 // Copy the object used to create the prototype in case we need to 14164 // redefine the widget later 14165 _proto: $.extend( {}, prototype ), 14166 14167 // Track widgets that inherit from this widget in case this widget is 14168 // redefined after a widget inherits from it 14169 _childConstructors: [] 14170 } ); 14171 14172 basePrototype = new base(); 14173 14174 // We need to make the options hash a property directly on the new instance 14175 // otherwise we'll modify the options hash on the prototype that we're 14176 // inheriting from 14177 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 14178 $.each( prototype, function( prop, value ) { 14179 if ( typeof value !== "function" ) { 14180 proxiedPrototype[ prop ] = value; 14181 return; 14182 } 14183 proxiedPrototype[ prop ] = ( function() { 14184 function _super() { 14185 return base.prototype[ prop ].apply( this, arguments ); 14186 } 14187 14188 function _superApply( args ) { 14189 return base.prototype[ prop ].apply( this, args ); 14190 } 14191 14192 return function() { 14193 var __super = this._super; 14194 var __superApply = this._superApply; 14195 var returnValue; 14196 14197 this._super = _super; 14198 this._superApply = _superApply; 14199 14200 returnValue = value.apply( this, arguments ); 14201 14202 this._super = __super; 14203 this._superApply = __superApply; 14204 14205 return returnValue; 14206 }; 14207 } )(); 14208 } ); 14209 constructor.prototype = $.widget.extend( basePrototype, { 14210 14211 // TODO: remove support for widgetEventPrefix 14212 // always use the name + a colon as the prefix, e.g., draggable:start 14213 // don't prefix for widgets that aren't DOM-based 14214 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 14215 }, proxiedPrototype, { 14216 constructor: constructor, 14217 namespace: namespace, 14218 widgetName: name, 14219 widgetFullName: fullName 14220 } ); 14221 14222 // If this widget is being redefined then we need to find all widgets that 14223 // are inheriting from it and redefine all of them so that they inherit from 14224 // the new version of this widget. We're essentially trying to replace one 14225 // level in the prototype chain. 14226 if ( existingConstructor ) { 14227 $.each( existingConstructor._childConstructors, function( i, child ) { 14228 var childPrototype = child.prototype; 14229 14230 // Redefine the child widget using the same prototype that was 14231 // originally used, but inherit from the new version of the base 14232 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 14233 child._proto ); 14234 } ); 14235 14236 // Remove the list of existing child constructors from the old constructor 14237 // so the old child constructors can be garbage collected 14238 delete existingConstructor._childConstructors; 14239 } else { 14240 base._childConstructors.push( constructor ); 14241 } 14242 14243 $.widget.bridge( name, constructor ); 14244 14245 return constructor; 14246}; 14247 14248$.widget.extend = function( target ) { 14249 var input = widgetSlice.call( arguments, 1 ); 14250 var inputIndex = 0; 14251 var inputLength = input.length; 14252 var key; 14253 var value; 14254 14255 for ( ; inputIndex < inputLength; inputIndex++ ) { 14256 for ( key in input[ inputIndex ] ) { 14257 value = input[ inputIndex ][ key ]; 14258 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 14259 14260 // Clone objects 14261 if ( $.isPlainObject( value ) ) { 14262 target[ key ] = $.isPlainObject( target[ key ] ) ? 14263 $.widget.extend( {}, target[ key ], value ) : 14264 14265 // Don't extend strings, arrays, etc. with objects 14266 $.widget.extend( {}, value ); 14267 14268 // Copy everything else by reference 14269 } else { 14270 target[ key ] = value; 14271 } 14272 } 14273 } 14274 } 14275 return target; 14276}; 14277 14278$.widget.bridge = function( name, object ) { 14279 var fullName = object.prototype.widgetFullName || name; 14280 $.fn[ name ] = function( options ) { 14281 var isMethodCall = typeof options === "string"; 14282 var args = widgetSlice.call( arguments, 1 ); 14283 var returnValue = this; 14284 14285 if ( isMethodCall ) { 14286 14287 // If this is an empty collection, we need to have the instance method 14288 // return undefined instead of the jQuery instance 14289 if ( !this.length && options === "instance" ) { 14290 returnValue = undefined; 14291 } else { 14292 this.each( function() { 14293 var methodValue; 14294 var instance = $.data( this, fullName ); 14295 14296 if ( options === "instance" ) { 14297 returnValue = instance; 14298 return false; 14299 } 14300 14301 if ( !instance ) { 14302 return $.error( "cannot call methods on " + name + 14303 " prior to initialization; " + 14304 "attempted to call method '" + options + "'" ); 14305 } 14306 14307 if ( typeof instance[ options ] !== "function" || 14308 options.charAt( 0 ) === "_" ) { 14309 return $.error( "no such method '" + options + "' for " + name + 14310 " widget instance" ); 14311 } 14312 14313 methodValue = instance[ options ].apply( instance, args ); 14314 14315 if ( methodValue !== instance && methodValue !== undefined ) { 14316 returnValue = methodValue && methodValue.jquery ? 14317 returnValue.pushStack( methodValue.get() ) : 14318 methodValue; 14319 return false; 14320 } 14321 } ); 14322 } 14323 } else { 14324 14325 // Allow multiple hashes to be passed on init 14326 if ( args.length ) { 14327 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 14328 } 14329 14330 this.each( function() { 14331 var instance = $.data( this, fullName ); 14332 if ( instance ) { 14333 instance.option( options || {} ); 14334 if ( instance._init ) { 14335 instance._init(); 14336 } 14337 } else { 14338 $.data( this, fullName, new object( options, this ) ); 14339 } 14340 } ); 14341 } 14342 14343 return returnValue; 14344 }; 14345}; 14346 14347$.Widget = function( /* options, element */ ) {}; 14348$.Widget._childConstructors = []; 14349 14350$.Widget.prototype = { 14351 widgetName: "widget", 14352 widgetEventPrefix: "", 14353 defaultElement: "<div>", 14354 14355 options: { 14356 classes: {}, 14357 disabled: false, 14358 14359 // Callbacks 14360 create: null 14361 }, 14362 14363 _createWidget: function( options, element ) { 14364 element = $( element || this.defaultElement || this )[ 0 ]; 14365 this.element = $( element ); 14366 this.uuid = widgetUuid++; 14367 this.eventNamespace = "." + this.widgetName + this.uuid; 14368 14369 this.bindings = $(); 14370 this.hoverable = $(); 14371 this.focusable = $(); 14372 this.classesElementLookup = {}; 14373 14374 if ( element !== this ) { 14375 $.data( element, this.widgetFullName, this ); 14376 this._on( true, this.element, { 14377 remove: function( event ) { 14378 if ( event.target === element ) { 14379 this.destroy(); 14380 } 14381 } 14382 } ); 14383 this.document = $( element.style ? 14384 14385 // Element within the document 14386 element.ownerDocument : 14387 14388 // Element is window or document 14389 element.document || element ); 14390 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 14391 } 14392 14393 this.options = $.widget.extend( {}, 14394 this.options, 14395 this._getCreateOptions(), 14396 options ); 14397 14398 this._create(); 14399 14400 if ( this.options.disabled ) { 14401 this._setOptionDisabled( this.options.disabled ); 14402 } 14403 14404 this._trigger( "create", null, this._getCreateEventData() ); 14405 this._init(); 14406 }, 14407 14408 _getCreateOptions: function() { 14409 return {}; 14410 }, 14411 14412 _getCreateEventData: $.noop, 14413 14414 _create: $.noop, 14415 14416 _init: $.noop, 14417 14418 destroy: function() { 14419 var that = this; 14420 14421 this._destroy(); 14422 $.each( this.classesElementLookup, function( key, value ) { 14423 that._removeClass( value, key ); 14424 } ); 14425 14426 // We can probably remove the unbind calls in 2.0 14427 // all event bindings should go through this._on() 14428 this.element 14429 .off( this.eventNamespace ) 14430 .removeData( this.widgetFullName ); 14431 this.widget() 14432 .off( this.eventNamespace ) 14433 .removeAttr( "aria-disabled" ); 14434 14435 // Clean up events and states 14436 this.bindings.off( this.eventNamespace ); 14437 }, 14438 14439 _destroy: $.noop, 14440 14441 widget: function() { 14442 return this.element; 14443 }, 14444 14445 option: function( key, value ) { 14446 var options = key; 14447 var parts; 14448 var curOption; 14449 var i; 14450 14451 if ( arguments.length === 0 ) { 14452 14453 // Don't return a reference to the internal hash 14454 return $.widget.extend( {}, this.options ); 14455 } 14456 14457 if ( typeof key === "string" ) { 14458 14459 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 14460 options = {}; 14461 parts = key.split( "." ); 14462 key = parts.shift(); 14463 if ( parts.length ) { 14464 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 14465 for ( i = 0; i < parts.length - 1; i++ ) { 14466 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 14467 curOption = curOption[ parts[ i ] ]; 14468 } 14469 key = parts.pop(); 14470 if ( arguments.length === 1 ) { 14471 return curOption[ key ] === undefined ? null : curOption[ key ]; 14472 } 14473 curOption[ key ] = value; 14474 } else { 14475 if ( arguments.length === 1 ) { 14476 return this.options[ key ] === undefined ? null : this.options[ key ]; 14477 } 14478 options[ key ] = value; 14479 } 14480 } 14481 14482 this._setOptions( options ); 14483 14484 return this; 14485 }, 14486 14487 _setOptions: function( options ) { 14488 var key; 14489 14490 for ( key in options ) { 14491 this._setOption( key, options[ key ] ); 14492 } 14493 14494 return this; 14495 }, 14496 14497 _setOption: function( key, value ) { 14498 if ( key === "classes" ) { 14499 this._setOptionClasses( value ); 14500 } 14501 14502 this.options[ key ] = value; 14503 14504 if ( key === "disabled" ) { 14505 this._setOptionDisabled( value ); 14506 } 14507 14508 return this; 14509 }, 14510 14511 _setOptionClasses: function( value ) { 14512 var classKey, elements, currentElements; 14513 14514 for ( classKey in value ) { 14515 currentElements = this.classesElementLookup[ classKey ]; 14516 if ( value[ classKey ] === this.options.classes[ classKey ] || 14517 !currentElements || 14518 !currentElements.length ) { 14519 continue; 14520 } 14521 14522 // We are doing this to create a new jQuery object because the _removeClass() call 14523 // on the next line is going to destroy the reference to the current elements being 14524 // tracked. We need to save a copy of this collection so that we can add the new classes 14525 // below. 14526 elements = $( currentElements.get() ); 14527 this._removeClass( currentElements, classKey ); 14528 14529 // We don't use _addClass() here, because that uses this.options.classes 14530 // for generating the string of classes. We want to use the value passed in from 14531 // _setOption(), this is the new value of the classes option which was passed to 14532 // _setOption(). We pass this value directly to _classes(). 14533 elements.addClass( this._classes( { 14534 element: elements, 14535 keys: classKey, 14536 classes: value, 14537 add: true 14538 } ) ); 14539 } 14540 }, 14541 14542 _setOptionDisabled: function( value ) { 14543 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 14544 14545 // If the widget is becoming disabled, then nothing is interactive 14546 if ( value ) { 14547 this._removeClass( this.hoverable, null, "ui-state-hover" ); 14548 this._removeClass( this.focusable, null, "ui-state-focus" ); 14549 } 14550 }, 14551 14552 enable: function() { 14553 return this._setOptions( { disabled: false } ); 14554 }, 14555 14556 disable: function() { 14557 return this._setOptions( { disabled: true } ); 14558 }, 14559 14560 _classes: function( options ) { 14561 var full = []; 14562 var that = this; 14563 14564 options = $.extend( { 14565 element: this.element, 14566 classes: this.options.classes || {} 14567 }, options ); 14568 14569 function bindRemoveEvent() { 14570
vendor: 34,981 bytes, lines 14570-16024
14570options.element.each( function( _, element ) { 14571 var isTracked = $.map( that.classesElementLookup, function( elements ) { 14572 return elements; 14573 } ) 14574 .some( function( elements ) { 14575 return elements.is( element ); 14576 } ); 14577 14578 if ( !isTracked ) { 14579 that._on( $( element ), { 14580 remove: "_untrackClassesElement" 14581 } ); 14582 } 14583 } ); 14584 } 14585 14586 function processClassString( classes, checkOption ) { 14587 var current, i; 14588 for ( i = 0; i < classes.length; i++ ) { 14589 current = that.classesElementLookup[ classes[ i ] ] || $(); 14590 if ( options.add ) { 14591 bindRemoveEvent(); 14592 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 14593 } else { 14594 current = $( current.not( options.element ).get() ); 14595 } 14596 that.classesElementLookup[ classes[ i ] ] = current; 14597 full.push( classes[ i ] ); 14598 if ( checkOption && options.classes[ classes[ i ] ] ) { 14599 full.push( options.classes[ classes[ i ] ] ); 14600 } 14601 } 14602 } 14603 14604 if ( options.keys ) { 14605 processClassString( options.keys.match( /\S+/g ) || [], true ); 14606 } 14607 if ( options.extra ) { 14608 processClassString( options.extra.match( /\S+/g ) || [] ); 14609 } 14610 14611 return full.join( " " ); 14612 }, 14613 14614 _untrackClassesElement: function( event ) { 14615 var that = this; 14616 $.each( that.classesElementLookup, function( key, value ) { 14617 if ( $.inArray( event.target, value ) !== -1 ) { 14618 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 14619 } 14620 } ); 14621 14622 this._off( $( event.target ) ); 14623 }, 14624 14625 _removeClass: function( element, keys, extra ) { 14626 return this._toggleClass( element, keys, extra, false ); 14627 }, 14628 14629 _addClass: function( element, keys, extra ) { 14630 return this._toggleClass( element, keys, extra, true ); 14631 }, 14632 14633 _toggleClass: function( element, keys, extra, add ) { 14634 add = ( typeof add === "boolean" ) ? add : extra; 14635 var shift = ( typeof element === "string" || element === null ), 14636 options = { 14637 extra: shift ? keys : extra, 14638 keys: shift ? element : keys, 14639 element: shift ? this.element : element, 14640 add: add 14641 }; 14642 options.element.toggleClass( this._classes( options ), add ); 14643 return this; 14644 }, 14645 14646 _on: function( suppressDisabledCheck, element, handlers ) { 14647 var delegateElement; 14648 var instance = this; 14649 14650 // No suppressDisabledCheck flag, shuffle arguments 14651 if ( typeof suppressDisabledCheck !== "boolean" ) { 14652 handlers = element; 14653 element = suppressDisabledCheck; 14654 suppressDisabledCheck = false; 14655 } 14656 14657 // No element argument, shuffle and use this.element 14658 if ( !handlers ) { 14659 handlers = element; 14660 element = this.element; 14661 delegateElement = this.widget(); 14662 } else { 14663 element = delegateElement = $( element ); 14664 this.bindings = this.bindings.add( element ); 14665 } 14666 14667 $.each( handlers, function( event, handler ) { 14668 function handlerProxy() { 14669 14670 // Allow widgets to customize the disabled handling 14671 // - disabled as an array instead of boolean 14672 // - disabled class as method for disabling individual parts 14673 if ( !suppressDisabledCheck && 14674 ( instance.options.disabled === true || 14675 $( this ).hasClass( "ui-state-disabled" ) ) ) { 14676 return; 14677 } 14678 return ( typeof handler === "string" ? instance[ handler ] : handler ) 14679 .apply( instance, arguments ); 14680 } 14681 14682 // Copy the guid so direct unbinding works 14683 if ( typeof handler !== "string" ) { 14684 handlerProxy.guid = handler.guid = 14685 handler.guid || handlerProxy.guid || $.guid++; 14686 } 14687 14688 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 14689 var eventName = match[ 1 ] + instance.eventNamespace; 14690 var selector = match[ 2 ]; 14691 14692 if ( selector ) { 14693 delegateElement.on( eventName, selector, handlerProxy ); 14694 } else { 14695 element.on( eventName, handlerProxy ); 14696 } 14697 } ); 14698 }, 14699 14700 _off: function( element, eventName ) { 14701 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 14702 this.eventNamespace; 14703 element.off( eventName ); 14704 14705 // Clear the stack to avoid memory leaks (#10056) 14706 this.bindings = $( this.bindings.not( element ).get() ); 14707 this.focusable = $( this.focusable.not( element ).get() ); 14708 this.hoverable = $( this.hoverable.not( element ).get() ); 14709 }, 14710 14711 _delay: function( handler, delay ) { 14712 function handlerProxy() { 14713 return ( typeof handler === "string" ? instance[ handler ] : handler ) 14714 .apply( instance, arguments ); 14715 } 14716 var instance = this; 14717 return setTimeout( handlerProxy, delay || 0 ); 14718 }, 14719 14720 _hoverable: function( element ) { 14721 this.hoverable = this.hoverable.add( element ); 14722 this._on( element, { 14723 mouseenter: function( event ) { 14724 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 14725 }, 14726 mouseleave: function( event ) { 14727 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 14728 } 14729 } ); 14730 }, 14731 14732 _focusable: function( element ) { 14733 this.focusable = this.focusable.add( element ); 14734 this._on( element, { 14735 focusin: function( event ) { 14736 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 14737 }, 14738 focusout: function( event ) { 14739 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 14740 } 14741 } ); 14742 }, 14743 14744 _trigger: function( type, event, data ) { 14745 var prop, orig; 14746 var callback = this.options[ type ]; 14747 14748 data = data || {}; 14749 event = $.Event( event ); 14750 event.type = ( type === this.widgetEventPrefix ? 14751 type : 14752 this.widgetEventPrefix + type ).toLowerCase(); 14753 14754 // The original event may come from any element 14755 // so we need to reset the target on the new event 14756 event.target = this.element[ 0 ]; 14757 14758 // Copy original event properties over to the new event 14759 orig = event.originalEvent; 14760 if ( orig ) { 14761 for ( prop in orig ) { 14762 if ( !( prop in event ) ) { 14763 event[ prop ] = orig[ prop ]; 14764 } 14765 } 14766 } 14767 14768 this.element.trigger( event, data ); 14769 return !( typeof callback === "function" && 14770 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 14771 event.isDefaultPrevented() ); 14772 } 14773}; 14774 14775$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 14776 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 14777 if ( typeof options === "string" ) { 14778 options = { effect: options }; 14779 } 14780 14781 var hasOptions; 14782 var effectName = !options ? 14783 method : 14784 options === true || typeof options === "number" ? 14785 defaultEffect : 14786 options.effect || defaultEffect; 14787 14788 options = options || {}; 14789 if ( typeof options === "number" ) { 14790 options = { duration: options }; 14791 } else if ( options === true ) { 14792 options = {}; 14793 } 14794 14795 hasOptions = !$.isEmptyObject( options ); 14796 options.complete = callback; 14797 14798 if ( options.delay ) { 14799 element.delay( options.delay ); 14800 } 14801 14802 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 14803 element[ method ]( options ); 14804 } else if ( effectName !== method && element[ effectName ] ) { 14805 element[ effectName ]( options.duration, options.easing, callback ); 14806 } else { 14807 element.queue( function( next ) { 14808 $( this )[ method ](); 14809 if ( callback ) { 14810 callback.call( element[ 0 ] ); 14811 } 14812 next(); 14813 } ); 14814 } 14815 }; 14816} ); 14817 14818return $.widget; 14819 14820} ); 14821 14822 14823 14824/*! 14825 * jQuery UI Effects Blind 1.13.0 14826 * http://jqueryui.com 14827 * 14828 * Copyright jQuery Foundation and other contributors 14829 * Released under the MIT license. 14830 * http://jquery.org/license 14831 */ 14832 14833//>>label: Blind Effect 14834//>>group: Effects 14835//>>description: Blinds the element. 14836//>>docs: http://api.jqueryui.com/blind-effect/ 14837//>>demos: http://jqueryui.com/effect/ 14838 14839( function( factory ) { 14840 "use strict"; 14841 14842 if ( typeof define === "function" && define.amd ) { 14843 14844 // AMD. Register as an anonymous module. 14845 define( [ 14846 "jquery", 14847 "../version", 14848 "../effect" 14849 ], factory ); 14850 } else { 14851 14852 // Browser globals 14853 factory( jQuery ); 14854 } 14855} )( function( $ ) { 14856"use strict"; 14857 14858return $.effects.define( "blind", "hide", function( options, done ) { 14859 var map = { 14860 up: [ "bottom", "top" ], 14861 vertical: [ "bottom", "top" ], 14862 down: [ "top", "bottom" ], 14863 left: [ "right", "left" ], 14864 horizontal: [ "right", "left" ], 14865 right: [ "left", "right" ] 14866 }, 14867 element = $( this ), 14868 direction = options.direction || "up", 14869 start = element.cssClip(), 14870 animate = { clip: $.extend( {}, start ) }, 14871 placeholder = $.effects.createPlaceholder( element ); 14872 14873 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 14874 14875 if ( options.mode === "show" ) { 14876 element.cssClip( animate.clip ); 14877 if ( placeholder ) { 14878 placeholder.css( $.effects.clipToBox( animate ) ); 14879 } 14880 14881 animate.clip = start; 14882 } 14883 14884 if ( placeholder ) { 14885 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 14886 } 14887 14888 element.animate( animate, { 14889 queue: false, 14890 duration: options.duration, 14891 easing: options.easing, 14892 complete: done 14893 } ); 14894} ); 14895 14896} ); 14897 14898 14899 14900/*! 14901 * jQuery UI Effects Bounce 1.13.0 14902 * http://jqueryui.com 14903 * 14904 * Copyright jQuery Foundation and other contributors 14905 * Released under the MIT license. 14906 * http://jquery.org/license 14907 */ 14908 14909//>>label: Bounce Effect 14910//>>group: Effects 14911//>>description: Bounces an element horizontally or vertically n times. 14912//>>docs: http://api.jqueryui.com/bounce-effect/ 14913//>>demos: http://jqueryui.com/effect/ 14914 14915( function( factory ) { 14916 "use strict"; 14917 14918 if ( typeof define === "function" && define.amd ) { 14919 14920 // AMD. Register as an anonymous module. 14921 define( [ 14922 "jquery", 14923 "../version", 14924 "../effect" 14925 ], factory ); 14926 } else { 14927 14928 // Browser globals 14929 factory( jQuery ); 14930 } 14931} )( function( $ ) { 14932"use strict"; 14933 14934return $.effects.define( "bounce", function( options, done ) { 14935 var upAnim, downAnim, refValue, 14936 element = $( this ), 14937 14938 // Defaults: 14939 mode = options.mode, 14940 hide = mode === "hide", 14941 show = mode === "show", 14942 direction = options.direction || "up", 14943 distance = options.distance, 14944 times = options.times || 5, 14945 14946 // Number of internal animations 14947 anims = times * 2 + ( show || hide ? 1 : 0 ), 14948 speed = options.duration / anims, 14949 easing = options.easing, 14950 14951 // Utility: 14952 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14953 motion = ( direction === "up" || direction === "left" ), 14954 i = 0, 14955 14956 queuelen = element.queue().length; 14957 14958 $.effects.createPlaceholder( element ); 14959 14960 refValue = element.css( ref ); 14961 14962 // Default distance for the BIGGEST bounce is the outer Distance / 3 14963 if ( !distance ) { 14964 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 14965 } 14966 14967 if ( show ) { 14968 downAnim = { opacity: 1 }; 14969 downAnim[ ref ] = refValue; 14970 14971 // If we are showing, force opacity 0 and set the initial position 14972 // then do the "first" animation 14973 element 14974 .css( "opacity", 0 ) 14975 .css( ref, motion ? -distance * 2 : distance * 2 ) 14976 .animate( downAnim, speed, easing ); 14977 } 14978 14979 // Start at the smallest distance if we are hiding 14980 if ( hide ) { 14981 distance = distance / Math.pow( 2, times - 1 ); 14982 } 14983 14984 downAnim = {}; 14985 downAnim[ ref ] = refValue; 14986 14987 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 14988 for ( ; i < times; i++ ) { 14989 upAnim = {}; 14990 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 14991 14992 element 14993 .animate( upAnim, speed, easing ) 14994 .animate( downAnim, speed, easing ); 14995 14996 distance = hide ? distance * 2 : distance / 2; 14997 } 14998 14999 // Last Bounce when Hiding 15000 if ( hide ) { 15001 upAnim = { opacity: 0 }; 15002 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 15003 15004 element.animate( upAnim, speed, easing ); 15005 } 15006 15007 element.queue( done ); 15008 15009 $.effects.unshift( element, queuelen, anims + 1 ); 15010} ); 15011 15012} ); 15013 15014 15015 15016/*! 15017 * jQuery UI Effects Clip 1.13.0 15018 * http://jqueryui.com 15019 * 15020 * Copyright jQuery Foundation and other contributors 15021 * Released under the MIT license. 15022 * http://jquery.org/license 15023 */ 15024 15025//>>label: Clip Effect 15026//>>group: Effects 15027//>>description: Clips the element on and off like an old TV. 15028//>>docs: http://api.jqueryui.com/clip-effect/ 15029//>>demos: http://jqueryui.com/effect/ 15030 15031( function( factory ) { 15032 "use strict"; 15033 15034 if ( typeof define === "function" && define.amd ) { 15035 15036 // AMD. Register as an anonymous module. 15037 define( [ 15038 "jquery", 15039 "../version", 15040 "../effect" 15041 ], factory ); 15042 } else { 15043 15044 // Browser globals 15045 factory( jQuery ); 15046 } 15047} )( function( $ ) { 15048"use strict"; 15049 15050return $.effects.define( "clip", "hide", function( options, done ) { 15051 var start, 15052 animate = {}, 15053 element = $( this ), 15054 direction = options.direction || "vertical", 15055 both = direction === "both", 15056 horizontal = both || direction === "horizontal", 15057 vertical = both || direction === "vertical"; 15058 15059 start = element.cssClip(); 15060 animate.clip = { 15061 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 15062 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 15063 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 15064 left: horizontal ? ( start.right - start.left ) / 2 : start.left 15065 }; 15066 15067 $.effects.createPlaceholder( element ); 15068 15069 if ( options.mode === "show" ) { 15070 element.cssClip( animate.clip ); 15071 animate.clip = start; 15072 } 15073 15074 element.animate( animate, { 15075 queue: false, 15076 duration: options.duration, 15077 easing: options.easing, 15078 complete: done 15079 } ); 15080 15081} ); 15082 15083} ); 15084 15085 15086 15087/*! 15088 * jQuery UI Effects Drop 1.13.0 15089 * http://jqueryui.com 15090 * 15091 * Copyright jQuery Foundation and other contributors 15092 * Released under the MIT license. 15093 * http://jquery.org/license 15094 */ 15095 15096//>>label: Drop Effect 15097//>>group: Effects 15098//>>description: Moves an element in one direction and hides it at the same time. 15099//>>docs: http://api.jqueryui.com/drop-effect/ 15100//>>demos: http://jqueryui.com/effect/ 15101 15102( function( factory ) { 15103 "use strict"; 15104 15105 if ( typeof define === "function" && define.amd ) { 15106 15107 // AMD. Register as an anonymous module. 15108 define( [ 15109 "jquery", 15110 "../version", 15111 "../effect" 15112 ], factory ); 15113 } else { 15114 15115 // Browser globals 15116 factory( jQuery ); 15117 } 15118} )( function( $ ) { 15119"use strict"; 15120 15121return $.effects.define( "drop", "hide", function( options, done ) { 15122 15123 var distance, 15124 element = $( this ), 15125 mode = options.mode, 15126 show = mode === "show", 15127 direction = options.direction || "left", 15128 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15129 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 15130 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 15131 animation = { 15132 opacity: 0 15133 }; 15134 15135 $.effects.createPlaceholder( element ); 15136 15137 distance = options.distance || 15138 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 15139 15140 animation[ ref ] = motion + distance; 15141 15142 if ( show ) { 15143 element.css( animation ); 15144 15145 animation[ ref ] = oppositeMotion + distance; 15146 animation.opacity = 1; 15147 } 15148 15149 // Animate 15150 element.animate( animation, { 15151 queue: false, 15152 duration: options.duration, 15153 easing: options.easing, 15154 complete: done 15155 } ); 15156} ); 15157 15158} ); 15159 15160 15161 15162/*! 15163 * jQuery UI Effects Explode 1.13.0 15164 * http://jqueryui.com 15165 * 15166 * Copyright jQuery Foundation and other contributors 15167 * Released under the MIT license. 15168 * http://jquery.org/license 15169 */ 15170 15171//>>label: Explode Effect 15172//>>group: Effects 15173/* eslint-disable max-len */ 15174//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 15175/* eslint-enable max-len */ 15176//>>docs: http://api.jqueryui.com/explode-effect/ 15177//>>demos: http://jqueryui.com/effect/ 15178 15179( function( factory ) { 15180 "use strict"; 15181 15182 if ( typeof define === "function" && define.amd ) { 15183 15184 // AMD. Register as an anonymous module. 15185 define( [ 15186 "jquery", 15187 "../version", 15188 "../effect" 15189 ], factory ); 15190 } else { 15191 15192 // Browser globals 15193 factory( jQuery ); 15194 } 15195} )( function( $ ) { 15196"use strict"; 15197 15198return $.effects.define( "explode", "hide", function( options, done ) { 15199 15200 var i, j, left, top, mx, my, 15201 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 15202 cells = rows, 15203 element = $( this ), 15204 mode = options.mode, 15205 show = mode === "show", 15206 15207 // Show and then visibility:hidden the element before calculating offset 15208 offset = element.show().css( "visibility", "hidden" ).offset(), 15209 15210 // Width and height of a piece 15211 width = Math.ceil( element.outerWidth() / cells ), 15212 height = Math.ceil( element.outerHeight() / rows ), 15213 pieces = []; 15214 15215 // Children animate complete: 15216 function childComplete() { 15217 pieces.push( this ); 15218 if ( pieces.length === rows * cells ) { 15219 animComplete(); 15220 } 15221 } 15222 15223 // Clone the element for each row and cell. 15224 for ( i = 0; i < rows; i++ ) { // ===> 15225 top = offset.top + i * height; 15226 my = i - ( rows - 1 ) / 2; 15227 15228 for ( j = 0; j < cells; j++ ) { // ||| 15229 left = offset.left + j * width; 15230 mx = j - ( cells - 1 ) / 2; 15231 15232 // Create a clone of the now hidden main element that will be absolute positioned 15233 // within a wrapper div off the -left and -top equal to size of our pieces 15234 element 15235 .clone() 15236 .appendTo( "body" ) 15237 .wrap( "<div></div>" ) 15238 .css( { 15239 position: "absolute", 15240 visibility: "visible", 15241 left: -j * width, 15242 top: -i * height 15243 } ) 15244 15245 // Select the wrapper - make it overflow: hidden and absolute positioned based on 15246 // where the original was located +left and +top equal to the size of pieces 15247 .parent() 15248 .addClass( "ui-effects-explode" ) 15249 .css( { 15250 position: "absolute", 15251 overflow: "hidden", 15252 width: width, 15253 height: height, 15254 left: left + ( show ? mx * width : 0 ), 15255 top: top + ( show ? my * height : 0 ), 15256 opacity: show ? 0 : 1 15257 } ) 15258 .animate( { 15259 left: left + ( show ? 0 : mx * width ), 15260 top: top + ( show ? 0 : my * height ), 15261 opacity: show ? 1 : 0 15262 }, options.duration || 500, options.easing, childComplete ); 15263 } 15264 } 15265 15266 function animComplete() { 15267 element.css( { 15268 visibility: "visible" 15269 } ); 15270 $( pieces ).remove(); 15271 done(); 15272 } 15273} ); 15274 15275} ); 15276 15277 15278 15279/*! 15280 * jQuery UI Effects Fade 1.13.0 15281 * http://jqueryui.com 15282 * 15283 * Copyright jQuery Foundation and other contributors 15284 * Released under the MIT license. 15285 * http://jquery.org/license 15286 */ 15287 15288//>>label: Fade Effect 15289//>>group: Effects 15290//>>description: Fades the element. 15291//>>docs: http://api.jqueryui.com/fade-effect/ 15292//>>demos: http://jqueryui.com/effect/ 15293 15294( function( factory ) { 15295 "use strict"; 15296 15297 if ( typeof define === "function" && define.amd ) { 15298 15299 // AMD. Register as an anonymous module. 15300 define( [ 15301 "jquery", 15302 "../version", 15303 "../effect" 15304 ], factory ); 15305 } else { 15306 15307 // Browser globals 15308 factory( jQuery ); 15309 } 15310} )( function( $ ) { 15311"use strict"; 15312 15313return $.effects.define( "fade", "toggle", function( options, done ) { 15314 var show = options.mode === "show"; 15315 15316 $( this ) 15317 .css( "opacity", show ? 0 : 1 ) 15318 .animate( { 15319 opacity: show ? 1 : 0 15320 }, { 15321 queue: false, 15322 duration: options.duration, 15323 easing: options.easing, 15324 complete: done 15325 } ); 15326} ); 15327 15328} ); 15329 15330 15331 15332/*! 15333 * jQuery UI Effects Fold 1.13.0 15334 * http://jqueryui.com 15335 * 15336 * Copyright jQuery Foundation and other contributors 15337 * Released under the MIT license. 15338 * http://jquery.org/license 15339 */ 15340 15341//>>label: Fold Effect 15342//>>group: Effects 15343//>>description: Folds an element first horizontally and then vertically. 15344//>>docs: http://api.jqueryui.com/fold-effect/ 15345//>>demos: http://jqueryui.com/effect/ 15346 15347( function( factory ) { 15348 "use strict"; 15349 15350 if ( typeof define === "function" && define.amd ) { 15351 15352 // AMD. Register as an anonymous module. 15353 define( [ 15354 "jquery", 15355 "../version", 15356 "../effect" 15357 ], factory ); 15358 } else { 15359 15360 // Browser globals 15361 factory( jQuery ); 15362 } 15363} )( function( $ ) { 15364"use strict"; 15365 15366return $.effects.define( "fold", "hide", function( options, done ) { 15367 15368 // Create element 15369 var element = $( this ), 15370 mode = options.mode, 15371 show = mode === "show", 15372 hide = mode === "hide", 15373 size = options.size || 15, 15374 percent = /([0-9]+)%/.exec( size ), 15375 horizFirst = !!options.horizFirst, 15376 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 15377 duration = options.duration / 2, 15378 15379 placeholder = $.effects.createPlaceholder( element ), 15380 15381 start = element.cssClip(), 15382 animation1 = { clip: $.extend( {}, start ) }, 15383 animation2 = { clip: $.extend( {}, start ) }, 15384 15385 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 15386 15387 queuelen = element.queue().length; 15388 15389 if ( percent ) { 15390 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 15391 } 15392 animation1.clip[ ref[ 0 ] ] = size; 15393 animation2.clip[ ref[ 0 ] ] = size; 15394 animation2.clip[ ref[ 1 ] ] = 0; 15395 15396 if ( show ) { 15397 element.cssClip( animation2.clip ); 15398 if ( placeholder ) { 15399 placeholder.css( $.effects.clipToBox( animation2 ) ); 15400 } 15401 15402 animation2.clip = start; 15403 } 15404 15405 // Animate 15406 element 15407 .queue( function( next ) { 15408 if ( placeholder ) { 15409 placeholder 15410 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 15411 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 15412 } 15413 15414 next(); 15415 } ) 15416 .animate( animation1, duration, options.easing ) 15417 .animate( animation2, duration, options.easing ) 15418 .queue( done ); 15419 15420 $.effects.unshift( element, queuelen, 4 ); 15421} ); 15422 15423} ); 15424 15425 15426 15427/*! 15428 * jQuery UI Effects Highlight 1.13.0 15429 * http://jqueryui.com 15430 * 15431 * Copyright jQuery Foundation and other contributors 15432 * Released under the MIT license. 15433 * http://jquery.org/license 15434 */ 15435 15436//>>label: Highlight Effect 15437//>>group: Effects 15438//>>description: Highlights the background of an element in a defined color for a custom duration. 15439//>>docs: http://api.jqueryui.com/highlight-effect/ 15440//>>demos: http://jqueryui.com/effect/ 15441 15442( function( factory ) { 15443 "use strict"; 15444 15445 if ( typeof define === "function" && define.amd ) { 15446 15447 // AMD. Register as an anonymous module. 15448 define( [ 15449 "jquery", 15450 "../version", 15451 "../effect" 15452 ], factory ); 15453 } else { 15454 15455 // Browser globals 15456 factory( jQuery ); 15457 } 15458} )( function( $ ) { 15459"use strict"; 15460 15461return $.effects.define( "highlight", "show", function( options, done ) { 15462 var element = $( this ), 15463 animation = { 15464 backgroundColor: element.css( "backgroundColor" ) 15465 }; 15466 15467 if ( options.mode === "hide" ) { 15468 animation.opacity = 0; 15469 } 15470 15471 $.effects.saveStyle( element ); 15472 15473 element 15474 .css( { 15475 backgroundImage: "none", 15476 backgroundColor: options.color || "#ffff99" 15477 } ) 15478 .animate( animation, { 15479 queue: false, 15480 duration: options.duration, 15481 easing: options.easing, 15482 complete: done 15483 } ); 15484} ); 15485 15486} ); 15487 15488 15489 15490/*! 15491 * jQuery UI Effects Size 1.13.0 15492 * http://jqueryui.com 15493 * 15494 * Copyright jQuery Foundation and other contributors 15495 * Released under the MIT license. 15496 * http://jquery.org/license 15497 */ 15498 15499//>>label: Size Effect 15500//>>group: Effects 15501//>>description: Resize an element to a specified width and height. 15502//>>docs: http://api.jqueryui.com/size-effect/ 15503//>>demos: http://jqueryui.com/effect/ 15504 15505( function( factory ) { 15506 "use strict"; 15507 15508 if ( typeof define === "function" && define.amd ) { 15509 15510 // AMD. Register as an anonymous module. 15511 define( [ 15512 "jquery", 15513 "../version", 15514 "../effect" 15515 ], factory ); 15516 } else { 15517 15518 // Browser globals 15519 factory( jQuery ); 15520 } 15521} )( function( $ ) { 15522"use strict"; 15523 15524return $.effects.define( "size", function( options, done ) { 15525 15526 // Create element 15527 var baseline, factor, temp, 15528 element = $( this ), 15529 15530 // Copy for children 15531 cProps = [ "fontSize" ], 15532 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 15533 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 15534 15535 // Set options 15536 mode = options.mode, 15537 restore = mode !== "effect", 15538 scale = options.scale || "both", 15539 origin = options.origin || [ "middle", "center" ], 15540 position = element.css( "position" ), 15541 pos = element.position(), 15542 original = $.effects.scaledDimensions( element ), 15543 from = options.from || original, 15544 to = options.to || $.effects.scaledDimensions( element, 0 ); 15545 15546 $.effects.createPlaceholder( element ); 15547 15548 if ( mode === "show" ) { 15549 temp = from; 15550 from = to; 15551 to = temp; 15552 } 15553 15554 // Set scaling factor 15555 factor = { 15556 from: { 15557 y: from.height / original.height, 15558 x: from.width / original.width 15559 }, 15560 to: { 15561 y: to.height / original.height, 15562 x: to.width / original.width 15563 } 15564 }; 15565 15566 // Scale the css box 15567 if ( scale === "box" || scale === "both" ) { 15568 15569 // Vertical props scaling 15570 if ( factor.from.y !== factor.to.y ) { 15571 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 15572 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 15573 } 15574 15575 // Horizontal props scaling 15576 if ( factor.from.x !== factor.to.x ) { 15577 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 15578 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 15579 } 15580 } 15581 15582 // Scale the content 15583 if ( scale === "content" || scale === "both" ) { 15584 15585 // Vertical props scaling 15586 if ( factor.from.y !== factor.to.y ) { 15587 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 15588 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 15589 } 15590 } 15591 15592 // Adjust the position properties based on the provided origin points 15593 if ( origin ) { 15594 baseline = $.effects.getBaseline( origin, original ); 15595 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 15596 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 15597 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 15598 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 15599 } 15600 delete from.outerHeight; 15601 delete from.outerWidth; 15602 element.css( from ); 15603 15604 // Animate the children if desired 15605 if ( scale === "content" || scale === "both" ) { 15606 15607 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 15608 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 15609 15610 // Only animate children with width attributes specified 15611 // TODO: is this right? should we include anything with css width specified as well 15612 element.find( "*[width]" ).each( function() { 15613 var child = $( this ), 15614 childOriginal = $.effects.scaledDimensions( child ), 15615 childFrom = { 15616 height: childOriginal.height * factor.from.y, 15617 width: childOriginal.width * factor.from.x, 15618 outerHeight: childOriginal.outerHeight * factor.from.y, 15619 outerWidth: childOriginal.outerWidth * factor.from.x 15620 }, 15621 childTo = { 15622 height: childOriginal.height * factor.to.y, 15623 width: childOriginal.width * factor.to.x, 15624 outerHeight: childOriginal.height * factor.to.y, 15625 outerWidth: childOriginal.width * factor.to.x 15626 }; 15627 15628 // Vertical props scaling 15629 if ( factor.from.y !== factor.to.y ) { 15630 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 15631 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 15632 } 15633 15634 // Horizontal props scaling 15635 if ( factor.from.x !== factor.to.x ) { 15636 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 15637 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 15638 } 15639 15640 if ( restore ) { 15641 $.effects.saveStyle( child ); 15642 } 15643 15644 // Animate children 15645 child.css( childFrom ); 15646 child.animate( childTo, options.duration, options.easing, function() { 15647 15648 // Restore children 15649 if ( restore ) { 15650 $.effects.restoreStyle( child ); 15651 } 15652 } ); 15653 } ); 15654 } 15655 15656 // Animate 15657 element.animate( to, { 15658 queue: false, 15659 duration: options.duration, 15660 easing: options.easing, 15661 complete: function() { 15662 15663 var offset = element.offset(); 15664 15665 if ( to.opacity === 0 ) { 15666 element.css( "opacity", from.opacity ); 15667 } 15668 15669 if ( !restore ) { 15670 element 15671 .css( "position", position === "static" ? "relative" : position ) 15672 .offset( offset ); 15673 15674 // Need to save style here so that automatic style restoration 15675 // doesn't restore to the original styles from before the animation. 15676 $.effects.saveStyle( element ); 15677 } 15678 15679 done(); 15680 } 15681 } ); 15682 15683} ); 15684 15685} ); 15686 15687 15688 15689 15690/*! 15691 * jQuery UI Effects Scale 1.13.0 15692 * http://jqueryui.com 15693 * 15694 * Copyright jQuery Foundation and other contributors 15695 * Released under the MIT license. 15696 * http://jquery.org/license 15697 */ 15698 15699//>>label: Scale Effect 15700//>>group: Effects 15701//>>description: Grows or shrinks an element and its content. 15702//>>docs: http://api.jqueryui.com/scale-effect/ 15703//>>demos: http://jqueryui.com/effect/ 15704 15705( function( factory ) { 15706 "use strict"; 15707 15708 if ( typeof define === "function" && define.amd ) { 15709 15710 // AMD. Register as an anonymous module. 15711 define( [ 15712 "jquery", 15713 "../version", 15714 "../effect", 15715 "./effect-size" 15716 ], factory ); 15717 } else { 15718 15719 // Browser globals 15720 factory( jQuery ); 15721 } 15722} )( function( $ ) { 15723"use strict"; 15724 15725return $.effects.define( "scale", function( options, done ) { 15726 15727 // Create element 15728 var el = $( this ), 15729 mode = options.mode, 15730 percent = parseInt( options.percent, 10 ) || 15731 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 15732 15733 newOptions = $.extend( true, { 15734 from: $.effects.scaledDimensions( el ), 15735 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 15736 origin: options.origin || [ "middle", "center" ] 15737 }, options ); 15738 15739 // Fade option to support puff 15740 if ( options.fade ) { 15741 newOptions.from.opacity = 1; 15742 newOptions.to.opacity = 0; 15743 } 15744 15745 $.effects.effect.size.call( this, newOptions, done ); 15746} ); 15747 15748} ); 15749 15750 15751 15752 15753/*! 15754 * jQuery UI Effects Puff 1.13.0 15755 * http://jqueryui.com 15756 * 15757 * Copyright jQuery Foundation and other contributors 15758 * Released under the MIT license. 15759 * http://jquery.org/license 15760 */ 15761 15762//>>label: Puff Effect 15763//>>group: Effects 15764//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 15765//>>docs: http://api.jqueryui.com/puff-effect/ 15766//>>demos: http://jqueryui.com/effect/ 15767 15768( function( factory ) { 15769 "use strict"; 15770 15771 if ( typeof define === "function" && define.amd ) { 15772 15773 // AMD. Register as an anonymous module. 15774 define( [ 15775 "jquery", 15776 "../version", 15777 "../effect", 15778 "./effect-scale" 15779 ], factory ); 15780 } else { 15781 15782 // Browser globals 15783 factory( jQuery ); 15784 } 15785} )( function( $ ) { 15786"use strict"; 15787 15788return $.effects.define( "puff", "hide", function( options, done ) { 15789 var newOptions = $.extend( true, {}, options, { 15790 fade: true, 15791 percent: parseInt( options.percent, 10 ) || 150 15792 } ); 15793 15794 $.effects.effect.scale.call( this, newOptions, done ); 15795} ); 15796 15797} ); 15798 15799 15800 15801/*! 15802 * jQuery UI Effects Pulsate 1.13.0 15803 * http://jqueryui.com 15804 * 15805 * Copyright jQuery Foundation and other contributors 15806 * Released under the MIT license. 15807 * http://jquery.org/license 15808 */ 15809 15810//>>label: Pulsate Effect 15811//>>group: Effects 15812//>>description: Pulsates an element n times by changing the opacity to zero and back. 15813//>>docs: http://api.jqueryui.com/pulsate-effect/ 15814//>>demos: http://jqueryui.com/effect/ 15815 15816( function( factory ) { 15817 "use strict"; 15818 15819 if ( typeof define === "function" && define.amd ) { 15820 15821 // AMD. Register as an anonymous module. 15822 define( [ 15823 "jquery", 15824 "../version", 15825 "../effect" 15826 ], factory ); 15827 } else { 15828 15829 // Browser globals 15830 factory( jQuery ); 15831 } 15832} )( function( $ ) { 15833"use strict"; 15834 15835return $.effects.define( "pulsate", "show", function( options, done ) { 15836 var element = $( this ), 15837 mode = options.mode, 15838 show = mode === "show", 15839 hide = mode === "hide", 15840 showhide = show || hide, 15841 15842 // Showing or hiding leaves off the "last" animation 15843 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 15844 duration = options.duration / anims, 15845 animateTo = 0, 15846 i = 1, 15847 queuelen = element.queue().length; 15848 15849 if ( show || !element.is( ":visible" ) ) { 15850 element.css( "opacity", 0 ).show(); 15851 animateTo = 1; 15852 } 15853 15854 // Anims - 1 opacity "toggles" 15855 for ( ; i < anims; i++ ) { 15856 element.animate( { opacity: animateTo }, duration, options.easing ); 15857 animateTo = 1 - animateTo; 15858 } 15859 15860 element.animate( { opacity: animateTo }, duration, options.easing ); 15861 15862 element.queue( done ); 15863 15864 $.effects.unshift( element, queuelen, anims + 1 ); 15865} ); 15866 15867} ); 15868 15869 15870 15871/*! 15872 * jQuery UI Effects Shake 1.13.0 15873 * http://jqueryui.com 15874 * 15875 * Copyright jQuery Foundation and other contributors 15876 * Released under the MIT license. 15877 * http://jquery.org/license 15878 */ 15879 15880//>>label: Shake Effect 15881//>>group: Effects 15882//>>description: Shakes an element horizontally or vertically n times. 15883//>>docs: http://api.jqueryui.com/shake-effect/ 15884//>>demos: http://jqueryui.com/effect/ 15885 15886( function( factory ) { 15887 "use strict"; 15888 15889 if ( typeof define === "function" && define.amd ) { 15890 15891 // AMD. Register as an anonymous module. 15892 define( [ 15893 "jquery", 15894 "../version", 15895 "../effect" 15896 ], factory ); 15897 } else { 15898 15899 // Browser globals 15900 factory( jQuery ); 15901 } 15902} )( function( $ ) { 15903"use strict"; 15904 15905return $.effects.define( "shake", function( options, done ) { 15906 15907 var i = 1, 15908 element = $( this ), 15909 direction = options.direction || "left", 15910 distance = options.distance || 20, 15911 times = options.times || 3, 15912 anims = times * 2 + 1, 15913 speed = Math.round( options.duration / anims ), 15914 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15915 positiveMotion = ( direction === "up" || direction === "left" ), 15916 animation = {}, 15917 animation1 = {}, 15918 animation2 = {}, 15919 15920 queuelen = element.queue().length; 15921 15922 $.effects.createPlaceholder( element ); 15923 15924 // Animation 15925 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 15926 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 15927 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 15928 15929 // Animate 15930 element.animate( animation, speed, options.easing ); 15931 15932 // Shakes 15933 for ( ; i < times; i++ ) { 15934 element 15935 .animate( animation1, speed, options.easing ) 15936 .animate( animation2, speed, options.easing ); 15937 } 15938 15939 element 15940 .animate( animation1, speed, options.easing ) 15941 .animate( animation, speed / 2, options.easing ) 15942 .queue( done ); 15943 15944 $.effects.unshift( element, queuelen, anims + 1 ); 15945} ); 15946 15947} ); 15948 15949 15950 15951/*! 15952 * jQuery UI Effects Slide 1.13.0 15953 * http://jqueryui.com 15954 * 15955 * Copyright jQuery Foundation and other contributors 15956 * Released under the MIT license. 15957 * http://jquery.org/license 15958 */ 15959 15960//>>label: Slide Effect 15961//>>group: Effects 15962//>>description: Slides an element in and out of the viewport. 15963//>>docs: http://api.jqueryui.com/slide-effect/ 15964//>>demos: http://jqueryui.com/effect/ 15965 15966( function( factory ) { 15967 "use strict"; 15968 15969 if ( typeof define === "function" && define.amd ) { 15970 15971 // AMD. Register as an anonymous module. 15972 define( [ 15973 "jquery", 15974 "../version", 15975 "../effect" 15976 ], factory ); 15977 } else { 15978 15979 // Browser globals 15980 factory( jQuery ); 15981 } 15982} )( function( $ ) { 15983"use strict"; 15984 15985return $.effects.define( "slide", "show", function( options, done ) { 15986 var startClip, startRef, 15987 element = $( this ), 15988 map = { 15989 up: [ "bottom", "top" ], 15990 down: [ "top", "bottom" ], 15991 left: [ "right", "left" ], 15992 right: [ "left", "right" ] 15993 }, 15994 mode = options.mode, 15995 direction = options.direction || "left", 15996 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 15997 positiveMotion = ( direction === "up" || direction === "left" ), 15998 distance = options.distance || 15999 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 16000 animation = {}; 16001 16002 $.effects.createPlaceholder( element ); 16003 16004 startClip = element.cssClip(); 16005 startRef = element.position()[ ref ]; 16006 16007 // Define hide animation 16008 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 16009 animation.clip = element.cssClip(); 16010 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 16011 16012 // Reverse the animation if we're showing 16013 if ( mode === "show" ) { 16014 element.cssClip( animation.clip ); 16015 element.css( ref, animation[ ref ] ); 16016 animation.clip = startClip; 16017 animation[ ref ] = startRef; 16018 } 16019 16020 // Actually animate 16021 element.animate( animation, { 16022 queue: false, 16023 duration: options.duration, 16024 easing: options.easing,
16025 complete: done 16026 } ); 16027} ); 16028 16029} ); 16030 16031 16032 16033/*! 16034 * jQuery UI Effects Transfer 1.13.0 16035 * http://jqueryui.com 16036 * 16037 * Copyright jQuery Foundation and other contributors 16038 * Released under the MIT license. 16039 * http://jquery.org/license 16040 */ 16041 16042//>>label: Transfer Effect 16043//>>group: Effects 16044//>>description: Displays a transfer effect from one element to another. 16045//>>docs: http://api.jqueryui.com/transfer-effect/ 16046//>>demos: http://jqueryui.com/effect/ 16047 16048( function( factory ) { 16049 "use strict"; 16050 16051 if ( typeof define === "function" && define.amd ) { 16052 16053 // AMD. Register as an anonymous module. 16054 define( [ 16055 "jquery", 16056 "../version", 16057 "../effect" 16058 ], factory ); 16059 } else { 16060 16061 // Browser globals 16062 factory( jQuery ); 16063 } 16064} )( function( $ ) { 16065"use strict"; 16066 16067var effect; 16068if ( $.uiBackCompat !== false ) { 16069 effect = $.effects.define( "transfer", function( options, done ) { 16070 $( this ).transfer( options, done ); 16071 } ); 16072} 16073return effect; 16074 16075} ); 16076 16077 16078 16079 16080 16081/*! 16082 * jQuery UI Accordion 1.13.0 16083 * http://jqueryui.com 16084 * 16085 * Copyright jQuery Foundation and other contributors 16086 * Released under the MIT license. 16087 * http://jquery.org/license 16088 */ 16089 16090//>>label: Accordion 16091//>>group: Widgets 16092/* eslint-disable max-len */ 16093//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 16094/* eslint-enable max-len */ 16095//>>docs: http://api.jqueryui.com/accordion/ 16096//>>demos: http://jqueryui.com/accordion/ 16097//>>css.structure: ../../themes/base/core.css 16098//>>css.structure: ../../themes/base/accordion.css 16099//>>css.theme: ../../themes/base/theme.css 16100 16101( function( factory ) { 16102 "use strict"; 16103 16104 if ( typeof define === "function" && define.amd ) { 16105 16106 // AMD. Register as an anonymous module. 16107 define( [ 16108 "jquery", 16109 "../version", 16110 "../keycode", 16111 "../unique-id", 16112 "../widget" 16113 ], factory ); 16114 } else { 16115 16116 // Browser globals 16117 factory( jQuery ); 16118 } 16119} )( function( $ ) { 16120"use strict"; 16121 16122return $.widget( "ui.accordion", { 16123 version: "1.13.0
vendor: 15,121 bytes, lines 16123-16701
16123", 16124 options: { 16125 active: 0, 16126 animate: {}, 16127 classes: { 16128 "ui-accordion-header": "ui-corner-top", 16129 "ui-accordion-header-collapsed": "ui-corner-all", 16130 "ui-accordion-content": "ui-corner-bottom" 16131 }, 16132 collapsible: false, 16133 event: "click", 16134 header: function( elem ) { 16135 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); 16136 }, 16137 heightStyle: "auto", 16138 icons: { 16139 activeHeader: "ui-icon-triangle-1-s", 16140 header: "ui-icon-triangle-1-e" 16141 }, 16142 16143 // Callbacks 16144 activate: null, 16145 beforeActivate: null 16146 }, 16147 16148 hideProps: { 16149 borderTopWidth: "hide", 16150 borderBottomWidth: "hide", 16151 paddingTop: "hide", 16152 paddingBottom: "hide", 16153 height: "hide" 16154 }, 16155 16156 showProps: { 16157 borderTopWidth: "show", 16158 borderBottomWidth: "show", 16159 paddingTop: "show", 16160 paddingBottom: "show", 16161 height: "show" 16162 }, 16163 16164 _create: function() { 16165 var options = this.options; 16166 16167 this.prevShow = this.prevHide = $(); 16168 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 16169 this.element.attr( "role", "tablist" ); 16170 16171 // Don't allow collapsible: false and active: false / null 16172 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 16173 options.active = 0; 16174 } 16175 16176 this._processPanels(); 16177 16178 // handle negative values 16179 if ( options.active < 0 ) { 16180 options.active += this.headers.length; 16181 } 16182 this._refresh(); 16183 }, 16184 16185 _getCreateEventData: function() { 16186 return { 16187 header: this.active, 16188 panel: !this.active.length ? $() : this.active.next() 16189 }; 16190 }, 16191 16192 _createIcons: function() { 16193 var icon, children, 16194 icons = this.options.icons; 16195 16196 if ( icons ) { 16197 icon = $( "<span>" ); 16198 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 16199 icon.prependTo( this.headers ); 16200 children = this.active.children( ".ui-accordion-header-icon" ); 16201 this._removeClass( children, icons.header ) 16202 ._addClass( children, null, icons.activeHeader ) 16203 ._addClass( this.headers, "ui-accordion-icons" ); 16204 } 16205 }, 16206 16207 _destroyIcons: function() { 16208 this._removeClass( this.headers, "ui-accordion-icons" ); 16209 this.headers.children( ".ui-accordion-header-icon" ).remove(); 16210 }, 16211 16212 _destroy: function() { 16213 var contents; 16214 16215 // Clean up main element 16216 this.element.removeAttr( "role" ); 16217 16218 // Clean up headers 16219 this.headers 16220 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 16221 .removeUniqueId(); 16222 16223 this._destroyIcons(); 16224 16225 // Clean up content panels 16226 contents = this.headers.next() 16227 .css( "display", "" ) 16228 .removeAttr( "role aria-hidden aria-labelledby" ) 16229 .removeUniqueId(); 16230 16231 if ( this.options.heightStyle !== "content" ) { 16232 contents.css( "height", "" ); 16233 } 16234 }, 16235 16236 _setOption: function( key, value ) { 16237 if ( key === "active" ) { 16238 16239 // _activate() will handle invalid values and update this.options 16240 this._activate( value ); 16241 return; 16242 } 16243 16244 if ( key === "event" ) { 16245 if ( this.options.event ) { 16246 this._off( this.headers, this.options.event ); 16247 } 16248 this._setupEvents( value ); 16249 } 16250 16251 this._super( key, value ); 16252 16253 // Setting collapsible: false while collapsed; open first panel 16254 if ( key === "collapsible" && !value && this.options.active === false ) { 16255 this._activate( 0 ); 16256 } 16257 16258 if ( key === "icons" ) { 16259 this._destroyIcons(); 16260 if ( value ) { 16261 this._createIcons(); 16262 } 16263 } 16264 }, 16265 16266 _setOptionDisabled: function( value ) { 16267 this._super( value ); 16268 16269 this.element.attr( "aria-disabled", value ); 16270 16271 // Support: IE8 Only 16272 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE 16273 // so we need to add the disabled class to the headers and panels 16274 this._toggleClass( null, "ui-state-disabled", !!value ); 16275 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", 16276 !!value ); 16277 }, 16278 16279 _keydown: function( event ) { 16280 if ( event.altKey || event.ctrlKey ) { 16281 return; 16282 } 16283 16284 var keyCode = $.ui.keyCode, 16285 length = this.headers.length, 16286 currentIndex = this.headers.index( event.target ), 16287 toFocus = false; 16288 16289 switch ( event.keyCode ) { 16290 case keyCode.RIGHT: 16291 case keyCode.DOWN: 16292 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 16293 break; 16294 case keyCode.LEFT: 16295 case keyCode.UP: 16296 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 16297 break; 16298 case keyCode.SPACE: 16299 case keyCode.ENTER: 16300 this._eventHandler( event ); 16301 break; 16302 case keyCode.HOME: 16303 toFocus = this.headers[ 0 ]; 16304 break; 16305 case keyCode.END: 16306 toFocus = this.headers[ length - 1 ]; 16307 break; 16308 } 16309 16310 if ( toFocus ) { 16311 $( event.target ).attr( "tabIndex", -1 ); 16312 $( toFocus ).attr( "tabIndex", 0 ); 16313 $( toFocus ).trigger( "focus" ); 16314 event.preventDefault(); 16315 } 16316 }, 16317 16318 _panelKeyDown: function( event ) { 16319 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 16320 $( event.currentTarget ).prev().trigger( "focus" ); 16321 } 16322 }, 16323 16324 refresh: function() { 16325 var options = this.options; 16326 this._processPanels(); 16327 16328 // Was collapsed or no panel 16329 if ( ( options.active === false && options.collapsible === true ) || 16330 !this.headers.length ) { 16331 options.active = false; 16332 this.active = $(); 16333 16334 // active false only when collapsible is true 16335 } else if ( options.active === false ) { 16336 this._activate( 0 ); 16337 16338 // was active, but active panel is gone 16339 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 16340 16341 // all remaining panel are disabled 16342 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 16343 options.active = false; 16344 this.active = $(); 16345 16346 // activate previous panel 16347 } else { 16348 this._activate( Math.max( 0, options.active - 1 ) ); 16349 } 16350 16351 // was active, active panel still exists 16352 } else { 16353 16354 // make sure active index is correct 16355 options.active = this.headers.index( this.active ); 16356 } 16357 16358 this._destroyIcons(); 16359 16360 this._refresh(); 16361 }, 16362 16363 _processPanels: function() { 16364 var prevHeaders = this.headers, 16365 prevPanels = this.panels; 16366 16367 if ( typeof this.options.header === "function" ) { 16368 this.headers = this.options.header( this.element ); 16369 } else { 16370 this.headers = this.element.find( this.options.header ); 16371 } 16372 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 16373 "ui-state-default" ); 16374 16375 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 16376 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 16377 16378 // Avoid memory leaks (#10056) 16379 if ( prevPanels ) { 16380 this._off( prevHeaders.not( this.headers ) ); 16381 this._off( prevPanels.not( this.panels ) ); 16382 } 16383 }, 16384 16385 _refresh: function() { 16386 var maxHeight, 16387 options = this.options, 16388 heightStyle = options.heightStyle, 16389 parent = this.element.parent(); 16390 16391 this.active = this._findActive( options.active ); 16392 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 16393 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 16394 this._addClass( this.active.next(), "ui-accordion-content-active" ); 16395 this.active.next().show(); 16396 16397 this.headers 16398 .attr( "role", "tab" ) 16399 .each( function() { 16400 var header = $( this ), 16401 headerId = header.uniqueId().attr( "id" ), 16402 panel = header.next(), 16403 panelId = panel.uniqueId().attr( "id" ); 16404 header.attr( "aria-controls", panelId ); 16405 panel.attr( "aria-labelledby", headerId ); 16406 } ) 16407 .next() 16408 .attr( "role", "tabpanel" ); 16409 16410 this.headers 16411 .not( this.active ) 16412 .attr( { 16413 "aria-selected": "false", 16414 "aria-expanded": "false", 16415 tabIndex: -1 16416 } ) 16417 .next() 16418 .attr( { 16419 "aria-hidden": "true" 16420 } ) 16421 .hide(); 16422 16423 // Make sure at least one header is in the tab order 16424 if ( !this.active.length ) { 16425 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 16426 } else { 16427 this.active.attr( { 16428 "aria-selected": "true", 16429 "aria-expanded": "true", 16430 tabIndex: 0 16431 } ) 16432 .next() 16433 .attr( { 16434 "aria-hidden": "false" 16435 } ); 16436 } 16437 16438 this._createIcons(); 16439 16440 this._setupEvents( options.event ); 16441 16442 if ( heightStyle === "fill" ) { 16443 maxHeight = parent.height(); 16444 this.element.siblings( ":visible" ).each( function() { 16445 var elem = $( this ), 16446 position = elem.css( "position" ); 16447 16448 if ( position === "absolute" || position === "fixed" ) { 16449 return; 16450 } 16451 maxHeight -= elem.outerHeight( true ); 16452 } ); 16453 16454 this.headers.each( function() { 16455 maxHeight -= $( this ).outerHeight( true ); 16456 } ); 16457 16458 this.headers.next() 16459 .each( function() { 16460 $( this ).height( Math.max( 0, maxHeight - 16461 $( this ).innerHeight() + $( this ).height() ) ); 16462 } ) 16463 .css( "overflow", "auto" ); 16464 } else if ( heightStyle === "auto" ) { 16465 maxHeight = 0; 16466 this.headers.next() 16467 .each( function() { 16468 var isVisible = $( this ).is( ":visible" ); 16469 if ( !isVisible ) { 16470 $( this ).show(); 16471 } 16472 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 16473 if ( !isVisible ) { 16474 $( this ).hide(); 16475 } 16476 } ) 16477 .height( maxHeight ); 16478 } 16479 }, 16480 16481 _activate: function( index ) { 16482 var active = this._findActive( index )[ 0 ]; 16483 16484 // Trying to activate the already active panel 16485 if ( active === this.active[ 0 ] ) { 16486 return; 16487 } 16488 16489 // Trying to collapse, simulate a click on the currently active header 16490 active = active || this.active[ 0 ]; 16491 16492 this._eventHandler( { 16493 target: active, 16494 currentTarget: active, 16495 preventDefault: $.noop 16496 } ); 16497 }, 16498 16499 _findActive: function( selector ) { 16500 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 16501 }, 16502 16503 _setupEvents: function( event ) { 16504 var events = { 16505 keydown: "_keydown" 16506 }; 16507 if ( event ) { 16508 $.each( event.split( " " ), function( index, eventName ) { 16509 events[ eventName ] = "_eventHandler"; 16510 } ); 16511 } 16512 16513 this._off( this.headers.add( this.headers.next() ) ); 16514 this._on( this.headers, events ); 16515 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 16516 this._hoverable( this.headers ); 16517 this._focusable( this.headers ); 16518 }, 16519 16520 _eventHandler: function( event ) { 16521 var activeChildren, clickedChildren, 16522 options = this.options, 16523 active = this.active, 16524 clicked = $( event.currentTarget ), 16525 clickedIsActive = clicked[ 0 ] === active[ 0 ], 16526 collapsing = clickedIsActive && options.collapsible, 16527 toShow = collapsing ? $() : clicked.next(), 16528 toHide = active.next(), 16529 eventData = { 16530 oldHeader: active, 16531 oldPanel: toHide, 16532 newHeader: collapsing ? $() : clicked, 16533 newPanel: toShow 16534 }; 16535 16536 event.preventDefault(); 16537 16538 if ( 16539 16540 // click on active header, but not collapsible 16541 ( clickedIsActive && !options.collapsible ) || 16542 16543 // allow canceling activation 16544 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 16545 return; 16546 } 16547 16548 options.active = collapsing ? false : this.headers.index( clicked ); 16549 16550 // When the call to ._toggle() comes after the class changes 16551 // it causes a very odd bug in IE 8 (see #6720) 16552 this.active = clickedIsActive ? $() : clicked; 16553 this._toggle( eventData ); 16554 16555 // Switch classes 16556 // corner classes on the previously active header stay after the animation 16557 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 16558 if ( options.icons ) { 16559 activeChildren = active.children( ".ui-accordion-header-icon" ); 16560 this._removeClass( activeChildren, null, options.icons.activeHeader ) 16561 ._addClass( activeChildren, null, options.icons.header ); 16562 } 16563 16564 if ( !clickedIsActive ) { 16565 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 16566 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 16567 if ( options.icons ) { 16568 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 16569 this._removeClass( clickedChildren, null, options.icons.header ) 16570 ._addClass( clickedChildren, null, options.icons.activeHeader ); 16571 } 16572 16573 this._addClass( clicked.next(), "ui-accordion-content-active" ); 16574 } 16575 }, 16576 16577 _toggle: function( data ) { 16578 var toShow = data.newPanel, 16579 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 16580 16581 // Handle activating a panel during the animation for another activation 16582 this.prevShow.add( this.prevHide ).stop( true, true ); 16583 this.prevShow = toShow; 16584 this.prevHide = toHide; 16585 16586 if ( this.options.animate ) { 16587 this._animate( toShow, toHide, data ); 16588 } else { 16589 toHide.hide(); 16590 toShow.show(); 16591 this._toggleComplete( data ); 16592 } 16593 16594 toHide.attr( { 16595 "aria-hidden": "true" 16596 } ); 16597 toHide.prev().attr( { 16598 "aria-selected": "false", 16599 "aria-expanded": "false" 16600 } ); 16601 16602 // if we're switching panels, remove the old header from the tab order 16603 // if we're opening from collapsed state, remove the previous header from the tab order 16604 // if we're collapsing, then keep the collapsing header in the tab order 16605 if ( toShow.length && toHide.length ) { 16606 toHide.prev().attr( { 16607 "tabIndex": -1, 16608 "aria-expanded": "false" 16609 } ); 16610 } else if ( toShow.length ) { 16611 this.headers.filter( function() { 16612 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 16613 } ) 16614 .attr( "tabIndex", -1 ); 16615 } 16616 16617 toShow 16618 .attr( "aria-hidden", "false" ) 16619 .prev() 16620 .attr( { 16621 "aria-selected": "true", 16622 "aria-expanded": "true", 16623 tabIndex: 0 16624 } ); 16625 }, 16626 16627 _animate: function( toShow, toHide, data ) { 16628 var total, easing, duration, 16629 that = this, 16630 adjust = 0, 16631 boxSizing = toShow.css( "box-sizing" ), 16632 down = toShow.length && 16633 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 16634 animate = this.options.animate || {}, 16635 options = down && animate.down || animate, 16636 complete = function() { 16637 that._toggleComplete( data ); 16638 }; 16639 16640 if ( typeof options === "number" ) { 16641 duration = options; 16642 } 16643 if ( typeof options === "string" ) { 16644 easing = options; 16645 } 16646 16647 // fall back from options to animation in case of partial down settings 16648 easing = easing || options.easing || animate.easing; 16649 duration = duration || options.duration || animate.duration; 16650 16651 if ( !toHide.length ) { 16652 return toShow.animate( this.showProps, duration, easing, complete ); 16653 } 16654 if ( !toShow.length ) { 16655 return toHide.animate( this.hideProps, duration, easing, complete ); 16656 } 16657 16658 total = toShow.show().outerHeight(); 16659 toHide.animate( this.hideProps, { 16660 duration: duration, 16661 easing: easing, 16662 step: function( now, fx ) { 16663 fx.now = Math.round( now ); 16664 } 16665 } ); 16666 toShow 16667 .hide() 16668 .animate( this.showProps, { 16669 duration: duration, 16670 easing: easing, 16671 complete: complete, 16672 step: function( now, fx ) { 16673 fx.now = Math.round( now ); 16674 if ( fx.prop !== "height" ) { 16675 if ( boxSizing === "content-box" ) { 16676 adjust += fx.now; 16677 } 16678 } else if ( that.options.heightStyle !== "content" ) { 16679 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 16680 adjust = 0; 16681 } 16682 } 16683 } ); 16684 }, 16685 16686 _toggleComplete: function( data ) { 16687 var toHide = data.oldPanel, 16688 prev = toHide.prev(); 16689 16690 this._removeClass( toHide, "ui-accordion-content-active" ); 16691 this._removeClass( prev, "ui-accordion-header-active" ) 16692 ._addClass( prev, "ui-accordion-header-collapsed" ); 16693 16694 // Work around for rendering bug in IE (#5421) 16695 if ( toHide.length ) { 16696 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 16697 } 16698 this._trigger( "activate", null, data ); 16699 } 16700} ); 16701
16702} ); 16703 16704 16705 16706 16707 16708 16709 16710/*! 16711 * jQuery UI Menu 1.13.0 16712 * http://jqueryui.com 16713 * 16714 * Copyright jQuery Foundation and other contributors 16715 * Released under the MIT license. 16716 * http://jquery.org/license 16717 */ 16718 16719//>>label: Menu 16720//>>group: Widgets 16721//>>description: Creates nestable menus. 16722//>>docs: http://api.jqueryui.com/menu/ 16723//>>demos: http://jqueryui.com/menu/ 16724//>>css.structure: ../../themes/base/core.css 16725//>>css.structure: ../../themes/base/menu.css 16726//>>css.theme: ../../themes/base/theme.css 16727 16728( function( factory ) { 16729 "use strict"; 16730 16731 if ( typeof define === "function" && define.amd ) { 16732 16733 // AMD. Register as an anonymous module. 16734 define( [ 16735 "jquery", 16736 "../keycode", 16737 "../position", 16738 "../safe-active-element", 16739 "../unique-id", 16740 "../version", 16741 "../widget" 16742 ], factory ); 16743 } else { 16744 16745 // Browser globals 16746 factory( jQuery ); 16747 } 16748} )( function( $ ) { 16749"use strict"; 16750 16751return $.widget( "ui.menu", { 16752 version: "1.13.0
vendor: 2,668 bytes, lines 16752-16854
16752", 16753 defaultElement: "<ul>", 16754 delay: 300, 16755 options: { 16756 icons: { 16757 submenu: "ui-icon-caret-1-e" 16758 }, 16759 items: "> *", 16760 menus: "ul", 16761 position: { 16762 my: "left top", 16763 at: "right top" 16764 }, 16765 role: "menu", 16766 16767 // Callbacks 16768 blur: null, 16769 focus: null, 16770 select: null 16771 }, 16772 16773 _create: function() { 16774 this.activeMenu = this.element; 16775 16776 // Flag used to prevent firing of the click handler 16777 // as the event bubbles up through nested menus 16778 this.mouseHandled = false; 16779 this.lastMousePosition = { x: null, y: null }; 16780 this.element 16781 .uniqueId() 16782 .attr( { 16783 role: this.options.role, 16784 tabIndex: 0 16785 } ); 16786 16787 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 16788 this._on( { 16789 16790 // Prevent focus from sticking to links inside menu after clicking 16791 // them (focus should always stay on UL during navigation). 16792 "mousedown .ui-menu-item": function( event ) { 16793 event.preventDefault(); 16794 16795 this._activateItem( event ); 16796 }, 16797 "click .ui-menu-item": function( event ) { 16798 var target = $( event.target ); 16799 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 16800 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 16801 this.select( event ); 16802 16803 // Only set the mouseHandled flag if the event will bubble, see #9469. 16804 if ( !event.isPropagationStopped() ) { 16805 this.mouseHandled = true; 16806 } 16807 16808 // Open submenu on click 16809 if ( target.has( ".ui-menu" ).length ) { 16810 this.expand( event ); 16811 } else if ( !this.element.is( ":focus" ) && 16812 active.closest( ".ui-menu" ).length ) { 16813 16814 // Redirect focus to the menu 16815 this.element.trigger( "focus", [ true ] ); 16816 16817 // If the active item is on the top level, let it stay active. 16818 // Otherwise, blur the active item since it is no longer visible. 16819 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 16820 clearTimeout( this.timer ); 16821 } 16822 } 16823 } 16824 }, 16825 "mouseenter .ui-menu-item": "_activateItem", 16826 "mousemove .ui-menu-item": "_activateItem", 16827 mouseleave: "collapseAll", 16828 "mouseleave .ui-menu": "collapseAll", 16829 focus: function( event, keepActiveItem ) { 16830 16831 // If there's already an active item, keep it active 16832 // If not, activate the first item 16833 var item = this.active || this._menuItems().first(); 16834 16835 if ( !keepActiveItem ) { 16836 this.focus( event, item ); 16837 } 16838 }, 16839 blur: function( event ) { 16840 this._delay( function() { 16841 var notContained = !$.contains( 16842 this.element[ 0 ], 16843 $.ui.safeActiveElement( this.document[ 0 ] ) 16844 ); 16845 if ( notContained ) { 16846 this.collapseAll( event ); 16847 } 16848 } ); 16849 }, 16850 keydown: "_keydown" 16851 } ); 16852 16853 this.refresh(); 16854
vendor: 3,056 bytes, lines 16855-16971
16855 // Clicks outside of a menu collapse any open menus 16856 this._on( this.document, { 16857 click: function( event ) { 16858 if ( this._closeOnDocumentClick( event ) ) { 16859 this.collapseAll( event, true ); 16860 } 16861 16862 // Reset the mouseHandled flag 16863 this.mouseHandled = false; 16864 } 16865 } ); 16866 }, 16867 16868 _activateItem: function( event ) { 16869 16870 // Ignore mouse events while typeahead is active, see #10458. 16871 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 16872 // is over an item in the menu 16873 if ( this.previousFilter ) { 16874 return; 16875 } 16876 16877 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 16878 if ( event.clientX === this.lastMousePosition.x && 16879 event.clientY === this.lastMousePosition.y ) { 16880 return; 16881 } 16882 16883 this.lastMousePosition = { 16884 x: event.clientX, 16885 y: event.clientY 16886 }; 16887 16888 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 16889 target = $( event.currentTarget ); 16890 16891 // Ignore bubbled events on parent items, see #11641 16892 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 16893 return; 16894 } 16895 16896 // If the item is already active, there's nothing to do 16897 if ( target.is( ".ui-state-active" ) ) { 16898 return; 16899 } 16900 16901 // Remove ui-state-active class from siblings of the newly focused menu item 16902 // to avoid a jump caused by adjacent elements both having a class with a border 16903 this._removeClass( target.siblings().children( ".ui-state-active" ), 16904 null, "ui-state-active" ); 16905 this.focus( event, target ); 16906 }, 16907 16908 _destroy: function() { 16909 var items = this.element.find( ".ui-menu-item" ) 16910 .removeAttr( "role aria-disabled" ), 16911 submenus = items.children( ".ui-menu-item-wrapper" ) 16912 .removeUniqueId() 16913 .removeAttr( "tabIndex role aria-haspopup" ); 16914 16915 // Destroy (sub)menus 16916 this.element 16917 .removeAttr( "aria-activedescendant" ) 16918 .find( ".ui-menu" ).addBack() 16919 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 16920 "tabIndex" ) 16921 .removeUniqueId() 16922 .show(); 16923 16924 submenus.children().each( function() { 16925 var elem = $( this ); 16926 if ( elem.data( "ui-menu-submenu-caret" ) ) { 16927 elem.remove(); 16928 } 16929 } ); 16930 }, 16931 16932 _keydown: function( event ) { 16933 var match, prev, character, skip, 16934 preventDefault = true; 16935 16936 switch ( event.keyCode ) { 16937 case $.ui.keyCode.PAGE_UP: 16938 this.previousPage( event ); 16939 break; 16940 case $.ui.keyCode.PAGE_DOWN: 16941 this.nextPage( event ); 16942 break; 16943 case $.ui.keyCode.HOME: 16944 this._move( "first", "first", event ); 16945 break; 16946 case $.ui.keyCode.END: 16947 this._move( "last", "last", event ); 16948 break; 16949 case $.ui.keyCode.UP: 16950 this.previous( event ); 16951 break; 16952 case $.ui.keyCode.DOWN: 16953 this.next( event ); 16954 break; 16955 case $.ui.keyCode.LEFT: 16956 this.collapse( event ); 16957 break; 16958 case $.ui.keyCode.RIGHT: 16959 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 16960 this.expand( event ); 16961 } 16962 break; 16963 case $.ui.keyCode.ENTER: 16964 case $.ui.keyCode.SPACE: 16965 this._activate( event ); 16966 break; 16967 case $.ui.keyCode.ESCAPE: 16968 this.collapse( event ); 16969 break; 16970 default: 16971 preventDefault = false;
vendor: 2,378 bytes, lines 16972-17057
16972 prev = this.previousFilter || ""; 16973 skip = false; 16974 16975 // Support number pad values 16976 character = event.keyCode >= 96 && event.keyCode <= 105 ? 16977 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 16978 16979 clearTimeout( this.filterTimer ); 16980 16981 if ( character === prev ) { 16982 skip = true; 16983 } else { 16984 character = prev + character; 16985 } 16986 16987 match = this._filterMenuItems( character ); 16988 match = skip && match.index( this.active.next() ) !== -1 ? 16989 this.active.nextAll( ".ui-menu-item" ) : 16990 match; 16991 16992 // If no matches on the current filter, reset to the last character pressed 16993 // to move down the menu to the first item that starts with that character 16994 if ( !match.length ) { 16995 character = String.fromCharCode( event.keyCode ); 16996 match = this._filterMenuItems( character ); 16997 } 16998 16999 if ( match.length ) { 17000 this.focus( event, match ); 17001 this.previousFilter = character; 17002 this.filterTimer = this._delay( function() { 17003 delete this.previousFilter; 17004 }, 1000 ); 17005 } else { 17006 delete this.previousFilter; 17007 } 17008 } 17009 17010 if ( preventDefault ) { 17011 event.preventDefault(); 17012 } 17013 }, 17014 17015 _activate: function( event ) { 17016 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 17017 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 17018 this.expand( event ); 17019 } else { 17020 this.select( event ); 17021 } 17022 } 17023 }, 17024 17025 refresh: function() { 17026 var menus, items, newSubmenus, newItems, newWrappers, 17027 that = this, 17028 icon = this.options.icons.submenu, 17029 submenus = this.element.find( this.options.menus ); 17030 17031 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 17032 17033 // Initialize nested menus 17034 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 17035 .hide() 17036 .attr( { 17037 role: this.options.role, 17038 "aria-hidden": "true", 17039 "aria-expanded": "false" 17040 } ) 17041 .each( function() { 17042 var menu = $( this ), 17043 item = menu.prev(), 17044 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 17045 17046 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 17047 item 17048 .attr( "aria-haspopup", "true" ) 17049 .prepend( submenuCaret ); 17050 menu.attr( "aria-labelledby", item.attr( "id" ) ); 17051 } ); 17052 17053 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 17054 17055 menus = submenus.add( this.element ); 17056 items = menus.find( this.options.items ); 17057
vendor: 4,552 bytes, lines 17058-17220
17058 // Initialize menu-items containing spaces and/or dashes only as dividers 17059 items.not( ".ui-menu-item" ).each( function() { 17060 var item = $( this ); 17061 if ( that._isDivider( item ) ) { 17062 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 17063 } 17064 } ); 17065 17066 // Don't refresh list items that are already adapted 17067 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 17068 newWrappers = newItems.children() 17069 .not( ".ui-menu" ) 17070 .uniqueId() 17071 .attr( { 17072 tabIndex: -1, 17073 role: this._itemRole() 17074 } ); 17075 this._addClass( newItems, "ui-menu-item" ) 17076 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 17077 17078 // Add aria-disabled attribute to any disabled menu item 17079 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 17080 17081 // If the active item has been removed, blur the menu 17082 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 17083 this.blur(); 17084 } 17085 }, 17086 17087 _itemRole: function() { 17088 return { 17089 menu: "menuitem", 17090 listbox: "option" 17091 }[ this.options.role ]; 17092 }, 17093 17094 _setOption: function( key, value ) { 17095 if ( key === "icons" ) { 17096 var icons = this.element.find( ".ui-menu-icon" ); 17097 this._removeClass( icons, null, this.options.icons.submenu ) 17098 ._addClass( icons, null, value.submenu ); 17099 } 17100 this._super( key, value ); 17101 }, 17102 17103 _setOptionDisabled: function( value ) { 17104 this._super( value ); 17105 17106 this.element.attr( "aria-disabled", String( value ) ); 17107 this._toggleClass( null, "ui-state-disabled", !!value ); 17108 }, 17109 17110 focus: function( event, item ) { 17111 var nested, focused, activeParent; 17112 this.blur( event, event && event.type === "focus" ); 17113 17114 this._scrollIntoView( item ); 17115 17116 this.active = item.first(); 17117 17118 focused = this.active.children( ".ui-menu-item-wrapper" ); 17119 this._addClass( focused, null, "ui-state-active" ); 17120 17121 // Only update aria-activedescendant if there's a role 17122 // otherwise we assume focus is managed elsewhere 17123 if ( this.options.role ) { 17124 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 17125 } 17126 17127 // Highlight active parent menu item, if any 17128 activeParent = this.active 17129 .parent() 17130 .closest( ".ui-menu-item" ) 17131 .children( ".ui-menu-item-wrapper" ); 17132 this._addClass( activeParent, null, "ui-state-active" ); 17133 17134 if ( event && event.type === "keydown" ) { 17135 this._close(); 17136 } else { 17137 this.timer = this._delay( function() { 17138 this._close(); 17139 }, this.delay ); 17140 } 17141 17142 nested = item.children( ".ui-menu" ); 17143 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 17144 this._startOpening( nested ); 17145 } 17146 this.activeMenu = item.parent(); 17147 17148 this._trigger( "focus", event, { item: item } ); 17149 }, 17150 17151 _scrollIntoView: function( item ) { 17152 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 17153 if ( this._hasScroll() ) { 17154 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 17155 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 17156 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 17157 scroll = this.activeMenu.scrollTop(); 17158 elementHeight = this.activeMenu.height(); 17159 itemHeight = item.outerHeight(); 17160 17161 if ( offset < 0 ) { 17162 this.activeMenu.scrollTop( scroll + offset ); 17163 } else if ( offset + itemHeight > elementHeight ) { 17164 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 17165 } 17166 } 17167 }, 17168 17169 blur: function( event, fromFocus ) { 17170 if ( !fromFocus ) { 17171 clearTimeout( this.timer ); 17172 } 17173 17174 if ( !this.active ) { 17175 return; 17176 } 17177 17178 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 17179 null, "ui-state-active" ); 17180 17181 this._trigger( "blur", event, { item: this.active } ); 17182 this.active = null; 17183 }, 17184 17185 _startOpening: function( submenu ) { 17186 clearTimeout( this.timer ); 17187 17188 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 17189 // shift in the submenu position when mousing over the caret icon 17190 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 17191 return; 17192 } 17193 17194 this.timer = this._delay( function() { 17195 this._close(); 17196 this._open( submenu ); 17197 }, this.delay ); 17198 }, 17199 17200 _open: function( submenu ) { 17201 var position = $.extend( { 17202 of: this.active 17203 }, this.options.position ); 17204 17205 clearTimeout( this.timer ); 17206 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 17207 .hide() 17208 .attr( "aria-hidden", "true" ); 17209 17210 submenu 17211 .show() 17212 .removeAttr( "aria-hidden" ) 17213 .attr( "aria-expanded", "true" ) 17214 .position( position ); 17215 }, 17216 17217 collapseAll: function( event, all ) { 17218 clearTimeout( this.timer ); 17219 this.timer = this._delay( function() { 17220
vendor: 5,398 bytes, lines 17221-17421
17221 // If we were passed an event, look for the submenu that contains the event 17222 var currentMenu = all ? this.element : 17223 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 17224 17225 // If we found no valid submenu ancestor, use the main menu to close all 17226 // sub menus anyway 17227 if ( !currentMenu.length ) { 17228 currentMenu = this.element; 17229 } 17230 17231 this._close( currentMenu ); 17232 17233 this.blur( event ); 17234 17235 // Work around active item staying active after menu is blurred 17236 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 17237 17238 this.activeMenu = currentMenu; 17239 }, all ? 0 : this.delay ); 17240 }, 17241 17242 // With no arguments, closes the currently active menu - if nothing is active 17243 // it closes all menus. If passed an argument, it will search for menus BELOW 17244 _close: function( startMenu ) { 17245 if ( !startMenu ) { 17246 startMenu = this.active ? this.active.parent() : this.element; 17247 } 17248 17249 startMenu.find( ".ui-menu" ) 17250 .hide() 17251 .attr( "aria-hidden", "true" ) 17252 .attr( "aria-expanded", "false" ); 17253 }, 17254 17255 _closeOnDocumentClick: function( event ) { 17256 return !$( event.target ).closest( ".ui-menu" ).length; 17257 }, 17258 17259 _isDivider: function( item ) { 17260 17261 // Match hyphen, em dash, en dash 17262 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 17263 }, 17264 17265 collapse: function( event ) { 17266 var newItem = this.active && 17267 this.active.parent().closest( ".ui-menu-item", this.element ); 17268 if ( newItem && newItem.length ) { 17269 this._close(); 17270 this.focus( event, newItem ); 17271 } 17272 }, 17273 17274 expand: function( event ) { 17275 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 17276 17277 if ( newItem && newItem.length ) { 17278 this._open( newItem.parent() ); 17279 17280 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 17281 this._delay( function() { 17282 this.focus( event, newItem ); 17283 } ); 17284 } 17285 }, 17286 17287 next: function( event ) { 17288 this._move( "next", "first", event ); 17289 }, 17290 17291 previous: function( event ) { 17292 this._move( "prev", "last", event ); 17293 }, 17294 17295 isFirstItem: function() { 17296 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 17297 }, 17298 17299 isLastItem: function() { 17300 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 17301 }, 17302 17303 _menuItems: function( menu ) { 17304 return ( menu || this.element ) 17305 .find( this.options.items ) 17306 .filter( ".ui-menu-item" ); 17307 }, 17308 17309 _move: function( direction, filter, event ) { 17310 var next; 17311 if ( this.active ) { 17312 if ( direction === "first" || direction === "last" ) { 17313 next = this.active 17314 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 17315 .last(); 17316 } else { 17317 next = this.active 17318 [ direction + "All" ]( ".ui-menu-item" ) 17319 .first(); 17320 } 17321 } 17322 if ( !next || !next.length || !this.active ) { 17323 next = this._menuItems( this.activeMenu )[ filter ](); 17324 } 17325 17326 this.focus( event, next ); 17327 }, 17328 17329 nextPage: function( event ) { 17330 var item, base, height; 17331 17332 if ( !this.active ) { 17333 this.next( event ); 17334 return; 17335 } 17336 if ( this.isLastItem() ) { 17337 return; 17338 } 17339 if ( this._hasScroll() ) { 17340 base = this.active.offset().top; 17341 height = this.element.innerHeight(); 17342 17343 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 17344 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 17345 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 17346 } 17347 17348 this.active.nextAll( ".ui-menu-item" ).each( function() { 17349 item = $( this ); 17350 return item.offset().top - base - height < 0; 17351 } ); 17352 17353 this.focus( event, item ); 17354 } else { 17355 this.focus( event, this._menuItems( this.activeMenu ) 17356 [ !this.active ? "first" : "last" ]() ); 17357 } 17358 }, 17359 17360 previousPage: function( event ) { 17361 var item, base, height; 17362 if ( !this.active ) { 17363 this.next( event ); 17364 return; 17365 } 17366 if ( this.isFirstItem() ) { 17367 return; 17368 } 17369 if ( this._hasScroll() ) { 17370 base = this.active.offset().top; 17371 height = this.element.innerHeight(); 17372 17373 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 17374 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 17375 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 17376 } 17377 17378 this.active.prevAll( ".ui-menu-item" ).each( function() { 17379 item = $( this ); 17380 return item.offset().top - base + height > 0; 17381 } ); 17382 17383 this.focus( event, item ); 17384 } else { 17385 this.focus( event, this._menuItems( this.activeMenu ).first() ); 17386 } 17387 }, 17388 17389 _hasScroll: function() { 17390 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 17391 }, 17392 17393 select: function( event ) { 17394 17395 // TODO: It should never be possible to not have an active item at this 17396 // point, but the tests don't trigger mouseenter before click. 17397 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 17398 var ui = { item: this.active }; 17399 if ( !this.active.has( ".ui-menu" ).length ) { 17400 this.collapseAll( event, true ); 17401 } 17402 this._trigger( "select", event, ui ); 17403 }, 17404 17405 _filterMenuItems: function( character ) { 17406 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 17407 regex = new RegExp( "^" + escapedCharacter, "i" ); 17408 17409 return this.activeMenu 17410 .find( this.options.items ) 17411 17412 // Only match on items, not dividers or other content (#10571) 17413 .filter( ".ui-menu-item" ) 17414 .filter( function() { 17415 return regex.test( 17416 String.prototype.trim.call( 17417 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 17418 } ); 17419 } 17420} ); 17421
17422} ); 17423 17424 17425 17426 17427 17428 17429 17430/*! 17431 * jQuery UI Autocomplete 1.13.0 17432 * http://jqueryui.com 17433 * 17434 * Copyright jQuery Foundation and other contributors 17435 * Released under the MIT license. 17436 * http://jquery.org/license 17437 */ 17438 17439//>>label: Autocomplete 17440//>>group: Widgets 17441//>>description: Lists suggested words as the user is typing. 17442//>>docs: http://api.jqueryui.com/autocomplete/ 17443//>>demos: http://jqueryui.com/autocomplete/ 17444//>>css.structure: ../../themes/base/core.css 17445//>>css.structure: ../../themes/base/autocomplete.css 17446//>>css.theme: ../../themes/base/theme.css 17447 17448( function( factory ) { 17449 "use strict"; 17450 17451 if ( typeof define === "function" && define.amd ) { 17452 17453 // AMD. Register as an anonymous module. 17454 define( [ 17455 "jquery", 17456 "./menu", 17457 "../keycode", 17458 "../position", 17459 "../safe-active-element", 17460 "../version", 17461 "../widget" 17462 ], factory ); 17463 } else { 17464 17465 // Browser globals 17466 factory( jQuery ); 17467 } 17468} )( function( $ ) { 17469"use strict"; 17470 17471$.widget( "ui.autocomplete", { 17472 version: "1.13.0", 17473 defaultElement: "<input>", 17474 options: { 17475 appendTo: null, 17476 autoFocus: false, 17477 delay: 300, 17478 minLength: 1, 17479 position: { 17480 my: "left top", 17481 at: "left bottom", 17482 collision: "none" 17483 }, 17484 source: null, 17485 17486 // Callbacks 17487 change: null, 17488 close: null, 17489 focus: null, 17490 open: null, 17491 response: null, 17492 search: null, 17493 select: null 17494 }, 17495 17496 requestIndex: 0, 17497 pending: 0
vendor: 5,947 bytes, lines 17497-17699
17497, 17498 17499 _create: function() { 17500 17501 // Some browsers only repeat keydown events, not keypress events, 17502 // so we use the suppressKeyPress flag to determine if we've already 17503 // handled the keydown event. #7269 17504 // Unfortunately the code for & in keypress is the same as the up arrow, 17505 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 17506 // events when we know the keydown event was used to modify the 17507 // search term. #7799 17508 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 17509 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 17510 isTextarea = nodeName === "textarea", 17511 isInput = nodeName === "input"; 17512 17513 // Textareas are always multi-line 17514 // Inputs are always single-line, even if inside a contentEditable element 17515 // IE also treats inputs as contentEditable 17516 // All other element types are determined by whether or not they're contentEditable 17517 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 17518 17519 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 17520 this.isNewMenu = true; 17521 17522 this._addClass( "ui-autocomplete-input" ); 17523 this.element.attr( "autocomplete", "off" ); 17524 17525 this._on( this.element, { 17526 keydown: function( event ) { 17527 if ( this.element.prop( "readOnly" ) ) { 17528 suppressKeyPress = true; 17529 suppressInput = true; 17530 suppressKeyPressRepeat = true; 17531 return; 17532 } 17533 17534 suppressKeyPress = false; 17535 suppressInput = false; 17536 suppressKeyPressRepeat = false; 17537 var keyCode = $.ui.keyCode; 17538 switch ( event.keyCode ) { 17539 case keyCode.PAGE_UP: 17540 suppressKeyPress = true; 17541 this._move( "previousPage", event ); 17542 break; 17543 case keyCode.PAGE_DOWN: 17544 suppressKeyPress = true; 17545 this._move( "nextPage", event ); 17546 break; 17547 case keyCode.UP: 17548 suppressKeyPress = true; 17549 this._keyEvent( "previous", event ); 17550 break; 17551 case keyCode.DOWN: 17552 suppressKeyPress = true; 17553 this._keyEvent( "next", event ); 17554 break; 17555 case keyCode.ENTER: 17556 17557 // when menu is open and has focus 17558 if ( this.menu.active ) { 17559 17560 // #6055 - Opera still allows the keypress to occur 17561 // which causes forms to submit 17562 suppressKeyPress = true; 17563 event.preventDefault(); 17564 this.menu.select( event ); 17565 } 17566 break; 17567 case keyCode.TAB: 17568 if ( this.menu.active ) { 17569 this.menu.select( event ); 17570 } 17571 break; 17572 case keyCode.ESCAPE: 17573 if ( this.menu.element.is( ":visible" ) ) { 17574 if ( !this.isMultiLine ) { 17575 this._value( this.term ); 17576 } 17577 this.close( event ); 17578 17579 // Different browsers have different default behavior for escape 17580 // Single press can mean undo or clear 17581 // Double press in IE means clear the whole form 17582 event.preventDefault(); 17583 } 17584 break; 17585 default: 17586 suppressKeyPressRepeat = true; 17587 17588 // search timeout should be triggered before the input value is changed 17589 this._searchTimeout( event ); 17590 break; 17591 } 17592 }, 17593 keypress: function( event ) { 17594 if ( suppressKeyPress ) { 17595 suppressKeyPress = false; 17596 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 17597 event.preventDefault(); 17598 } 17599 return; 17600 } 17601 if ( suppressKeyPressRepeat ) { 17602 return; 17603 } 17604 17605 // Replicate some key handlers to allow them to repeat in Firefox and Opera 17606 var keyCode = $.ui.keyCode; 17607 switch ( event.keyCode ) { 17608 case keyCode.PAGE_UP: 17609 this._move( "previousPage", event ); 17610 break; 17611 case keyCode.PAGE_DOWN: 17612 this._move( "nextPage", event ); 17613 break; 17614 case keyCode.UP: 17615 this._keyEvent( "previous", event ); 17616 break; 17617 case keyCode.DOWN: 17618 this._keyEvent( "next", event ); 17619 break; 17620 } 17621 }, 17622 input: function( event ) { 17623 if ( suppressInput ) { 17624 suppressInput = false; 17625 event.preventDefault(); 17626 return; 17627 } 17628 this._searchTimeout( event ); 17629 }, 17630 focus: function() { 17631 this.selectedItem = null; 17632 this.previous = this._value(); 17633 }, 17634 blur: function( event ) { 17635 clearTimeout( this.searching ); 17636 this.close( event ); 17637 this._change( event ); 17638 } 17639 } ); 17640 17641 this._initSource(); 17642 this.menu = $( "<ul>" ) 17643 .appendTo( this._appendTo() ) 17644 .menu( { 17645 17646 // disable ARIA support, the live region takes care of that 17647 role: null 17648 } ) 17649 .hide() 17650 17651 // Support: IE 11 only, Edge <= 14 17652 // For other browsers, we preventDefault() on the mousedown event 17653 // to keep the dropdown from taking focus from the input. This doesn't 17654 // work for IE/Edge, causing problems with selection and scrolling (#9638) 17655 // Happily, IE and Edge support an "unselectable" attribute that 17656 // prevents an element from receiving focus, exactly what we want here. 17657 .attr( { 17658 "unselectable": "on" 17659 } ) 17660 .menu( "instance" ); 17661 17662 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 17663 this._on( this.menu.element, { 17664 mousedown: function( event ) { 17665 17666 // Prevent moving focus out of the text field 17667 event.preventDefault(); 17668 }, 17669 menufocus: function( event, ui ) { 17670 var label, item; 17671 17672 // support: Firefox 17673 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 17674 if ( this.isNewMenu ) { 17675 this.isNewMenu = false; 17676 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 17677 this.menu.blur(); 17678 17679 this.document.one( "mousemove", function() { 17680 $( event.target ).trigger( event.originalEvent ); 17681 } ); 17682 17683 return; 17684 } 17685 } 17686 17687 item = ui.item.data( "ui-autocomplete-item" ); 17688 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 17689 17690 // use value to match what will end up in the input, if it was a key event 17691 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 17692 this._value( item.value ); 17693 } 17694 } 17695 17696 // Announce the value in the liveRegion 17697 label = ui.item.attr( "aria-label" ) || item.value; 17698 if ( label && String.prototype.trim.call( label ).length ) { 17699
17699this.liveRegion.children().hide(); 17700 $( "<div>" ).text( label ).appendTo( this.liveRegion
vendor: 9,873 bytes, lines 17700-18095
17700 ); 17701 } 17702 }, 17703 menuselect: function( event, ui ) { 17704 var item = ui.item.data( "ui-autocomplete-item" ), 17705 previous = this.previous; 17706 17707 // Only trigger when focus was lost (click on menu) 17708 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 17709 this.element.trigger( "focus" ); 17710 this.previous = previous; 17711 17712 // #6109 - IE triggers two focus events and the second 17713 // is asynchronous, so we need to reset the previous 17714 // term synchronously and asynchronously :-( 17715 this._delay( function() { 17716 this.previous = previous; 17717 this.selectedItem = item; 17718 } ); 17719 } 17720 17721 if ( false !== this._trigger( "select", event, { item: item } ) ) { 17722 this._value( item.value ); 17723 } 17724 17725 // reset the term after the select event 17726 // this allows custom select handling to work properly 17727 this.term = this._value(); 17728 17729 this.close( event ); 17730 this.selectedItem = item; 17731 } 17732 } ); 17733 17734 this.liveRegion = $( "<div>", { 17735 role: "status", 17736 "aria-live": "assertive", 17737 "aria-relevant": "additions" 17738 } ) 17739 .appendTo( this.document[ 0 ].body ); 17740 17741 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 17742 17743 // Turning off autocomplete prevents the browser from remembering the 17744 // value when navigating through history, so we re-enable autocomplete 17745 // if the page is unloaded before the widget is destroyed. #7790 17746 this._on( this.window, { 17747 beforeunload: function() { 17748 this.element.removeAttr( "autocomplete" ); 17749 } 17750 } ); 17751 }, 17752 17753 _destroy: function() { 17754 clearTimeout( this.searching ); 17755 this.element.removeAttr( "autocomplete" ); 17756 this.menu.element.remove(); 17757 this.liveRegion.remove(); 17758 }, 17759 17760 _setOption: function( key, value ) { 17761 this._super( key, value ); 17762 if ( key === "source" ) { 17763 this._initSource(); 17764 } 17765 if ( key === "appendTo" ) { 17766 this.menu.element.appendTo( this._appendTo() ); 17767 } 17768 if ( key === "disabled" && value && this.xhr ) { 17769 this.xhr.abort(); 17770 } 17771 }, 17772 17773 _isEventTargetInWidget: function( event ) { 17774 var menuElement = this.menu.element[ 0 ]; 17775 17776 return event.target === this.element[ 0 ] || 17777 event.target === menuElement || 17778 $.contains( menuElement, event.target ); 17779 }, 17780 17781 _closeOnClickOutside: function( event ) { 17782 if ( !this._isEventTargetInWidget( event ) ) { 17783 this.close(); 17784 } 17785 }, 17786 17787 _appendTo: function() { 17788 var element = this.options.appendTo; 17789 17790 if ( element ) { 17791 element = element.jquery || element.nodeType ? 17792 $( element ) : 17793 this.document.find( element ).eq( 0 ); 17794 } 17795 17796 if ( !element || !element[ 0 ] ) { 17797 element = this.element.closest( ".ui-front, dialog" ); 17798 } 17799 17800 if ( !element.length ) { 17801 element = this.document[ 0 ].body; 17802 } 17803 17804 return element; 17805 }, 17806 17807 _initSource: function() { 17808 var array, url, 17809 that = this; 17810 if ( Array.isArray( this.options.source ) ) { 17811 array = this.options.source; 17812 this.source = function( request, response ) { 17813 response( $.ui.autocomplete.filter( array, request.term ) ); 17814 }; 17815 } else if ( typeof this.options.source === "string" ) { 17816 url = this.options.source; 17817 this.source = function( request, response ) { 17818 if ( that.xhr ) { 17819 that.xhr.abort(); 17820 } 17821 that.xhr = $.ajax( { 17822 url: url, 17823 data: request, 17824 dataType: "json", 17825 success: function( data ) { 17826 response( data ); 17827 }, 17828 error: function() { 17829 response( [] ); 17830 } 17831 } ); 17832 }; 17833 } else { 17834 this.source = this.options.source; 17835 } 17836 }, 17837 17838 _searchTimeout: function( event ) { 17839 clearTimeout( this.searching ); 17840 this.searching = this._delay( function() { 17841 17842 // Search if the value has changed, or if the user retypes the same value (see #7434) 17843 var equalValues = this.term === this._value(), 17844 menuVisible = this.menu.element.is( ":visible" ), 17845 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 17846 17847 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 17848 this.selectedItem = null; 17849 this.search( null, event ); 17850 } 17851 }, this.options.delay ); 17852 }, 17853 17854 search: function( value, event ) { 17855 value = value != null ? value : this._value(); 17856 17857 // Always save the actual value, not the one passed as an argument 17858 this.term = this._value(); 17859 17860 if ( value.length < this.options.minLength ) { 17861 return this.close( event ); 17862 } 17863 17864 if ( this._trigger( "search", event ) === false ) { 17865 return; 17866 } 17867 17868 return this._search( value ); 17869 }, 17870 17871 _search: function( value ) { 17872 this.pending++; 17873 this._addClass( "ui-autocomplete-loading" ); 17874 this.cancelSearch = false; 17875 17876 this.source( { term: value }, this._response() ); 17877 }, 17878 17879 _response: function() { 17880 var index = ++this.requestIndex; 17881 17882 return function( content ) { 17883 if ( index === this.requestIndex ) { 17884 this.__response( content ); 17885 } 17886 17887 this.pending--; 17888 if ( !this.pending ) { 17889 this._removeClass( "ui-autocomplete-loading" ); 17890 } 17891 }.bind( this ); 17892 }, 17893 17894 __response: function( content ) { 17895 if ( content ) { 17896 content = this._normalize( content ); 17897 } 17898 this._trigger( "response", null, { content: content } ); 17899 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 17900 this._suggest( content ); 17901 this._trigger( "open" ); 17902 } else { 17903 17904 // use ._close() instead of .close() so we don't cancel future searches 17905 this._close(); 17906 } 17907 }, 17908 17909 close: function( event ) { 17910 this.cancelSearch = true; 17911 this._close( event ); 17912 }, 17913 17914 _close: function( event ) { 17915 17916 // Remove the handler that closes the menu on outside clicks 17917 this._off( this.document, "mousedown" ); 17918 17919 if ( this.menu.element.is( ":visible" ) ) { 17920 this.menu.element.hide(); 17921 this.menu.blur(); 17922 this.isNewMenu = true; 17923 this._trigger( "close", event ); 17924 } 17925 }, 17926 17927 _change: function( event ) { 17928 if ( this.previous !== this._value() ) { 17929 this._trigger( "change", event, { item: this.selectedItem } ); 17930 } 17931 }, 17932 17933 _normalize: function( items ) { 17934 17935 // assume all items have the right format when the first item is complete 17936 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 17937 return items; 17938 } 17939 return $.map( items, function( item ) { 17940 if ( typeof item === "string" ) { 17941 return { 17942 label: item, 17943 value: item 17944 }; 17945 } 17946 return $.extend( {}, item, { 17947 label: item.label || item.value, 17948 value: item.value || item.label 17949 } ); 17950 } ); 17951 }, 17952 17953 _suggest: function( items ) { 17954 var ul = this.menu.element.empty(); 17955 this._renderMenu( ul, items ); 17956 this.isNewMenu = true; 17957 this.menu.refresh(); 17958 17959 // Size and position menu 17960 ul.show(); 17961 this._resizeMenu(); 17962 ul.position( $.extend( { 17963 of: this.element 17964 }, this.options.position ) ); 17965 17966 if ( this.options.autoFocus ) { 17967 this.menu.next(); 17968 } 17969 17970 // Listen for interactions outside of the widget (#6642) 17971 this._on( this.document, { 17972 mousedown: "_closeOnClickOutside" 17973 } ); 17974 }, 17975 17976 _resizeMenu: function() { 17977 var ul = this.menu.element; 17978 ul.outerWidth( Math.max( 17979 17980 // Firefox wraps long text (possibly a rounding bug) 17981 // so we add 1px to avoid the wrapping (#7513) 17982 ul.width( "" ).outerWidth() + 1, 17983 this.element.outerWidth() 17984 ) ); 17985 }, 17986 17987 _renderMenu: function( ul, items ) { 17988 var that = this; 17989 $.each( items, function( index, item ) { 17990 that._renderItemData( ul, item ); 17991 } ); 17992 }, 17993 17994 _renderItemData: function( ul, item ) { 17995 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 17996 }, 17997 17998 _renderItem: function( ul, item ) { 17999 return $( "<li>" ) 18000 .append( $( "<div>" ).text( item.label ) ) 18001 .appendTo( ul ); 18002 }, 18003 18004 _move: function( direction, event ) { 18005 if ( !this.menu.element.is( ":visible" ) ) { 18006 this.search( null, event ); 18007 return; 18008 } 18009 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 18010 this.menu.isLastItem() && /^next/.test( direction ) ) { 18011 18012 if ( !this.isMultiLine ) { 18013 this._value( this.term ); 18014 } 18015 18016 this.menu.blur(); 18017 return; 18018 } 18019 this.menu[ direction ]( event ); 18020 }, 18021 18022 widget: function() { 18023 return this.menu.element; 18024 }, 18025 18026 _value: function() { 18027 return this.valueMethod.apply( this.element, arguments ); 18028 }, 18029 18030 _keyEvent: function( keyEvent, event ) { 18031 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 18032 this._move( keyEvent, event ); 18033 18034 // Prevents moving cursor to beginning/end of the text field in some browsers 18035 event.preventDefault(); 18036 } 18037 }, 18038 18039 // Support: Chrome <=50 18040 // We should be able to just use this.element.prop( "isContentEditable" ) 18041 // but hidden elements always report false in Chrome. 18042 // https://code.google.com/p/chromium/issues/detail?id=313082 18043 _isContentEditable: function( element ) { 18044 if ( !element.length ) { 18045 return false; 18046 } 18047 18048 var editable = element.prop( "contentEditable" ); 18049 18050 if ( editable === "inherit" ) { 18051 return this._isContentEditable( element.parent() ); 18052 } 18053 18054 return editable === "true"; 18055 } 18056} ); 18057 18058$.extend( $.ui.autocomplete, { 18059 escapeRegex: function( value ) { 18060 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 18061 }, 18062 filter: function( array, term ) { 18063 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 18064 return $.grep( array, function( value ) { 18065 return matcher.test( value.label || value.value || value ); 18066 } ); 18067 } 18068} ); 18069 18070// Live region extension, adding a `messages` option 18071// NOTE: This is an experimental API. We are still investigating 18072// a full solution for string manipulation and internationalization. 18073$.widget( "ui.autocomplete", $.ui.autocomplete, { 18074 options: { 18075 messages: { 18076 noResults: "No search results.", 18077 results: function( amount ) { 18078 return amount + ( amount > 1 ? " results are" : " result is" ) + 18079 " available, use up and down arrow keys to navigate."; 18080 } 18081 } 18082 }, 18083 18084 __response: function( content ) { 18085 var message; 18086 this._superApply( arguments ); 18087 if ( this.options.disabled || this.cancelSearch ) { 18088 return; 18089 } 18090 if ( content && content.length ) { 18091 message = this.options.messages.results( content.length ); 18092 } else { 18093 message = this.options.messages.noResults; 18094 } 18095
18095this.liveRegion.children().hide(); 18096 $( "<div>" ).text( message ).appendTo( this.liveRegion ); 18097 } 18098} ); 18099 18100return $.ui.autocomplete; 18101 18102} ); 18103 18104 18105/*! 18106 * jQuery UI Controlgroup 1.13.0 18107 * http://jqueryui.com 18108 * 18109 * Copyright jQuery Foundation and other contributors 18110 * Released under the MIT license. 18111 * http://jquery.org/license 18112 */ 18113 18114//>>label: Controlgroup 18115//>>group: Widgets 18116//>>description: Visually groups form control widgets 18117//>>docs: http://api.jqueryui.com/controlgroup/ 18118//>>demos: http://jqueryui.com/controlgroup/ 18119//>>css.structure: ../../themes/base/core.css 18120//>>css.structure: ../../themes/base/controlgroup.css 18121//>>css.theme: ../../themes/base/theme.css 18122 18123( function( factory ) { 18124 "use strict"; 18125 18126 if ( typeof define === "function" && define.amd ) { 18127 18128 // AMD. Register as an anonymous module. 18129 define( [ 18130 "jquery", 18131 "../widget" 18132 ], factory ); 18133 } else { 18134 18135 // Browser globals 18136 factory( jQuery ); 18137 } 18138} )( function( $ ) { 18139"use strict"; 18140 18141var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 18142 18143return $.widget( "ui.controlgroup", { 18144 version: "1.13.0
vendor: 7,699 bytes, lines 18144-18405
18144", 18145 defaultElement: "<div>", 18146 options: { 18147 direction: "horizontal", 18148 disabled: null, 18149 onlyVisible: true, 18150 items: { 18151 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 18152 "controlgroupLabel": ".ui-controlgroup-label", 18153 "checkboxradio": "input[type='checkbox'], input[type='radio']", 18154 "selectmenu": "select", 18155 "spinner": ".ui-spinner-input" 18156 } 18157 }, 18158 18159 _create: function() { 18160 this._enhance(); 18161 }, 18162 18163 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 18164 _enhance: function() { 18165 this.element.attr( "role", "toolbar" ); 18166 this.refresh(); 18167 }, 18168 18169 _destroy: function() { 18170 this._callChildMethod( "destroy" ); 18171 this.childWidgets.removeData( "ui-controlgroup-data" ); 18172 this.element.removeAttr( "role" ); 18173 if ( this.options.items.controlgroupLabel ) { 18174 this.element 18175 .find( this.options.items.controlgroupLabel ) 18176 .find( ".ui-controlgroup-label-contents" ) 18177 .contents().unwrap(); 18178 } 18179 }, 18180 18181 _initWidgets: function() { 18182 var that = this, 18183 childWidgets = []; 18184 18185 // First we iterate over each of the items options 18186 $.each( this.options.items, function( widget, selector ) { 18187 var labels; 18188 var options = {}; 18189 18190 // Make sure the widget has a selector set 18191 if ( !selector ) { 18192 return; 18193 } 18194 18195 if ( widget === "controlgroupLabel" ) { 18196 labels = that.element.find( selector ); 18197 labels.each( function() { 18198 var element = $( this ); 18199 18200 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 18201 return; 18202 } 18203 element.contents() 18204 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 18205 } ); 18206 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 18207 childWidgets = childWidgets.concat( labels.get() ); 18208 return; 18209 } 18210 18211 // Make sure the widget actually exists 18212 if ( !$.fn[ widget ] ) { 18213 return; 18214 } 18215 18216 // We assume everything is in the middle to start because we can't determine 18217 // first / last elements until all enhancments are done. 18218 if ( that[ "_" + widget + "Options" ] ) { 18219 options = that[ "_" + widget + "Options" ]( "middle" ); 18220 } else { 18221 options = { classes: {} }; 18222 } 18223 18224 // Find instances of this widget inside controlgroup and init them 18225 that.element 18226 .find( selector ) 18227 .each( function() { 18228 var element = $( this ); 18229 var instance = element[ widget ]( "instance" ); 18230 18231 // We need to clone the default options for this type of widget to avoid 18232 // polluting the variable options which has a wider scope than a single widget. 18233 var instanceOptions = $.widget.extend( {}, options ); 18234 18235 // If the button is the child of a spinner ignore it 18236 // TODO: Find a more generic solution 18237 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 18238 return; 18239 } 18240 18241 // Create the widget if it doesn't exist 18242 if ( !instance ) { 18243 instance = element[ widget ]()[ widget ]( "instance" ); 18244 } 18245 if ( instance ) { 18246 instanceOptions.classes = 18247 that._resolveClassesValues( instanceOptions.classes, instance ); 18248 } 18249 element[ widget ]( instanceOptions ); 18250 18251 // Store an instance of the controlgroup to be able to reference 18252 // from the outermost element for changing options and refresh 18253 var widgetElement = element[ widget ]( "widget" ); 18254 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 18255 instance ? instance : element[ widget ]( "instance" ) ); 18256 18257 childWidgets.push( widgetElement[ 0 ] ); 18258 } ); 18259 } ); 18260 18261 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 18262 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 18263 }, 18264 18265 _callChildMethod: function( method ) { 18266 this.childWidgets.each( function() { 18267 var element = $( this ), 18268 data = element.data( "ui-controlgroup-data" ); 18269 if ( data && data[ method ] ) { 18270 data[ method ](); 18271 } 18272 } ); 18273 }, 18274 18275 _updateCornerClass: function( element, position ) { 18276 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 18277 var add = this._buildSimpleOptions( position, "label" ).classes.label; 18278 18279 this._removeClass( element, null, remove ); 18280 this._addClass( element, null, add ); 18281 }, 18282 18283 _buildSimpleOptions: function( position, key ) { 18284 var direction = this.options.direction === "vertical"; 18285 var result = { 18286 classes: {} 18287 }; 18288 result.classes[ key ] = { 18289 "middle": "", 18290 "first": "ui-corner-" + ( direction ? "top" : "left" ), 18291 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 18292 "only": "ui-corner-all" 18293 }[ position ]; 18294 18295 return result; 18296 }, 18297 18298 _spinnerOptions: function( position ) { 18299 var options = this._buildSimpleOptions( position, "ui-spinner" ); 18300 18301 options.classes[ "ui-spinner-up" ] = ""; 18302 options.classes[ "ui-spinner-down" ] = ""; 18303 18304 return options; 18305 }, 18306 18307 _buttonOptions: function( position ) { 18308 return this._buildSimpleOptions( position, "ui-button" ); 18309 }, 18310 18311 _checkboxradioOptions: function( position ) { 18312 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 18313 }, 18314 18315 _selectmenuOptions: function( position ) { 18316 var direction = this.options.direction === "vertical"; 18317 return { 18318 width: direction ? "auto" : false, 18319 classes: { 18320 middle: { 18321 "ui-selectmenu-button-open": "", 18322 "ui-selectmenu-button-closed": "" 18323 }, 18324 first: { 18325 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 18326 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 18327 }, 18328 last: { 18329 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 18330 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 18331 }, 18332 only: { 18333 "ui-selectmenu-button-open": "ui-corner-top", 18334 "ui-selectmenu-button-closed": "ui-corner-all" 18335 } 18336 18337 }[ position ] 18338 }; 18339 }, 18340 18341 _resolveClassesValues: function( classes, instance ) { 18342 var result = {}; 18343 $.each( classes, function( key ) { 18344 var current = instance.options.classes[ key ] || ""; 18345 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 18346 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 18347 } ); 18348 return result; 18349 }, 18350 18351 _setOption: function( key, value ) { 18352 if ( key === "direction" ) { 18353 this._removeClass( "ui-controlgroup-" + this.options.direction ); 18354 } 18355 18356 this._super( key, value ); 18357 if ( key === "disabled" ) { 18358 this._callChildMethod( value ? "disable" : "enable" ); 18359 return; 18360 } 18361 18362 this.refresh(); 18363 }, 18364 18365 refresh: function() { 18366 var children, 18367 that = this; 18368 18369 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 18370 18371 if ( this.options.direction === "horizontal" ) { 18372 this._addClass( null, "ui-helper-clearfix" ); 18373 } 18374 this._initWidgets(); 18375 18376 children = this.childWidgets; 18377 18378 // We filter here because we need to track all childWidgets not just the visible ones 18379 if ( this.options.onlyVisible ) { 18380 children = children.filter( ":visible" ); 18381 } 18382 18383 if ( children.length ) { 18384 18385 // We do this last because we need to make sure all enhancment is done 18386 // before determining first and last 18387 $.each( [ "first", "last" ], function( index, value ) { 18388 var instance = children[ value ]().data( "ui-controlgroup-data" ); 18389 18390 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 18391 var options = that[ "_" + instance.widgetName + "Options" ]( 18392 children.length === 1 ? "only" : value 18393 ); 18394 options.classes = that._resolveClassesValues( options.classes, instance ); 18395 instance.element[ instance.widgetName ]( options ); 18396 } else { 18397 that._updateCornerClass( children[ value ](), value ); 18398 } 18399 } ); 18400 18401 // Finally call the refresh method on each of the child widgets. 18402 this._callChildMethod( "refresh" ); 18403 } 18404 } 18405} );
vendor: 5,352 bytes, lines 18406-18609
18406} ); 18407 18408 18409 18410 18411/*! 18412 * jQuery UI Checkboxradio 1.13.0 18413 * http://jqueryui.com 18414 * 18415 * Copyright jQuery Foundation and other contributors 18416 * Released under the MIT license. 18417 * http://jquery.org/license 18418 */ 18419 18420//>>label: Checkboxradio 18421//>>group: Widgets 18422//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 18423//>>docs: http://api.jqueryui.com/checkboxradio/ 18424//>>demos: http://jqueryui.com/checkboxradio/ 18425//>>css.structure: ../../themes/base/core.css 18426//>>css.structure: ../../themes/base/button.css 18427//>>css.structure: ../../themes/base/checkboxradio.css 18428//>>css.theme: ../../themes/base/theme.css 18429 18430( function( factory ) { 18431 "use strict"; 18432 18433 if ( typeof define === "function" && define.amd ) { 18434 18435 // AMD. Register as an anonymous module. 18436 define( [ 18437 "jquery", 18438 "../form-reset-mixin", 18439 "../labels", 18440 "../widget" 18441 ], factory ); 18442 } else { 18443 18444 // Browser globals 18445 factory( jQuery ); 18446 } 18447} )( function( $ ) { 18448"use strict"; 18449 18450$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 18451 version: "1.13.0", 18452 options: { 18453 disabled: null, 18454 label: null, 18455 icon: true, 18456 classes: { 18457 "ui-checkboxradio-label": "ui-corner-all", 18458 "ui-checkboxradio-icon": "ui-corner-all" 18459 } 18460 }, 18461 18462 _getCreateOptions: function() { 18463 var disabled, labels; 18464 var that = this; 18465 var options = this._super() || {}; 18466 18467 // We read the type here, because it makes more sense to throw a element type error first, 18468 // rather then the error for lack of a label. Often if its the wrong type, it 18469 // won't have a label (e.g. calling on a div, btn, etc) 18470 this._readType(); 18471 18472 labels = this.element.labels(); 18473 18474 // If there are multiple labels, use the last one 18475 this.label = $( labels[ labels.length - 1 ] ); 18476 if ( !this.label.length ) { 18477 $.error( "No label found for checkboxradio widget" ); 18478 } 18479 18480 this.originalLabel = ""; 18481 18482 // We need to get the label text but this may also need to make sure it does not contain the 18483 // input itself. 18484 this.label.contents().not( this.element[ 0 ] ).each( function() { 18485 18486 // The label contents could be text, html, or a mix. We concat each element to get a 18487 // string representation of the label, without the input as part of it. 18488 that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; 18489 } ); 18490 18491 // Set the label option if we found label text 18492 if ( this.originalLabel ) { 18493 options.label = this.originalLabel; 18494 } 18495 18496 disabled = this.element[ 0 ].disabled; 18497 if ( disabled != null ) { 18498 options.disabled = disabled; 18499 } 18500 return options; 18501 }, 18502 18503 _create: function() { 18504 var checked = this.element[ 0 ].checked; 18505 18506 this._bindFormResetHandler(); 18507 18508 if ( this.options.disabled == null ) { 18509 this.options.disabled = this.element[ 0 ].disabled; 18510 } 18511 18512 this._setOption( "disabled", this.options.disabled ); 18513 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 18514 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 18515 18516 if ( this.type === "radio" ) { 18517 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 18518 } 18519 18520 if ( this.options.label && this.options.label !== this.originalLabel ) { 18521 this._updateLabel(); 18522 } else if ( this.originalLabel ) { 18523 this.options.label = this.originalLabel; 18524 } 18525 18526 this._enhance(); 18527 18528 if ( checked ) { 18529 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 18530 } 18531 18532 this._on( { 18533 change: "_toggleClasses", 18534 focus: function() { 18535 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 18536 }, 18537 blur: function() { 18538 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 18539 } 18540 } ); 18541 }, 18542 18543 _readType: function() { 18544 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 18545 this.type = this.element[ 0 ].type; 18546 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 18547 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 18548 " and element.type=" + this.type ); 18549 } 18550 }, 18551 18552 // Support jQuery Mobile enhanced option 18553 _enhance: function() { 18554 this._updateIcon( this.element[ 0 ].checked ); 18555 }, 18556 18557 widget: function() { 18558 return this.label; 18559 }, 18560 18561 _getRadioGroup: function() { 18562 var group; 18563 var name = this.element[ 0 ].name; 18564 var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; 18565 18566 if ( !name ) { 18567 return $( [] ); 18568 } 18569 18570 if ( this.form.length ) { 18571 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 18572 } else { 18573 18574 // Not inside a form, check all inputs that also are not inside a form 18575 group = $( nameSelector ).filter( function() { 18576 return $( this )._form().length === 0; 18577 } ); 18578 } 18579 18580 return group.not( this.element ); 18581 }, 18582 18583 _toggleClasses: function() { 18584 var checked = this.element[ 0 ].checked; 18585 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 18586 18587 if ( this.options.icon && this.type === "checkbox" ) { 18588 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 18589 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 18590 } 18591 18592 if ( this.type === "radio" ) { 18593 this._getRadioGroup() 18594 .each( function() { 18595 var instance = $( this ).checkboxradio( "instance" ); 18596 18597 if ( instance ) { 18598 instance._removeClass( instance.label, 18599 "ui-checkboxradio-checked", "ui-state-active" ); 18600 } 18601 } ); 18602 } 18603 }, 18604 18605 _destroy: function() { 18606 this._unbindFormResetHandler(); 18607 18608 if ( this.icon ) { 18609 this.icon.remove();
vendor: 3,109 bytes, lines 18610-18745
18610 this.iconSpace.remove(); 18611 } 18612 }, 18613 18614 _setOption: function( key, value ) { 18615 18616 // We don't allow the value to be set to nothing 18617 if ( key === "label" && !value ) { 18618 return; 18619 } 18620 18621 this._super( key, value ); 18622 18623 if ( key === "disabled" ) { 18624 this._toggleClass( this.label, null, "ui-state-disabled", value ); 18625 this.element[ 0 ].disabled = value; 18626 18627 // Don't refresh when setting disabled 18628 return; 18629 } 18630 this.refresh(); 18631 }, 18632 18633 _updateIcon: function( checked ) { 18634 var toAdd = "ui-icon ui-icon-background "; 18635 18636 if ( this.options.icon ) { 18637 if ( !this.icon ) { 18638 this.icon = $( "<span>" ); 18639 this.iconSpace = $( "<span> </span>" ); 18640 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 18641 } 18642 18643 if ( this.type === "checkbox" ) { 18644 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 18645 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 18646 } else { 18647 toAdd += "ui-icon-blank"; 18648 } 18649 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 18650 if ( !checked ) { 18651 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 18652 } 18653 this.icon.prependTo( this.label ).after( this.iconSpace ); 18654 } else if ( this.icon !== undefined ) { 18655 this.icon.remove(); 18656 this.iconSpace.remove(); 18657 delete this.icon; 18658 } 18659 }, 18660 18661 _updateLabel: function() { 18662 18663 // Remove the contents of the label ( minus the icon, icon space, and input ) 18664 var contents = this.label.contents().not( this.element[ 0 ] ); 18665 if ( this.icon ) { 18666 contents = contents.not( this.icon[ 0 ] ); 18667 } 18668 if ( this.iconSpace ) { 18669 contents = contents.not( this.iconSpace[ 0 ] ); 18670 } 18671 contents.remove(); 18672 18673 this.label.append( this.options.label ); 18674 }, 18675 18676 refresh: function() { 18677 var checked = this.element[ 0 ].checked, 18678 isDisabled = this.element[ 0 ].disabled; 18679 18680 this._updateIcon( checked ); 18681 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 18682 if ( this.options.label !== null ) { 18683 this._updateLabel(); 18684 } 18685 18686 if ( isDisabled !== this.options.disabled ) { 18687 this._setOptions( { "disabled": isDisabled } ); 18688 } 18689 } 18690 18691} ] ); 18692 18693return $.ui.checkboxradio; 18694 18695} ); 18696 18697 18698 18699 18700 18701/*! 18702 * jQuery UI Button 1.13.0 18703 * http://jqueryui.com 18704 * 18705 * Copyright jQuery Foundation and other contributors 18706 * Released under the MIT license. 18707 * http://jquery.org/license 18708 */ 18709 18710//>>label: Button 18711//>>group: Widgets 18712//>>description: Enhances a form with themeable buttons. 18713//>>docs: http://api.jqueryui.com/button/ 18714//>>demos: http://jqueryui.com/button/ 18715//>>css.structure: ../../themes/base/core.css 18716//>>css.structure: ../../themes/base/button.css 18717//>>css.theme: ../../themes/base/theme.css 18718 18719( function( factory ) { 18720 "use strict"; 18721 18722 if ( typeof define === "function" && define.amd ) { 18723 18724 // AMD. Register as an anonymous module. 18725 define( [ 18726 "jquery", 18727 18728 // These are only for backcompat 18729 // TODO: Remove after 1.12 18730 "./controlgroup", 18731 "./checkboxradio", 18732 18733 "../keycode", 18734 "../widget" 18735 ], factory ); 18736 } else { 18737 18738 // Browser globals 18739 factory( jQuery ); 18740 } 18741} )( function( $ ) { 18742"use strict"; 18743 18744$.widget( "ui.button", { 18745 version: "1.13.0
vendor: 10,728 bytes, lines 18745-19146
18745", 18746 defaultElement: "<button>", 18747 options: { 18748 classes: { 18749 "ui-button": "ui-corner-all" 18750 }, 18751 disabled: null, 18752 icon: null, 18753 iconPosition: "beginning", 18754 label: null, 18755 showLabel: true 18756 }, 18757 18758 _getCreateOptions: function() { 18759 var disabled, 18760 18761 // This is to support cases like in jQuery Mobile where the base widget does have 18762 // an implementation of _getCreateOptions 18763 options = this._super() || {}; 18764 18765 this.isInput = this.element.is( "input" ); 18766 18767 disabled = this.element[ 0 ].disabled; 18768 if ( disabled != null ) { 18769 options.disabled = disabled; 18770 } 18771 18772 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 18773 if ( this.originalLabel ) { 18774 options.label = this.originalLabel; 18775 } 18776 18777 return options; 18778 }, 18779 18780 _create: function() { 18781 if ( !this.option.showLabel & !this.options.icon ) { 18782 this.options.showLabel = true; 18783 } 18784 18785 // We have to check the option again here even though we did in _getCreateOptions, 18786 // because null may have been passed on init which would override what was set in 18787 // _getCreateOptions 18788 if ( this.options.disabled == null ) { 18789 this.options.disabled = this.element[ 0 ].disabled || false; 18790 } 18791 18792 this.hasTitle = !!this.element.attr( "title" ); 18793 18794 // Check to see if the label needs to be set or if its already correct 18795 if ( this.options.label && this.options.label !== this.originalLabel ) { 18796 if ( this.isInput ) { 18797 this.element.val( this.options.label ); 18798 } else { 18799 this.element.html( this.options.label ); 18800 } 18801 } 18802 this._addClass( "ui-button", "ui-widget" ); 18803 this._setOption( "disabled", this.options.disabled ); 18804 this._enhance(); 18805 18806 if ( this.element.is( "a" ) ) { 18807 this._on( { 18808 "keyup": function( event ) { 18809 if ( event.keyCode === $.ui.keyCode.SPACE ) { 18810 event.preventDefault(); 18811 18812 // Support: PhantomJS <= 1.9, IE 8 Only 18813 // If a native click is available use it so we actually cause navigation 18814 // otherwise just trigger a click event 18815 if ( this.element[ 0 ].click ) { 18816 this.element[ 0 ].click(); 18817 } else { 18818 this.element.trigger( "click" ); 18819 } 18820 } 18821 } 18822 } ); 18823 } 18824 }, 18825 18826 _enhance: function() { 18827 if ( !this.element.is( "button" ) ) { 18828 this.element.attr( "role", "button" ); 18829 } 18830 18831 if ( this.options.icon ) { 18832 this._updateIcon( "icon", this.options.icon ); 18833 this._updateTooltip(); 18834 } 18835 }, 18836 18837 _updateTooltip: function() { 18838 this.title = this.element.attr( "title" ); 18839 18840 if ( !this.options.showLabel && !this.title ) { 18841 this.element.attr( "title", this.options.label ); 18842 } 18843 }, 18844 18845 _updateIcon: function( option, value ) { 18846 var icon = option !== "iconPosition", 18847 position = icon ? this.options.iconPosition : value, 18848 displayBlock = position === "top" || position === "bottom"; 18849 18850 // Create icon 18851 if ( !this.icon ) { 18852 this.icon = $( "<span>" ); 18853 18854 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 18855 18856 if ( !this.options.showLabel ) { 18857 this._addClass( "ui-button-icon-only" ); 18858 } 18859 } else if ( icon ) { 18860 18861 // If we are updating the icon remove the old icon class 18862 this._removeClass( this.icon, null, this.options.icon ); 18863 } 18864 18865 // If we are updating the icon add the new icon class 18866 if ( icon ) { 18867 this._addClass( this.icon, null, value ); 18868 } 18869 18870 this._attachIcon( position ); 18871 18872 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 18873 // the iconSpace if there is one. 18874 if ( displayBlock ) { 18875 this._addClass( this.icon, null, "ui-widget-icon-block" ); 18876 if ( this.iconSpace ) { 18877 this.iconSpace.remove(); 18878 } 18879 } else { 18880 18881 // Position is beginning or end so remove the ui-widget-icon-block class and add the 18882 // space if it does not exist 18883 if ( !this.iconSpace ) { 18884 this.iconSpace = $( "<span> </span>" ); 18885 this._addClass( this.iconSpace, "ui-button-icon-space" ); 18886 } 18887 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 18888 this._attachIconSpace( position ); 18889 } 18890 }, 18891 18892 _destroy: function() { 18893 this.element.removeAttr( "role" ); 18894 18895 if ( this.icon ) { 18896 this.icon.remove(); 18897 } 18898 if ( this.iconSpace ) { 18899 this.iconSpace.remove(); 18900 } 18901 if ( !this.hasTitle ) { 18902 this.element.removeAttr( "title" ); 18903 } 18904 }, 18905 18906 _attachIconSpace: function( iconPosition ) { 18907 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 18908 }, 18909 18910 _attachIcon: function( iconPosition ) { 18911 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 18912 }, 18913 18914 _setOptions: function( options ) { 18915 var newShowLabel = options.showLabel === undefined ? 18916 this.options.showLabel : 18917 options.showLabel, 18918 newIcon = options.icon === undefined ? this.options.icon : options.icon; 18919 18920 if ( !newShowLabel && !newIcon ) { 18921 options.showLabel = true; 18922 } 18923 this._super( options ); 18924 }, 18925 18926 _setOption: function( key, value ) { 18927 if ( key === "icon" ) { 18928 if ( value ) { 18929 this._updateIcon( key, value ); 18930 } else if ( this.icon ) { 18931 this.icon.remove(); 18932 if ( this.iconSpace ) { 18933 this.iconSpace.remove(); 18934 } 18935 } 18936 } 18937 18938 if ( key === "iconPosition" ) { 18939 this._updateIcon( key, value ); 18940 } 18941 18942 // Make sure we can't end up with a button that has neither text nor icon 18943 if ( key === "showLabel" ) { 18944 this._toggleClass( "ui-button-icon-only", null, !value ); 18945 this._updateTooltip(); 18946 } 18947 18948 if ( key === "label" ) { 18949 if ( this.isInput ) { 18950 this.element.val( value ); 18951 } else { 18952 18953 // If there is an icon, append it, else nothing then append the value 18954 // this avoids removal of the icon when setting label text 18955 this.element.html( value ); 18956 if ( this.icon ) { 18957 this._attachIcon( this.options.iconPosition ); 18958 this._attachIconSpace( this.options.iconPosition ); 18959 } 18960 } 18961 } 18962 18963 this._super( key, value ); 18964 18965 if ( key === "disabled" ) { 18966 this._toggleClass( null, "ui-state-disabled", value ); 18967 this.element[ 0 ].disabled = value; 18968 if ( value ) { 18969 this.element.trigger( "blur" ); 18970 } 18971 } 18972 }, 18973 18974 refresh: function() { 18975 18976 // Make sure to only check disabled if its an element that supports this otherwise 18977 // check for the disabled class to determine state 18978 var isDisabled = this.element.is( "input, button" ) ? 18979 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 18980 18981 if ( isDisabled !== this.options.disabled ) { 18982 this._setOptions( { disabled: isDisabled } ); 18983 } 18984 18985 this._updateTooltip(); 18986 } 18987} ); 18988 18989// DEPRECATED 18990if ( $.uiBackCompat !== false ) { 18991 18992 // Text and Icons options 18993 $.widget( "ui.button", $.ui.button, { 18994 options: { 18995 text: true, 18996 icons: { 18997 primary: null, 18998 secondary: null 18999 } 19000 }, 19001 19002 _create: function() { 19003 if ( this.options.showLabel && !this.options.text ) { 19004 this.options.showLabel = this.options.text; 19005 } 19006 if ( !this.options.showLabel && this.options.text ) { 19007 this.options.text = this.options.showLabel; 19008 } 19009 if ( !this.options.icon && ( this.options.icons.primary || 19010 this.options.icons.secondary ) ) { 19011 if ( this.options.icons.primary ) { 19012 this.options.icon = this.options.icons.primary; 19013 } else { 19014 this.options.icon = this.options.icons.secondary; 19015 this.options.iconPosition = "end"; 19016 } 19017 } else if ( this.options.icon ) { 19018 this.options.icons.primary = this.options.icon; 19019 } 19020 this._super(); 19021 }, 19022 19023 _setOption: function( key, value ) { 19024 if ( key === "text" ) { 19025 this._super( "showLabel", value ); 19026 return; 19027 } 19028 if ( key === "showLabel" ) { 19029 this.options.text = value; 19030 } 19031 if ( key === "icon" ) { 19032 this.options.icons.primary = value; 19033 } 19034 if ( key === "icons" ) { 19035 if ( value.primary ) { 19036 this._super( "icon", value.primary ); 19037 this._super( "iconPosition", "beginning" ); 19038 } else if ( value.secondary ) { 19039 this._super( "icon", value.secondary ); 19040 this._super( "iconPosition", "end" ); 19041 } 19042 } 19043 this._superApply( arguments ); 19044 } 19045 } ); 19046 19047 $.fn.button = ( function( orig ) { 19048 return function( options ) { 19049 var isMethodCall = typeof options === "string"; 19050 var args = Array.prototype.slice.call( arguments, 1 ); 19051 var returnValue = this; 19052 19053 if ( isMethodCall ) { 19054 19055 // If this is an empty collection, we need to have the instance method 19056 // return undefined instead of the jQuery instance 19057 if ( !this.length && options === "instance" ) { 19058 returnValue = undefined; 19059 } else { 19060 this.each( function() { 19061 var methodValue; 19062 var type = $( this ).attr( "type" ); 19063 var name = type !== "checkbox" && type !== "radio" ? 19064 "button" : 19065 "checkboxradio"; 19066 var instance = $.data( this, "ui-" + name ); 19067 19068 if ( options === "instance" ) { 19069 returnValue = instance; 19070 return false; 19071 } 19072 19073 if ( !instance ) { 19074 return $.error( "cannot call methods on button" + 19075 " prior to initialization; " + 19076 "attempted to call method '" + options + "'" ); 19077 } 19078 19079 if ( typeof instance[ options ] !== "function" || 19080 options.charAt( 0 ) === "_" ) { 19081 return $.error( "no such method '" + options + "' for button" + 19082 " widget instance" ); 19083 } 19084 19085 methodValue = instance[ options ].apply( instance, args ); 19086 19087 if ( methodValue !== instance && methodValue !== undefined ) { 19088 returnValue = methodValue && methodValue.jquery ? 19089 returnValue.pushStack( methodValue.get() ) : 19090 methodValue; 19091 return false; 19092 } 19093 } ); 19094 } 19095 } else { 19096 19097 // Allow multiple hashes to be passed on init 19098 if ( args.length ) { 19099 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 19100 } 19101 19102 this.each( function() { 19103 var type = $( this ).attr( "type" ); 19104 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 19105 var instance = $.data( this, "ui-" + name ); 19106 19107 if ( instance ) { 19108 instance.option( options || {} ); 19109 if ( instance._init ) { 19110 instance._init(); 19111 } 19112 } else { 19113 if ( name === "button" ) { 19114 orig.call( $( this ), options ); 19115 return; 19116 } 19117 19118 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 19119 } 19120 } ); 19121 } 19122 19123 return returnValue; 19124 }; 19125 } )( $.fn.button ); 19126 19127 $.fn.buttonset = function() { 19128 if ( !$.ui.controlgroup ) { 19129 $.error( "Controlgroup widget missing" ); 19130 } 19131 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 19132 return this.controlgroup.apply( this, 19133 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 19134 } 19135 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 19136 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 19137 } 19138 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 19139 arguments[ 0 ].items = { 19140 button: arguments[ 0 ].items 19141 }; 19142 } 19143 return this.controlgroup.apply( this, arguments ); 19144 }; 19145} 19146
19147return $.ui.button; 19148 19149} ); 19150 19151 19152 19153/* eslint-disable max-len, camelcase */ 19154/*! 19155 * jQuery UI Datepicker 1.13.0 19156 * http://jqueryui.com 19157 * 19158 * Copyright jQuery Foundation and other contributors 19159 * Released under the MIT license. 19160 * http://jquery.org/license 19161 */ 19162 19163//>>label: Datepicker 19164//>>group: Widgets 19165//>>description: Displays a calendar from an input or inline for selecting dates. 19166//>>docs: http://api.jqueryui.com/datepicker/ 19167//>>demos: http://jqueryui.com/datepicker/ 19168//>>css.structure: ../../themes/base/core.css 19169//>>css.structure: ../../themes/base/datepicker.css 19170//>>css.theme: ../../themes/base/theme.css 19171 19172( function( factory ) { 19173 "use strict"; 19174 19175 if ( typeof define === "function" && define.amd ) { 19176 19177 // AMD. Register as an anonymous module. 19178 define( [ 19179 "jquery", 19180 "../version", 19181 "../keycode" 19182 ], factory ); 19183 } else { 19184 19185 // Browser globals 19186 factory( jQuery ); 19187 } 19188} )( function( $ ) { 19189"use strict"; 19190 19191$.extend( $.ui, { datepicker: { version: "1.13.0
vendor: 14,162 bytes, lines 19191-19508
19191" } } ); 19192 19193var datepicker_instActive; 19194 19195function datepicker_getZindex( elem ) { 19196 var position, value; 19197 while ( elem.length && elem[ 0 ] !== document ) { 19198 19199 // Ignore z-index if position is set to a value where z-index is ignored by the browser 19200 // This makes behavior of this function consistent across browsers 19201 // WebKit always returns auto if the element is positioned 19202 position = elem.css( "position" ); 19203 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 19204 19205 // IE returns 0 when zIndex is not specified 19206 // other browsers return a string 19207 // we ignore the case of nested elements with an explicit value of 0 19208 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 19209 value = parseInt( elem.css( "zIndex" ), 10 ); 19210 if ( !isNaN( value ) && value !== 0 ) { 19211 return value; 19212 } 19213 } 19214 elem = elem.parent(); 19215 } 19216 19217 return 0; 19218} 19219 19220/* Date picker manager. 19221 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 19222 Settings for (groups of) date pickers are maintained in an instance object, 19223 allowing multiple different settings on the same page. */ 19224 19225function Datepicker() { 19226 this._curInst = null; // The current instance in use 19227 this._keyEvent = false; // If the last event was a key event 19228 this._disabledInputs = []; // List of date picker inputs that have been disabled 19229 this._datepickerShowing = false; // True if the popup picker is showing , false if not 19230 this._inDialog = false; // True if showing within a "dialog", false if not 19231 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 19232 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 19233 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 19234 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 19235 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 19236 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 19237 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 19238 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 19239 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 19240 this.regional = []; // Available regional settings, indexed by language code 19241 this.regional[ "" ] = { // Default regional settings 19242 closeText: "Done", // Display text for close link 19243 prevText: "Prev", // Display text for previous month link 19244 nextText: "Next", // Display text for next month link 19245 currentText: "Today", // Display text for current month link 19246 monthNames: [ "January", "February", "March", "April", "May", "June", 19247 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 19248 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 19249 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 19250 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 19251 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 19252 weekHeader: "Wk", // Column header for week of the year 19253 dateFormat: "mm/dd/yy", // See format options on parseDate 19254 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 19255 isRTL: false, // True if right-to-left language, false if left-to-right 19256 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 19257 yearSuffix: "", // Additional text to append to the year in the month headers, 19258 selectMonthLabel: "Select month", // Invisible label for month selector 19259 selectYearLabel: "Select year" // Invisible label for year selector 19260 }; 19261 this._defaults = { // Global defaults for all the date picker instances 19262 showOn: "focus", // "focus" for popup on focus, 19263 // "button" for trigger button, or "both" for either 19264 showAnim: "fadeIn", // Name of jQuery animation for popup 19265 showOptions: {}, // Options for enhanced animations 19266 defaultDate: null, // Used when field is blank: actual date, 19267 // +/-number for offset from today, null for today 19268 appendText: "", // Display text following the input box, e.g. showing the format 19269 buttonText: "...", // Text for trigger button 19270 buttonImage: "", // URL for trigger button image 19271 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 19272 hideIfNoPrevNext: false, // True to hide next/previous month links 19273 // if not applicable, false to just disable them 19274 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 19275 gotoCurrent: false, // True if today link goes back to current selection instead 19276 changeMonth: false, // True if month can be selected directly, false if only prev/next 19277 changeYear: false, // True if year can be selected directly, false if only prev/next 19278 yearRange: "c-10:c+10", // Range of years to display in drop-down, 19279 // either relative to today's year (-nn:+nn), relative to currently displayed year 19280 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 19281 showOtherMonths: false, // True to show dates in other months, false to leave blank 19282 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 19283 showWeek: false, // True to show week of the year, false to not show it 19284 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 19285 // takes a Date and returns the number of the week for it 19286 shortYearCutoff: "+10", // Short year values < this are in the current century, 19287 // > this are in the previous century, 19288 // string value starting with "+" for current year + value 19289 minDate: null, // The earliest selectable date, or null for no limit 19290 maxDate: null, // The latest selectable date, or null for no limit 19291 duration: "fast", // Duration of display/closure 19292 beforeShowDay: null, // Function that takes a date and returns an array with 19293 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 19294 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 19295 beforeShow: null, // Function that takes an input field and 19296 // returns a set of custom settings for the date picker 19297 onSelect: null, // Define a callback function when a date is selected 19298 onChangeMonthYear: null, // Define a callback function when the month or year is changed 19299 onClose: null, // Define a callback function when the datepicker is closed 19300 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 19301 numberOfMonths: 1, // Number of months to show at a time 19302 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 19303 stepMonths: 1, // Number of months to step back/forward 19304 stepBigMonths: 12, // Number of months to step back/forward for the big links 19305 altField: "", // Selector for an alternate field to store selected dates into 19306 altFormat: "", // The date format to use for the alternate field 19307 constrainInput: true, // The input is constrained by the current date format 19308 showButtonPanel: false, // True to show button panel, false to not show it 19309 autoSize: false, // True to size the input for the date format, false to leave as is 19310 disabled: false // The initial disabled state 19311 }; 19312 $.extend( this._defaults, this.regional[ "" ] ); 19313 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 19314 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 19315 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 19316} 19317 19318$.extend( Datepicker.prototype, { 19319 19320 /* Class name added to elements to indicate already configured with a date picker. */ 19321 markerClassName: "hasDatepicker", 19322 19323 //Keep track of the maximum number of rows displayed (see #7043) 19324 maxRows: 4, 19325 19326 // TODO rename to "widget" when switching to widget factory 19327 _widgetDatepicker: function() { 19328 return this.dpDiv; 19329 }, 19330 19331 /* Override the default settings for all instances of the date picker. 19332 * @param settings object - the new settings to use as defaults (anonymous object) 19333 * @return the manager object 19334 */ 19335 setDefaults: function( settings ) { 19336 datepicker_extendRemove( this._defaults, settings || {} ); 19337 return this; 19338 }, 19339 19340 /* Attach the date picker to a jQuery selection. 19341 * @param target element - the target input field or division or span 19342 * @param settings object - the new settings to use for this date picker instance (anonymous) 19343 */ 19344 _attachDatepicker: function( target, settings ) { 19345 var nodeName, inline, inst; 19346 nodeName = target.nodeName.toLowerCase(); 19347 inline = ( nodeName === "div" || nodeName === "span" ); 19348 if ( !target.id ) { 19349 this.uuid += 1; 19350 target.id = "dp" + this.uuid; 19351 } 19352 inst = this._newInst( $( target ), inline ); 19353 inst.settings = $.extend( {}, settings || {} ); 19354 if ( nodeName === "input" ) { 19355 this._connectDatepicker( target, inst ); 19356 } else if ( inline ) { 19357 this._inlineDatepicker( target, inst ); 19358 } 19359 }, 19360 19361 /* Create a new instance object. */ 19362 _newInst: function( target, inline ) { 19363 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 19364 return { id: id, input: target, // associated target 19365 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 19366 drawMonth: 0, drawYear: 0, // month being drawn 19367 inline: inline, // is datepicker inline or not 19368 dpDiv: ( !inline ? this.dpDiv : // presentation div 19369 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 19370 }, 19371 19372 /* Attach the date picker to an input field. */ 19373 _connectDatepicker: function( target, inst ) { 19374 var input = $( target ); 19375 inst.append = $( [] ); 19376 inst.trigger = $( [] ); 19377 if ( input.hasClass( this.markerClassName ) ) { 19378 return; 19379 } 19380 this._attachments( input, inst ); 19381 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 19382 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 19383 this._autoSize( inst ); 19384 $.data( target, "datepicker", inst ); 19385 19386 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 19387 if ( inst.settings.disabled ) { 19388 this._disableDatepicker( target ); 19389 } 19390 }, 19391 19392 /* Make attachments based on settings. */ 19393 _attachments: function( input, inst ) { 19394 var showOn, buttonText, buttonImage, 19395 appendText = this._get( inst, "appendText" ), 19396 isRTL = this._get( inst, "isRTL" ); 19397 19398 if ( inst.append ) { 19399 inst.append.remove(); 19400 } 19401 if ( appendText ) { 19402 inst.append = $( "<span>" ) 19403 .addClass( this._appendClass ) 19404 .text( appendText ); 19405 input[ isRTL ? "before" : "after" ]( inst.append ); 19406 } 19407 19408 input.off( "focus", this._showDatepicker ); 19409 19410 if ( inst.trigger ) { 19411 inst.trigger.remove(); 19412 } 19413 19414 showOn = this._get( inst, "showOn" ); 19415 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 19416 input.on( "focus", this._showDatepicker ); 19417 } 19418 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 19419 buttonText = this._get( inst, "buttonText" ); 19420 buttonImage = this._get( inst, "buttonImage" ); 19421 19422 if ( this._get( inst, "buttonImageOnly" ) ) { 19423 inst.trigger = $( "<img>" ) 19424 .addClass( this._triggerClass ) 19425 .attr( { 19426 src: buttonImage, 19427 alt: buttonText, 19428 title: buttonText 19429 } ); 19430 } else { 19431 inst.trigger = $( "<button type='button'>" ) 19432 .addClass( this._triggerClass ); 19433 if ( buttonImage ) { 19434 inst.trigger.html( 19435 $( "<img>" ) 19436 .attr( { 19437 src: buttonImage, 19438 alt: buttonText, 19439 title: buttonText 19440 } ) 19441 ); 19442 } else { 19443 inst.trigger.text( buttonText ); 19444 } 19445 } 19446 19447 input[ isRTL ? "before" : "after" ]( inst.trigger ); 19448 inst.trigger.on( "click", function() { 19449 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 19450 $.datepicker._hideDatepicker(); 19451 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 19452 $.datepicker._hideDatepicker(); 19453 $.datepicker._showDatepicker( input[ 0 ] ); 19454 } else { 19455 $.datepicker._showDatepicker( input[ 0 ] ); 19456 } 19457 return false; 19458 } ); 19459 } 19460 }, 19461 19462 /* Apply the maximum length for the date format. */ 19463 _autoSize: function( inst ) { 19464 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 19465 var findMax, max, maxI, i, 19466 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 19467 dateFormat = this._get( inst, "dateFormat" ); 19468 19469 if ( dateFormat.match( /[DM]/ ) ) { 19470 findMax = function( names ) { 19471 max = 0; 19472 maxI = 0; 19473 for ( i = 0; i < names.length; i++ ) { 19474 if ( names[ i ].length > max ) { 19475 max = names[ i ].length; 19476 maxI = i; 19477 } 19478 } 19479 return maxI; 19480 }; 19481 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 19482 "monthNames" : "monthNamesShort" ) ) ) ); 19483 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 19484 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 19485 } 19486 inst.input.attr( "size", this._formatDate( inst, date ).length ); 19487 } 19488 }, 19489 19490 /* Attach an inline date picker to a div. */ 19491 _inlineDatepicker: function( target, inst ) { 19492 var divSpan = $( target ); 19493 if ( divSpan.hasClass( this.markerClassName ) ) { 19494 return; 19495 } 19496 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 19497 $.data( target, "datepicker", inst ); 19498 this._setDate( inst, this._getDefaultDate( inst ), true ); 19499 this._updateDatepicker( inst ); 19500 this._updateAlternate( inst ); 19501 19502 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 19503 if ( inst.settings.disabled ) { 19504 this._disableDatepicker( target ); 19505 } 19506 19507 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 19508 // http
vendor: 14,693 bytes, lines 19508-19930
19508://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 19509 inst.dpDiv.css( "display", "block" ); 19510 }, 19511 19512 /* Pop-up the date picker in a "dialog" box. 19513 * @param input element - ignored 19514 * @param date string or Date - the initial date to display 19515 * @param onSelect function - the function to call when a date is selected 19516 * @param settings object - update the dialog date picker instance's settings (anonymous object) 19517 * @param pos int[2] - coordinates for the dialog's position within the screen or 19518 * event - with x/y coordinates or 19519 * leave empty for default (screen centre) 19520 * @return the manager object 19521 */ 19522 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 19523 var id, browserWidth, browserHeight, scrollX, scrollY, 19524 inst = this._dialogInst; // internal instance 19525 19526 if ( !inst ) { 19527 this.uuid += 1; 19528 id = "dp" + this.uuid; 19529 this._dialogInput = $( "<input type='text' id='" + id + 19530 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 19531 this._dialogInput.on( "keydown", this._doKeyDown ); 19532 $( "body" ).append( this._dialogInput ); 19533 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 19534 inst.settings = {}; 19535 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 19536 } 19537 datepicker_extendRemove( inst.settings, settings || {} ); 19538 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 19539 this._dialogInput.val( date ); 19540 19541 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 19542 if ( !this._pos ) { 19543 browserWidth = document.documentElement.clientWidth; 19544 browserHeight = document.documentElement.clientHeight; 19545 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 19546 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 19547 this._pos = // should use actual width/height below 19548 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 19549 } 19550 19551 // Move input on screen for focus, but hidden behind dialog 19552 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 19553 inst.settings.onSelect = onSelect; 19554 this._inDialog = true; 19555 this.dpDiv.addClass( this._dialogClass ); 19556 this._showDatepicker( this._dialogInput[ 0 ] ); 19557 if ( $.blockUI ) { 19558 $.blockUI( this.dpDiv ); 19559 } 19560 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 19561 return this; 19562 }, 19563 19564 /* Detach a datepicker from its control. 19565 * @param target element - the target input field or division or span 19566 */ 19567 _destroyDatepicker: function( target ) { 19568 var nodeName, 19569 $target = $( target ), 19570 inst = $.data( target, "datepicker" ); 19571 19572 if ( !$target.hasClass( this.markerClassName ) ) { 19573 return; 19574 } 19575 19576 nodeName = target.nodeName.toLowerCase(); 19577 $.removeData( target, "datepicker" ); 19578 if ( nodeName === "input" ) { 19579 inst.append.remove(); 19580 inst.trigger.remove(); 19581 $target.removeClass( this.markerClassName ). 19582 off( "focus", this._showDatepicker ). 19583 off( "keydown", this._doKeyDown ). 19584 off( "keypress", this._doKeyPress ). 19585 off( "keyup", this._doKeyUp ); 19586 } else if ( nodeName === "div" || nodeName === "span" ) { 19587 $target.removeClass( this.markerClassName ).empty(); 19588 } 19589 19590 if ( datepicker_instActive === inst ) { 19591 datepicker_instActive = null; 19592 this._curInst = null; 19593 } 19594 }, 19595 19596 /* Enable the date picker to a jQuery selection. 19597 * @param target element - the target input field or division or span 19598 */ 19599 _enableDatepicker: function( target ) { 19600 var nodeName, inline, 19601 $target = $( target ), 19602 inst = $.data( target, "datepicker" ); 19603 19604 if ( !$target.hasClass( this.markerClassName ) ) { 19605 return; 19606 } 19607 19608 nodeName = target.nodeName.toLowerCase(); 19609 if ( nodeName === "input" ) { 19610 target.disabled = false; 19611 inst.trigger.filter( "button" ). 19612 each( function() { 19613 this.disabled = false; 19614 } ).end(). 19615 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 19616 } else if ( nodeName === "div" || nodeName === "span" ) { 19617 inline = $target.children( "." + this._inlineClass ); 19618 inline.children().removeClass( "ui-state-disabled" ); 19619 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 19620 prop( "disabled", false ); 19621 } 19622 this._disabledInputs = $.map( this._disabledInputs, 19623 19624 // Delete entry 19625 function( value ) { 19626 return ( value === target ? null : value ); 19627 } ); 19628 }, 19629 19630 /* Disable the date picker to a jQuery selection. 19631 * @param target element - the target input field or division or span 19632 */ 19633 _disableDatepicker: function( target ) { 19634 var nodeName, inline, 19635 $target = $( target ), 19636 inst = $.data( target, "datepicker" ); 19637 19638 if ( !$target.hasClass( this.markerClassName ) ) { 19639 return; 19640 } 19641 19642 nodeName = target.nodeName.toLowerCase(); 19643 if ( nodeName === "input" ) { 19644 target.disabled = true; 19645 inst.trigger.filter( "button" ). 19646 each( function() { 19647 this.disabled = true; 19648 } ).end(). 19649 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 19650 } else if ( nodeName === "div" || nodeName === "span" ) { 19651 inline = $target.children( "." + this._inlineClass ); 19652 inline.children().addClass( "ui-state-disabled" ); 19653 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 19654 prop( "disabled", true ); 19655 } 19656 this._disabledInputs = $.map( this._disabledInputs, 19657 19658 // Delete entry 19659 function( value ) { 19660 return ( value === target ? null : value ); 19661 } ); 19662 this._disabledInputs[ this._disabledInputs.length ] = target; 19663 }, 19664 19665 /* Is the first field in a jQuery collection disabled as a datepicker? 19666 * @param target element - the target input field or division or span 19667 * @return boolean - true if disabled, false if enabled 19668 */ 19669 _isDisabledDatepicker: function( target ) { 19670 if ( !target ) { 19671 return false; 19672 } 19673 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 19674 if ( this._disabledInputs[ i ] === target ) { 19675 return true; 19676 } 19677 } 19678 return false; 19679 }, 19680 19681 /* Retrieve the instance data for the target control. 19682 * @param target element - the target input field or division or span 19683 * @return object - the associated instance data 19684 * @throws error if a jQuery problem getting data 19685 */ 19686 _getInst: function( target ) { 19687 try { 19688 return $.data( target, "datepicker" ); 19689 } catch ( err ) { 19690 throw "Missing instance data for this datepicker"; 19691 } 19692 }, 19693 19694 /* Update or retrieve the settings for a date picker attached to an input field or division. 19695 * @param target element - the target input field or division or span 19696 * @param name object - the new settings to update or 19697 * string - the name of the setting to change or retrieve, 19698 * when retrieving also "all" for all instance settings or 19699 * "defaults" for all global defaults 19700 * @param value any - the new value for the setting 19701 * (omit if above is an object or to retrieve a value) 19702 */ 19703 _optionDatepicker: function( target, name, value ) { 19704 var settings, date, minDate, maxDate, 19705 inst = this._getInst( target ); 19706 19707 if ( arguments.length === 2 && typeof name === "string" ) { 19708 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 19709 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 19710 this._get( inst, name ) ) : null ) ); 19711 } 19712 19713 settings = name || {}; 19714 if ( typeof name === "string" ) { 19715 settings = {}; 19716 settings[ name ] = value; 19717 } 19718 19719 if ( inst ) { 19720 if ( this._curInst === inst ) { 19721 this._hideDatepicker(); 19722 } 19723 19724 date = this._getDateDatepicker( target, true ); 19725 minDate = this._getMinMaxDate( inst, "min" ); 19726 maxDate = this._getMinMaxDate( inst, "max" ); 19727 datepicker_extendRemove( inst.settings, settings ); 19728 19729 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 19730 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 19731 inst.settings.minDate = this._formatDate( inst, minDate ); 19732 } 19733 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 19734 inst.settings.maxDate = this._formatDate( inst, maxDate ); 19735 } 19736 if ( "disabled" in settings ) { 19737 if ( settings.disabled ) { 19738 this._disableDatepicker( target ); 19739 } else { 19740 this._enableDatepicker( target ); 19741 } 19742 } 19743 this._attachments( $( target ), inst ); 19744 this._autoSize( inst ); 19745 this._setDate( inst, date ); 19746 this._updateAlternate( inst ); 19747 this._updateDatepicker( inst ); 19748 } 19749 }, 19750 19751 // Change method deprecated 19752 _changeDatepicker: function( target, name, value ) { 19753 this._optionDatepicker( target, name, value ); 19754 }, 19755 19756 /* Redraw the date picker attached to an input field or division. 19757 * @param target element - the target input field or division or span 19758 */ 19759 _refreshDatepicker: function( target ) { 19760 var inst = this._getInst( target ); 19761 if ( inst ) { 19762 this._updateDatepicker( inst ); 19763 } 19764 }, 19765 19766 /* Set the dates for a jQuery selection. 19767 * @param target element - the target input field or division or span 19768 * @param date Date - the new date 19769 */ 19770 _setDateDatepicker: function( target, date ) { 19771 var inst = this._getInst( target ); 19772 if ( inst ) { 19773 this._setDate( inst, date ); 19774 this._updateDatepicker( inst ); 19775 this._updateAlternate( inst ); 19776 } 19777 }, 19778 19779 /* Get the date(s) for the first entry in a jQuery selection. 19780 * @param target element - the target input field or division or span 19781 * @param noDefault boolean - true if no default date is to be used 19782 * @return Date - the current date 19783 */ 19784 _getDateDatepicker: function( target, noDefault ) { 19785 var inst = this._getInst( target ); 19786 if ( inst && !inst.inline ) { 19787 this._setDateFromField( inst, noDefault ); 19788 } 19789 return ( inst ? this._getDate( inst ) : null ); 19790 }, 19791 19792 /* Handle keystrokes. */ 19793 _doKeyDown: function( event ) { 19794 var onSelect, dateStr, sel, 19795 inst = $.datepicker._getInst( event.target ), 19796 handled = true, 19797 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 19798 19799 inst._keyEvent = true; 19800 if ( $.datepicker._datepickerShowing ) { 19801 switch ( event.keyCode ) { 19802 case 9: $.datepicker._hideDatepicker(); 19803 handled = false; 19804 break; // hide on tab out 19805 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 19806 $.datepicker._currentClass + ")", inst.dpDiv ); 19807 if ( sel[ 0 ] ) { 19808 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 19809 } 19810 19811 onSelect = $.datepicker._get( inst, "onSelect" ); 19812 if ( onSelect ) { 19813 dateStr = $.datepicker._formatDate( inst ); 19814 19815 // Trigger custom callback 19816 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 19817 } else { 19818 $.datepicker._hideDatepicker(); 19819 } 19820 19821 return false; // don't submit the form 19822 case 27: $.datepicker._hideDatepicker(); 19823 break; // hide on escape 19824 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 19825 -$.datepicker._get( inst, "stepBigMonths" ) : 19826 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 19827 break; // previous month/year on page up/+ ctrl 19828 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 19829 +$.datepicker._get( inst, "stepBigMonths" ) : 19830 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 19831 break; // next month/year on page down/+ ctrl 19832 case 35: if ( event.ctrlKey || event.metaKey ) { 19833 $.datepicker._clearDate( event.target ); 19834 } 19835 handled = event.ctrlKey || event.metaKey; 19836 break; // clear on ctrl or command +end 19837 case 36: if ( event.ctrlKey || event.metaKey ) { 19838 $.datepicker._gotoToday( event.target ); 19839 } 19840 handled = event.ctrlKey || event.metaKey; 19841 break; // current on ctrl or command +home 19842 case 37: if ( event.ctrlKey || event.metaKey ) { 19843 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 19844 } 19845 handled = event.ctrlKey || event.metaKey; 19846 19847 // -1 day on ctrl or command +left 19848 if ( event.originalEvent.altKey ) { 19849 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 19850 -$.datepicker._get( inst, "stepBigMonths" ) : 19851 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 19852 } 19853 19854 // next month/year on alt +left on Mac 19855 break; 19856 case 38: if ( event.ctrlKey || event.metaKey ) { 19857 $.datepicker._adjustDate( event.target, -7, "D" ); 19858 } 19859 handled = event.ctrlKey || event.metaKey; 19860 break; // -1 week on ctrl or command +up 19861 case 39: if ( event.ctrlKey || event.metaKey ) { 19862 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 19863 } 19864 handled = event.ctrlKey || event.metaKey; 19865 19866 // +1 day on ctrl or command +right 19867 if ( event.originalEvent.altKey ) { 19868 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 19869 +$.datepicker._get( inst, "stepBigMonths" ) : 19870 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 19871 } 19872 19873 // next month/year on alt +right 19874 break; 19875 case 40: if ( event.ctrlKey || event.metaKey ) { 19876 $.datepicker._adjustDate( event.target, +7, "D" ); 19877 } 19878 handled = event.ctrlKey || event.metaKey; 19879 break; // +1 week on ctrl or command +down 19880 default: handled = false; 19881 } 19882 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 19883 $.datepicker._showDatepicker( this ); 19884 } else { 19885 handled = false; 19886 } 19887 19888 if ( handled ) { 19889 event.preventDefault(); 19890 event.stopPropagation(); 19891 } 19892 }, 19893 19894 /* Filter entered characters - based on date format. */ 19895 _doKeyPress: function( event ) { 19896 var chars, chr, 19897 inst = $.datepicker._getInst( event.target ); 19898 19899 if ( $.datepicker._get( inst, "constrainInput" ) ) { 19900 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 19901 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 19902 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 19903 } 19904 }, 19905 19906 /* Synchronise manual entry and field/alternate field. */ 19907 _doKeyUp: function( event ) { 19908 var date, 19909 inst = $.datepicker._getInst( event.target ); 19910 19911 if ( inst.input.val() !== inst.lastVal ) { 19912 try { 19913 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 19914 ( inst.input ? inst.input.val() : null ), 19915 $.datepicker._getFormatConfig( inst ) ); 19916 19917 if ( date ) { // only if valid 19918 $.datepicker._setDateFromField( inst ); 19919 $.datepicker._updateAlternate( inst ); 19920 $.datepicker._updateDatepicker( inst ); 19921 } 19922 } catch ( err ) { 19923 } 19924 } 19925 return true; 19926 }, 19927 19928 /* Pop-up the date picker for a given input field. 19929 * If false returned from beforeShow event handler do not show. 19930 * @param input element - the input field attached to the date picker or
vendor: 4,332 bytes, lines 19931-20053
19931 * event - if triggered by focus 19932 */ 19933 _showDatepicker: function( input ) { 19934 input = input.target || input; 19935 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 19936 input = $( "input", input.parentNode )[ 0 ]; 19937 } 19938 19939 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 19940 return; 19941 } 19942 19943 var inst, beforeShow, beforeShowSettings, isFixed, 19944 offset, showAnim, duration; 19945 19946 inst = $.datepicker._getInst( input ); 19947 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 19948 $.datepicker._curInst.dpDiv.stop( true, true ); 19949 if ( inst && $.datepicker._datepickerShowing ) { 19950 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 19951 } 19952 } 19953 19954 beforeShow = $.datepicker._get( inst, "beforeShow" ); 19955 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 19956 if ( beforeShowSettings === false ) { 19957 return; 19958 } 19959 datepicker_extendRemove( inst.settings, beforeShowSettings ); 19960 19961 inst.lastVal = null; 19962 $.datepicker._lastInput = input; 19963 $.datepicker._setDateFromField( inst ); 19964 19965 if ( $.datepicker._inDialog ) { // hide cursor 19966 input.value = ""; 19967 } 19968 if ( !$.datepicker._pos ) { // position below input 19969 $.datepicker._pos = $.datepicker._findPos( input ); 19970 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 19971 } 19972 19973 isFixed = false; 19974 $( input ).parents().each( function() { 19975 isFixed |= $( this ).css( "position" ) === "fixed"; 19976 return !isFixed; 19977 } ); 19978 19979 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 19980 $.datepicker._pos = null; 19981 19982 //to avoid flashes on Firefox 19983 inst.dpDiv.empty(); 19984 19985 // determine sizing offscreen 19986 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 19987 $.datepicker._updateDatepicker( inst ); 19988 19989 // fix width for dynamic number of date pickers 19990 // and adjust position before showing 19991 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 19992 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 19993 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 19994 left: offset.left + "px", top: offset.top + "px" } ); 19995 19996 if ( !inst.inline ) { 19997 showAnim = $.datepicker._get( inst, "showAnim" ); 19998 duration = $.datepicker._get( inst, "duration" ); 19999 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 20000 $.datepicker._datepickerShowing = true; 20001 20002 if ( $.effects && $.effects.effect[ showAnim ] ) { 20003 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 20004 } else { 20005 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 20006 } 20007 20008 if ( $.datepicker._shouldFocusInput( inst ) ) { 20009 inst.input.trigger( "focus" ); 20010 } 20011 20012 $.datepicker._curInst = inst; 20013 } 20014 }, 20015 20016 /* Generate the date picker content. */ 20017 _updateDatepicker: function( inst ) { 20018 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 20019 datepicker_instActive = inst; // for delegate hover events 20020 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 20021 this._attachHandlers( inst ); 20022 20023 var origyearshtml, 20024 numMonths = this._getNumberOfMonths( inst ), 20025 cols = numMonths[ 1 ], 20026 width = 17, 20027 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 20028 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 20029 20030 if ( activeCell.length > 0 ) { 20031 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 20032 } 20033 20034 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 20035 if ( cols > 1 ) { 20036 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 20037 } 20038 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 20039 "Class" ]( "ui-datepicker-multi" ); 20040 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 20041 "Class" ]( "ui-datepicker-rtl" ); 20042 20043 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 20044 inst.input.trigger( "focus" ); 20045 } 20046 20047 // Deffered render of the years select (to avoid flashes on Firefox) 20048 if ( inst.yearshtml ) { 20049 origyearshtml = inst.yearshtml; 20050 setTimeout( function() { 20051 20052 //assure that inst.yearshtml didn't change. 20053 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
vendor: 5,508 bytes, lines 20054-20212
20054 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 20055 } 20056 origyearshtml = inst.yearshtml = null; 20057 }, 0 ); 20058 } 20059 20060 if ( onUpdateDatepicker ) { 20061 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 20062 } 20063 }, 20064 20065 // #6694 - don't focus the input if it's already focused 20066 // this breaks the change event in IE 20067 // Support: IE and jQuery <1.9 20068 _shouldFocusInput: function( inst ) { 20069 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 20070 }, 20071 20072 /* Check positioning to remain on screen. */ 20073 _checkOffset: function( inst, offset, isFixed ) { 20074 var dpWidth = inst.dpDiv.outerWidth(), 20075 dpHeight = inst.dpDiv.outerHeight(), 20076 inputWidth = inst.input ? inst.input.outerWidth() : 0, 20077 inputHeight = inst.input ? inst.input.outerHeight() : 0, 20078 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 20079 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 20080 20081 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 20082 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 20083 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 20084 20085 // Now check if datepicker is showing outside window viewport - move to a better place if so. 20086 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 20087 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 20088 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 20089 Math.abs( dpHeight + inputHeight ) : 0 ); 20090 20091 return offset; 20092 }, 20093 20094 /* Find an object's position on the screen. */ 20095 _findPos: function( obj ) { 20096 var position, 20097 inst = this._getInst( obj ), 20098 isRTL = this._get( inst, "isRTL" ); 20099 20100 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 20101 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 20102 } 20103 20104 position = $( obj ).offset(); 20105 return [ position.left, position.top ]; 20106 }, 20107 20108 /* Hide the date picker from view. 20109 * @param input element - the input field attached to the date picker 20110 */ 20111 _hideDatepicker: function( input ) { 20112 var showAnim, duration, postProcess, onClose, 20113 inst = this._curInst; 20114 20115 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 20116 return; 20117 } 20118 20119 if ( this._datepickerShowing ) { 20120 showAnim = this._get( inst, "showAnim" ); 20121 duration = this._get( inst, "duration" ); 20122 postProcess = function() { 20123 $.datepicker._tidyDialog( inst ); 20124 }; 20125 20126 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 20127 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 20128 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 20129 } else { 20130 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 20131 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 20132 } 20133 20134 if ( !showAnim ) { 20135 postProcess(); 20136 } 20137 this._datepickerShowing = false; 20138 20139 onClose = this._get( inst, "onClose" ); 20140 if ( onClose ) { 20141 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 20142 } 20143 20144 this._lastInput = null; 20145 if ( this._inDialog ) { 20146 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 20147 if ( $.blockUI ) { 20148 $.unblockUI(); 20149 $( "body" ).append( this.dpDiv ); 20150 } 20151 } 20152 this._inDialog = false; 20153 } 20154 }, 20155 20156 /* Tidy up after a dialog display. */ 20157 _tidyDialog: function( inst ) { 20158 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 20159 }, 20160 20161 /* Close date picker if clicked elsewhere. */ 20162 _checkExternalClick: function( event ) { 20163 if ( !$.datepicker._curInst ) { 20164 return; 20165 } 20166 20167 var $target = $( event.target ), 20168 inst = $.datepicker._getInst( $target[ 0 ] ); 20169 20170 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 20171 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 20172 !$target.hasClass( $.datepicker.markerClassName ) && 20173 !$target.closest( "." + $.datepicker._triggerClass ).length && 20174 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 20175 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 20176 $.datepicker._hideDatepicker(); 20177 } 20178 }, 20179 20180 /* Adjust one of the date sub-fields. */ 20181 _adjustDate: function( id, offset, period ) { 20182 var target = $( id ), 20183 inst = this._getInst( target[ 0 ] ); 20184 20185 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 20186 return; 20187 } 20188 this._adjustInstDate( inst, offset, period ); 20189 this._updateDatepicker( inst ); 20190 }, 20191 20192 /* Action for current link. */ 20193 _gotoToday: function( id ) { 20194 var date, 20195 target = $( id ), 20196 inst = this._getInst( target[ 0 ] ); 20197 20198 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 20199 inst.selectedDay = inst.currentDay; 20200 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 20201 inst.drawYear = inst.selectedYear = inst.currentYear; 20202 } else { 20203 date = new Date(); 20204 inst.selectedDay = date.getDate(); 20205 inst.drawMonth = inst.selectedMonth = date.getMonth(); 20206 inst.drawYear = inst.selectedYear = date.getFullYear(); 20207 } 20208 this._notifyChange( inst ); 20209 this._adjustDate( target ); 20210 }, 20211 20212 /* Action for selecting a new month/year. */
vendor: 4,615 bytes, lines 20213-20344
20213 _selectMonthYear: function( id, select, period ) { 20214 var target = $( id ), 20215 inst = this._getInst( target[ 0 ] ); 20216 20217 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 20218 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 20219 parseInt( select.options[ select.selectedIndex ].value, 10 ); 20220 20221 this._notifyChange( inst ); 20222 this._adjustDate( target ); 20223 }, 20224 20225 /* Action for selecting a day. */ 20226 _selectDay: function( id, month, year, td ) { 20227 var inst, 20228 target = $( id ); 20229 20230 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 20231 return; 20232 } 20233 20234 inst = this._getInst( target[ 0 ] ); 20235 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 20236 inst.selectedMonth = inst.currentMonth = month; 20237 inst.selectedYear = inst.currentYear = year; 20238 this._selectDate( id, this._formatDate( inst, 20239 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 20240 }, 20241 20242 /* Erase the input field and hide the date picker. */ 20243 _clearDate: function( id ) { 20244 var target = $( id ); 20245 this._selectDate( target, "" ); 20246 }, 20247 20248 /* Update the input field with the selected date. */ 20249 _selectDate: function( id, dateStr ) { 20250 var onSelect, 20251 target = $( id ), 20252 inst = this._getInst( target[ 0 ] ); 20253 20254 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 20255 if ( inst.input ) { 20256 inst.input.val( dateStr ); 20257 } 20258 this._updateAlternate( inst ); 20259 20260 onSelect = this._get( inst, "onSelect" ); 20261 if ( onSelect ) { 20262 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 20263 } else if ( inst.input ) { 20264 inst.input.trigger( "change" ); // fire the change event 20265 } 20266 20267 if ( inst.inline ) { 20268 this._updateDatepicker( inst ); 20269 } else { 20270 this._hideDatepicker(); 20271 this._lastInput = inst.input[ 0 ]; 20272 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 20273 inst.input.trigger( "focus" ); // restore focus 20274 } 20275 this._lastInput = null; 20276 } 20277 }, 20278 20279 /* Update any alternate field to synchronise with the main field. */ 20280 _updateAlternate: function( inst ) { 20281 var altFormat, date, dateStr, 20282 altField = this._get( inst, "altField" ); 20283 20284 if ( altField ) { // update alternate field too 20285 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 20286 date = this._getDate( inst ); 20287 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 20288 $( document ).find( altField ).val( dateStr ); 20289 } 20290 }, 20291 20292 /* Set as beforeShowDay function to prevent selection of weekends. 20293 * @param date Date - the date to customise 20294 * @return [boolean, string] - is this date selectable?, what is its CSS class? 20295 */ 20296 noWeekends: function( date ) { 20297 var day = date.getDay(); 20298 return [ ( day > 0 && day < 6 ), "" ]; 20299 }, 20300 20301 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 20302 * @param date Date - the date to get the week for 20303 * @return number - the number of the week within the year that contains this date 20304 */ 20305 iso8601Week: function( date ) { 20306 var time, 20307 checkDate = new Date( date.getTime() ); 20308 20309 // Find Thursday of this week starting on Monday 20310 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 20311 20312 time = checkDate.getTime(); 20313 checkDate.setMonth( 0 ); // Compare with Jan 1 20314 checkDate.setDate( 1 ); 20315 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 20316 }, 20317 20318 /* Parse a string value into a date object. 20319 * See formatDate below for the possible formats. 20320 * 20321 * @param format string - the expected format of the date 20322 * @param value string - the date in the above format 20323 * @param settings Object - attributes include: 20324 * shortYearCutoff number - the cutoff year for determining the century (optional) 20325 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 20326 * dayNames string[7] - names of the days from Sunday (optional) 20327 * monthNamesShort string[12] - abbreviated names of the months (optional) 20328 * monthNames string[12] - names of the months (optional) 20329 * @return Date - the extracted date value or null if value is blank 20330 */ 20331 parseDate: function( format, value, settings ) { 20332 if ( format == null || value == null ) { 20333 throw "Invalid arguments"; 20334 } 20335 20336 value = ( typeof value === "object" ? value.toString() : value + "" ); 20337 if ( value === "" ) { 20338 return null; 20339 } 20340 20341 var iFormat, dim, extra, 20342 iValue = 0, 20343 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 20344 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp
vendor: 16,988 bytes, lines 20344-20873
20344: 20345 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 20346 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 20347 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 20348 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 20349 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 20350 year = -1, 20351 month = -1, 20352 day = -1, 20353 doy = -1, 20354 literal = false, 20355 date, 20356 20357 // Check whether a format character is doubled 20358 lookAhead = function( match ) { 20359 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 20360 if ( matches ) { 20361 iFormat++; 20362 } 20363 return matches; 20364 }, 20365 20366 // Extract a number from the string value 20367 getNumber = function( match ) { 20368 var isDoubled = lookAhead( match ), 20369 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 20370 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 20371 minSize = ( match === "y" ? size : 1 ), 20372 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 20373 num = value.substring( iValue ).match( digits ); 20374 if ( !num ) { 20375 throw "Missing number at position " + iValue; 20376 } 20377 iValue += num[ 0 ].length; 20378 return parseInt( num[ 0 ], 10 ); 20379 }, 20380 20381 // Extract a name from the string value and convert to an index 20382 getName = function( match, shortNames, longNames ) { 20383 var index = -1, 20384 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 20385 return [ [ k, v ] ]; 20386 } ).sort( function( a, b ) { 20387 return -( a[ 1 ].length - b[ 1 ].length ); 20388 } ); 20389 20390 $.each( names, function( i, pair ) { 20391 var name = pair[ 1 ]; 20392 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 20393 index = pair[ 0 ]; 20394 iValue += name.length; 20395 return false; 20396 } 20397 } ); 20398 if ( index !== -1 ) { 20399 return index + 1; 20400 } else { 20401 throw "Unknown name at position " + iValue; 20402 } 20403 }, 20404 20405 // Confirm that a literal character matches the string value 20406 checkLiteral = function() { 20407 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 20408 throw "Unexpected literal at position " + iValue; 20409 } 20410 iValue++; 20411 }; 20412 20413 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 20414 if ( literal ) { 20415 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 20416 literal = false; 20417 } else { 20418 checkLiteral(); 20419 } 20420 } else { 20421 switch ( format.charAt( iFormat ) ) { 20422 case "d": 20423 day = getNumber( "d" ); 20424 break; 20425 case "D": 20426 getName( "D", dayNamesShort, dayNames ); 20427 break; 20428 case "o": 20429 doy = getNumber( "o" ); 20430 break; 20431 case "m": 20432 month = getNumber( "m" ); 20433 break; 20434 case "M": 20435 month = getName( "M", monthNamesShort, monthNames ); 20436 break; 20437 case "y": 20438 year = getNumber( "y" ); 20439 break; 20440 case "@": 20441 date = new Date( getNumber( "@" ) ); 20442 year = date.getFullYear(); 20443 month = date.getMonth() + 1; 20444 day = date.getDate(); 20445 break; 20446 case "!": 20447 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 20448 year = date.getFullYear(); 20449 month = date.getMonth() + 1; 20450 day = date.getDate(); 20451 break; 20452 case "'": 20453 if ( lookAhead( "'" ) ) { 20454 checkLiteral(); 20455 } else { 20456 literal = true; 20457 } 20458 break; 20459 default: 20460 checkLiteral(); 20461 } 20462 } 20463 } 20464 20465 if ( iValue < value.length ) { 20466 extra = value.substr( iValue ); 20467 if ( !/^\s+/.test( extra ) ) { 20468 throw "Extra/unparsed characters found in date: " + extra; 20469 } 20470 } 20471 20472 if ( year === -1 ) { 20473 year = new Date().getFullYear(); 20474 } else if ( year < 100 ) { 20475 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 20476 ( year <= shortYearCutoff ? 0 : -100 ); 20477 } 20478 20479 if ( doy > -1 ) { 20480 month = 1; 20481 day = doy; 20482 do { 20483 dim = this._getDaysInMonth( year, month - 1 ); 20484 if ( day <= dim ) { 20485 break; 20486 } 20487 month++; 20488 day -= dim; 20489 } while ( true ); 20490 } 20491 20492 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 20493 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 20494 throw "Invalid date"; // E.g. 31/02/00 20495 } 20496 return date; 20497 }, 20498 20499 /* Standard date formats. */ 20500 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 20501 COOKIE: "D, dd M yy", 20502 ISO_8601: "yy-mm-dd", 20503 RFC_822: "D, d M y", 20504 RFC_850: "DD, dd-M-y", 20505 RFC_1036: "D, d M y", 20506 RFC_1123: "D, d M yy", 20507 RFC_2822: "D, d M yy", 20508 RSS: "D, d M y", // RFC 822 20509 TICKS: "!", 20510 TIMESTAMP: "@", 20511 W3C: "yy-mm-dd", // ISO 8601 20512 20513 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 20514 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 20515 20516 /* Format a date object into a string value. 20517 * The format can be combinations of the following: 20518 * d - day of month (no leading zero) 20519 * dd - day of month (two digit) 20520 * o - day of year (no leading zeros) 20521 * oo - day of year (three digit) 20522 * D - day name short 20523 * DD - day name long 20524 * m - month of year (no leading zero) 20525 * mm - month of year (two digit) 20526 * M - month name short 20527 * MM - month name long 20528 * y - year (two digit) 20529 * yy - year (four digit) 20530 * @ - Unix timestamp (ms since 01/01/1970) 20531 * ! - Windows ticks (100ns since 01/01/0001) 20532 * "..." - literal text 20533 * '' - single quote 20534 * 20535 * @param format string - the desired format of the date 20536 * @param date Date - the date value to format 20537 * @param settings Object - attributes include: 20538 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 20539 * dayNames string[7] - names of the days from Sunday (optional) 20540 * monthNamesShort string[12] - abbreviated names of the months (optional) 20541 * monthNames string[12] - names of the months (optional) 20542 * @return string - the date in the above format 20543 */ 20544 formatDate: function( format, date, settings ) { 20545 if ( !date ) { 20546 return ""; 20547 } 20548 20549 var iFormat, 20550 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 20551 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 20552 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 20553 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 20554 20555 // Check whether a format character is doubled 20556 lookAhead = function( match ) { 20557 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 20558 if ( matches ) { 20559 iFormat++; 20560 } 20561 return matches; 20562 }, 20563 20564 // Format a number, with leading zero if necessary 20565 formatNumber = function( match, value, len ) { 20566 var num = "" + value; 20567 if ( lookAhead( match ) ) { 20568 while ( num.length < len ) { 20569 num = "0" + num; 20570 } 20571 } 20572 return num; 20573 }, 20574 20575 // Format a name, short or long as requested 20576 formatName = function( match, value, shortNames, longNames ) { 20577 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 20578 }, 20579 output = "", 20580 literal = false; 20581 20582 if ( date ) { 20583 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 20584 if ( literal ) { 20585 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 20586 literal = false; 20587 } else { 20588 output += format.charAt( iFormat ); 20589 } 20590 } else { 20591 switch ( format.charAt( iFormat ) ) { 20592 case "d": 20593 output += formatNumber( "d", date.getDate(), 2 ); 20594 break; 20595 case "D": 20596 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 20597 break; 20598 case "o": 20599 output += formatNumber( "o", 20600 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 20601 break; 20602 case "m": 20603 output += formatNumber( "m", date.getMonth() + 1, 2 ); 20604 break; 20605 case "M": 20606 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 20607 break; 20608 case "y": 20609 output += ( lookAhead( "y" ) ? date.getFullYear() : 20610 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 20611 break; 20612 case "@": 20613 output += date.getTime(); 20614 break; 20615 case "!": 20616 output += date.getTime() * 10000 + this._ticksTo1970; 20617 break; 20618 case "'": 20619 if ( lookAhead( "'" ) ) { 20620 output += "'"; 20621 } else { 20622 literal = true; 20623 } 20624 break; 20625 default: 20626 output += format.charAt( iFormat ); 20627 } 20628 } 20629 } 20630 } 20631 return output; 20632 }, 20633 20634 /* Extract all possible characters from the date format. */ 20635 _possibleChars: function( format ) { 20636 var iFormat, 20637 chars = "", 20638 literal = false, 20639 20640 // Check whether a format character is doubled 20641 lookAhead = function( match ) { 20642 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 20643 if ( matches ) { 20644 iFormat++; 20645 } 20646 return matches; 20647 }; 20648 20649 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 20650 if ( literal ) { 20651 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 20652 literal = false; 20653 } else { 20654 chars += format.charAt( iFormat ); 20655 } 20656 } else { 20657 switch ( format.charAt( iFormat ) ) { 20658 case "d": case "m": case "y": case "@": 20659 chars += "0123456789"; 20660 break; 20661 case "D": case "M": 20662 return null; // Accept anything 20663 case "'": 20664 if ( lookAhead( "'" ) ) { 20665 chars += "'"; 20666 } else { 20667 literal = true; 20668 } 20669 break; 20670 default: 20671 chars += format.charAt( iFormat ); 20672 } 20673 } 20674 } 20675 return chars; 20676 }, 20677 20678 /* Get a setting value, defaulting if necessary. */ 20679 _get: function( inst, name ) { 20680 return inst.settings[ name ] !== undefined ? 20681 inst.settings[ name ] : this._defaults[ name ]; 20682 }, 20683 20684 /* Parse existing date and initialise date picker. */ 20685 _setDateFromField: function( inst, noDefault ) { 20686 if ( inst.input.val() === inst.lastVal ) { 20687 return; 20688 } 20689 20690 var dateFormat = this._get( inst, "dateFormat" ), 20691 dates = inst.lastVal = inst.input ? inst.input.val() : null, 20692 defaultDate = this._getDefaultDate( inst ), 20693 date = defaultDate, 20694 settings = this._getFormatConfig( inst ); 20695 20696 try { 20697 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 20698 } catch ( event ) { 20699 dates = ( noDefault ? "" : dates ); 20700 } 20701 inst.selectedDay = date.getDate(); 20702 inst.drawMonth = inst.selectedMonth = date.getMonth(); 20703 inst.drawYear = inst.selectedYear = date.getFullYear(); 20704 inst.currentDay = ( dates ? date.getDate() : 0 ); 20705 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 20706 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 20707 this._adjustInstDate( inst ); 20708 }, 20709 20710 /* Retrieve the default date shown on opening. */ 20711 _getDefaultDate: function( inst ) { 20712 return this._restrictMinMax( inst, 20713 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 20714 }, 20715 20716 /* A date may be specified as an exact value or a relative one. */ 20717 _determineDate: function( inst, date, defaultDate ) { 20718 var offsetNumeric = function( offset ) { 20719 var date = new Date(); 20720 date.setDate( date.getDate() + offset ); 20721 return date; 20722 }, 20723 offsetString = function( offset ) { 20724 try { 20725 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 20726 offset, $.datepicker._getFormatConfig( inst ) ); 20727 } catch ( e ) { 20728 20729 // Ignore 20730 } 20731 20732 var date = ( offset.toLowerCase().match( /^c/ ) ? 20733 $.datepicker._getDate( inst ) : null ) || new Date(), 20734 year = date.getFullYear(), 20735 month = date.getMonth(), 20736 day = date.getDate(), 20737 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 20738 matches = pattern.exec( offset ); 20739 20740 while ( matches ) { 20741 switch ( matches[ 2 ] || "d" ) { 20742 case "d" : case "D" : 20743 day += parseInt( matches[ 1 ], 10 ); break; 20744 case "w" : case "W" : 20745 day += parseInt( matches[ 1 ], 10 ) * 7; break; 20746 case "m" : case "M" : 20747 month += parseInt( matches[ 1 ], 10 ); 20748 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 20749 break; 20750 case "y": case "Y" : 20751 year += parseInt( matches[ 1 ], 10 ); 20752 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 20753 break; 20754 } 20755 matches = pattern.exec( offset ); 20756 } 20757 return new Date( year, month, day ); 20758 }, 20759 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 20760 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 20761 20762 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 20763 if ( newDate ) { 20764 newDate.setHours( 0 ); 20765 newDate.setMinutes( 0 ); 20766 newDate.setSeconds( 0 ); 20767 newDate.setMilliseconds( 0 ); 20768 } 20769 return this._daylightSavingAdjust( newDate ); 20770 }, 20771 20772 /* Handle switch to/from daylight saving. 20773 * Hours may be non-zero on daylight saving cut-over: 20774 * > 12 when midnight changeover, but then cannot generate 20775 * midnight datetime, so jump to 1AM, otherwise reset. 20776 * @param date (Date) the date to check 20777 * @return (Date) the corrected date 20778 */ 20779 _daylightSavingAdjust: function( date ) { 20780 if ( !date ) { 20781 return null; 20782 } 20783 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 20784 return date; 20785 }, 20786 20787 /* Set the date(s) directly. */ 20788 _setDate: function( inst, date, noChange ) { 20789 var clear = !date, 20790 origMonth = inst.selectedMonth, 20791 origYear = inst.selectedYear, 20792 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 20793 20794 inst.selectedDay = inst.currentDay = newDate.getDate(); 20795 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 20796 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 20797 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 20798 this._notifyChange( inst ); 20799 } 20800 this._adjustInstDate( inst ); 20801 if ( inst.input ) { 20802 inst.input.val( clear ? "" : this._formatDate( inst ) ); 20803 } 20804 }, 20805 20806 /* Retrieve the date(s) directly. */ 20807 _getDate: function( inst ) { 20808 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 20809 this._daylightSavingAdjust( new Date( 20810 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 20811 return startDate; 20812 }, 20813 20814 /* Attach the onxxx handlers. These are declared statically so 20815 * they work with static code transformers like Caja. 20816 */ 20817 _attachHandlers: function( inst ) { 20818 var stepMonths = this._get( inst, "stepMonths" ), 20819 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 20820 inst.dpDiv.find( "[data-handler]" ).map( function() { 20821 var handler = { 20822 prev: function() { 20823 $.datepicker._adjustDate( id, -stepMonths, "M" ); 20824 }, 20825 next: function() { 20826 $.datepicker._adjustDate( id, +stepMonths, "M" ); 20827 }, 20828 hide: function() { 20829 $.datepicker._hideDatepicker(); 20830 }, 20831 today: function() { 20832 $.datepicker._gotoToday( id ); 20833 }, 20834 selectDay: function() { 20835 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 20836 return false; 20837 }, 20838 selectMonth: function() { 20839 $.datepicker._selectMonthYear( id, this, "M" ); 20840 return false; 20841 }, 20842 selectYear: function() { 20843 $.datepicker._selectMonthYear( id, this, "Y" ); 20844 return false; 20845 } 20846 }; 20847 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 20848 } ); 20849 }, 20850 20851 /* Generate the HTML for the current state of the date picker. */ 20852 _generateHTML: function( inst ) { 20853 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 20854 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 20855 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 20856 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 20857 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 20858 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 20859 tempDate = new Date(), 20860 today = this._daylightSavingAdjust( 20861 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 20862 isRTL = this._get( inst, "isRTL" ), 20863 showButtonPanel = this._get( inst, "showButtonPanel" ), 20864 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 20865 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 20866 numMonths = this._getNumberOfMonths( inst ), 20867 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 20868 stepMonths = this._get( inst, "stepMonths" ), 20869 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 20870 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 20871 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 20872 minDate = this._getMinMaxDate( inst, "min" ), 20873 maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,257 bytes, lines 20874-21388
20874 drawMonth = inst.drawMonth - showCurrentAtPos, 20875 drawYear = inst.drawYear; 20876 20877 if ( drawMonth < 0 ) { 20878 drawMonth += 12; 20879 drawYear--; 20880 } 20881 if ( maxDate ) { 20882 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 20883 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 20884 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 20885 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 20886 drawMonth--; 20887 if ( drawMonth < 0 ) { 20888 drawMonth = 11; 20889 drawYear--; 20890 } 20891 } 20892 } 20893 inst.drawMonth = drawMonth; 20894 inst.drawYear = drawYear; 20895 20896 prevText = this._get( inst, "prevText" ); 20897 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 20898 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 20899 this._getFormatConfig( inst ) ) ); 20900 20901 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 20902 prev = $( "<a>" ) 20903 .attr( { 20904 "class": "ui-datepicker-prev ui-corner-all", 20905 "data-handler": "prev", 20906 "data-event": "click", 20907 title: prevText 20908 } ) 20909 .append( 20910 $( "<span>" ) 20911 .addClass( "ui-icon ui-icon-circle-triangle-" + 20912 ( isRTL ? "e" : "w" ) ) 20913 .text( prevText ) 20914 )[ 0 ].outerHTML; 20915 } else if ( hideIfNoPrevNext ) { 20916 prev = ""; 20917 } else { 20918 prev = $( "<a>" ) 20919 .attr( { 20920 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 20921 title: prevText 20922 } ) 20923 .append( 20924 $( "<span>" ) 20925 .addClass( "ui-icon ui-icon-circle-triangle-" + 20926 ( isRTL ? "e" : "w" ) ) 20927 .text( prevText ) 20928 )[ 0 ].outerHTML; 20929 } 20930 20931 nextText = this._get( inst, "nextText" ); 20932 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 20933 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 20934 this._getFormatConfig( inst ) ) ); 20935 20936 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 20937 next = $( "<a>" ) 20938 .attr( { 20939 "class": "ui-datepicker-next ui-corner-all", 20940 "data-handler": "next", 20941 "data-event": "click", 20942 title: nextText 20943 } ) 20944 .append( 20945 $( "<span>" ) 20946 .addClass( "ui-icon ui-icon-circle-triangle-" + 20947 ( isRTL ? "w" : "e" ) ) 20948 .text( nextText ) 20949 )[ 0 ].outerHTML; 20950 } else if ( hideIfNoPrevNext ) { 20951 next = ""; 20952 } else { 20953 next = $( "<a>" ) 20954 .attr( { 20955 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 20956 title: nextText 20957 } ) 20958 .append( 20959 $( "<span>" ) 20960 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 20961 ( isRTL ? "w" : "e" ) ) 20962 .text( nextText ) 20963 )[ 0 ].outerHTML; 20964 } 20965 20966 currentText = this._get( inst, "currentText" ); 20967 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 20968 currentText = ( !navigationAsDateFormat ? currentText : 20969 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 20970 20971 controls = ""; 20972 if ( !inst.inline ) { 20973 controls = $( "<button>" ) 20974 .attr( { 20975 type: "button", 20976 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 20977 "data-handler": "hide", 20978 "data-event": "click" 20979 } ) 20980 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 20981 } 20982 20983 buttonPanel = ""; 20984 if ( showButtonPanel ) { 20985 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 20986 .append( isRTL ? controls : "" ) 20987 .append( this._isInRange( inst, gotoDate ) ? 20988 $( "<button>" ) 20989 .attr( { 20990 type: "button", 20991 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 20992 "data-handler": "today", 20993 "data-event": "click" 20994 } ) 20995 .text( currentText ) : 20996 "" ) 20997 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 20998 } 20999 21000 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 21001 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 21002 21003 showWeek = this._get( inst, "showWeek" ); 21004 dayNames = this._get( inst, "dayNames" ); 21005 dayNamesMin = this._get( inst, "dayNamesMin" ); 21006 monthNames = this._get( inst, "monthNames" ); 21007 monthNamesShort = this._get( inst, "monthNamesShort" ); 21008 beforeShowDay = this._get( inst, "beforeShowDay" ); 21009 showOtherMonths = this._get( inst, "showOtherMonths" ); 21010 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 21011 defaultDate = this._getDefaultDate( inst ); 21012 html = ""; 21013 21014 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 21015 group = ""; 21016 this.maxRows = 4; 21017 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 21018 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 21019 cornerClass = " ui-corner-all"; 21020 calender = ""; 21021 if ( isMultiMonth ) { 21022 calender += "<div class='ui-datepicker-group"; 21023 if ( numMonths[ 1 ] > 1 ) { 21024 switch ( col ) { 21025 case 0: calender += " ui-datepicker-group-first"; 21026 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 21027 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 21028 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 21029 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 21030 } 21031 } 21032 calender += "'>"; 21033 } 21034 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 21035 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 21036 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 21037 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 21038 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 21039 "</div><table class='ui-datepicker-calendar'><thead>" + 21040 "<tr>"; 21041 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 21042 for ( dow = 0; dow < 7; dow++ ) { // days of the week 21043 day = ( dow + firstDay ) % 7; 21044 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 21045 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 21046 } 21047 calender += thead + "</tr></thead><tbody>"; 21048 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 21049 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 21050 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 21051 } 21052 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 21053 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 21054 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 21055 this.maxRows = numRows; 21056 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 21057 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 21058 calender += "<tr>"; 21059 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 21060 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 21061 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 21062 daySettings = ( beforeShowDay ? 21063 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 21064 otherMonth = ( printDate.getMonth() !== drawMonth ); 21065 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 21066 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 21067 tbody += "<td class='" + 21068 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 21069 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 21070 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 21071 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 21072 21073 // or defaultDate is current printedDate and defaultDate is selectedDate 21074 " " + this._dayOverClass : "" ) + // highlight selected day 21075 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 21076 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 21077 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 21078 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 21079 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 21080 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 21081 ( otherMonth && !showOtherMonths ? " " : // display for other months 21082 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 21083 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 21084 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 21085 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 21086 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 21087 "' data-date='" + printDate.getDate() + // store date as data 21088 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 21089 printDate.setDate( printDate.getDate() + 1 ); 21090 printDate = this._daylightSavingAdjust( printDate ); 21091 } 21092 calender += tbody + "</tr>"; 21093 } 21094 drawMonth++; 21095 if ( drawMonth > 11 ) { 21096 drawMonth = 0; 21097 drawYear++; 21098 } 21099 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 21100 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 21101 group += calender; 21102 } 21103 html += group; 21104 } 21105 html += buttonPanel; 21106 inst._keyEvent = false; 21107 return html; 21108 }, 21109 21110 /* Generate the month and year header. */ 21111 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 21112 secondary, monthNames, monthNamesShort ) { 21113 21114 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 21115 changeMonth = this._get( inst, "changeMonth" ), 21116 changeYear = this._get( inst, "changeYear" ), 21117 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 21118 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 21119 selectYearLabel = this._get( inst, "selectYearLabel" ), 21120 html = "<div class='ui-datepicker-title'>", 21121 monthHtml = ""; 21122 21123 // Month selection 21124 if ( secondary || !changeMonth ) { 21125 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 21126 } else { 21127 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 21128 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 21129 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 21130 for ( month = 0; month < 12; month++ ) { 21131 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 21132 monthHtml += "<option value='" + month + "'" + 21133 ( month === drawMonth ? " selected='selected'" : "" ) + 21134 ">" + monthNamesShort[ month ] + "</option>"; 21135 } 21136 } 21137 monthHtml += "</select>"; 21138 } 21139 21140 if ( !showMonthAfterYear ) { 21141 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 21142 } 21143 21144 // Year selection 21145 if ( !inst.yearshtml ) { 21146 inst.yearshtml = ""; 21147 if ( secondary || !changeYear ) { 21148 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 21149 } else { 21150 21151 // determine range of years to display 21152 years = this._get( inst, "yearRange" ).split( ":" ); 21153 thisYear = new Date().getFullYear(); 21154 determineYear = function( value ) { 21155 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 21156 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 21157 parseInt( value, 10 ) ) ); 21158 return ( isNaN( year ) ? thisYear : year ); 21159 }; 21160 year = determineYear( years[ 0 ] ); 21161 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 21162 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 21163 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 21164 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 21165 for ( ; year <= endYear; year++ ) { 21166 inst.yearshtml += "<option value='" + year + "'" + 21167 ( year === drawYear ? " selected='selected'" : "" ) + 21168 ">" + year + "</option>"; 21169 } 21170 inst.yearshtml += "</select>"; 21171 21172 html += inst.yearshtml; 21173 inst.yearshtml = null; 21174 } 21175 } 21176 21177 html += this._get( inst, "yearSuffix" ); 21178 if ( showMonthAfterYear ) { 21179 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 21180 } 21181 html += "</div>"; // Close datepicker_header 21182 return html; 21183 }, 21184 21185 /* Adjust one of the date sub-fields. */ 21186 _adjustInstDate: function( inst, offset, period ) { 21187 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 21188 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 21189 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 21190 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 21191 21192 inst.selectedDay = date.getDate(); 21193 inst.drawMonth = inst.selectedMonth = date.getMonth(); 21194 inst.drawYear = inst.selectedYear = date.getFullYear(); 21195 if ( period === "M" || period === "Y" ) { 21196 this._notifyChange( inst ); 21197 } 21198 }, 21199 21200 /* Ensure a date is within any min/max bounds. */ 21201 _restrictMinMax: function( inst, date ) { 21202 var minDate = this._getMinMaxDate( inst, "min" ), 21203 maxDate = this._getMinMaxDate( inst, "max" ), 21204 newDate = ( minDate && date < minDate ? minDate : date ); 21205 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 21206 }, 21207 21208 /* Notify change of month/year. */ 21209 _notifyChange: function( inst ) { 21210 var onChange = this._get( inst, "onChangeMonthYear" ); 21211 if ( onChange ) { 21212 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 21213 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 21214 } 21215 }, 21216 21217 /* Determine the number of months to show. */ 21218 _getNumberOfMonths: function( inst ) { 21219 var numMonths = this._get( inst, "numberOfMonths" ); 21220 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 21221 }, 21222 21223 /* Determine the current maximum date - ensure no time components are set. */ 21224 _getMinMaxDate: function( inst, minMax ) { 21225 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 21226 }, 21227 21228 /* Find the number of days in a given month. */ 21229 _getDaysInMonth: function( year, month ) { 21230 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 21231 }, 21232 21233 /* Find the day of the week of the first of a month. */ 21234 _getFirstDayOfMonth: function( year, month ) { 21235 return new Date( year, month, 1 ).getDay(); 21236 }, 21237 21238 /* Determines if we should allow a "next/prev" month display change. */ 21239 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 21240 var numMonths = this._getNumberOfMonths( inst ), 21241 date = this._daylightSavingAdjust( new Date( curYear, 21242 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 21243 21244 if ( offset < 0 ) { 21245 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 21246 } 21247 return this._isInRange( inst, date ); 21248 }, 21249 21250 /* Is the given date in the accepted range? */ 21251 _isInRange: function( inst, date ) { 21252 var yearSplit, currentYear, 21253 minDate = this._getMinMaxDate( inst, "min" ), 21254 maxDate = this._getMinMaxDate( inst, "max" ), 21255 minYear = null, 21256 maxYear = null, 21257 years = this._get( inst, "yearRange" ); 21258 if ( years ) { 21259 yearSplit = years.split( ":" ); 21260 currentYear = new Date().getFullYear(); 21261 minYear = parseInt( yearSplit[ 0 ], 10 ); 21262 maxYear = parseInt( yearSplit[ 1 ], 10 ); 21263 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 21264 minYear += currentYear; 21265 } 21266 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 21267 maxYear += currentYear; 21268 } 21269 } 21270 21271 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 21272 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 21273 ( !minYear || date.getFullYear() >= minYear ) && 21274 ( !maxYear || date.getFullYear() <= maxYear ) ); 21275 }, 21276 21277 /* Provide the configuration settings for formatting/parsing. */ 21278 _getFormatConfig: function( inst ) { 21279 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 21280 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 21281 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 21282 return { shortYearCutoff: shortYearCutoff, 21283 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 21284 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 21285 }, 21286 21287 /* Format the given date for display. */ 21288 _formatDate: function( inst, day, month, year ) { 21289 if ( !day ) { 21290 inst.currentDay = inst.selectedDay; 21291 inst.currentMonth = inst.selectedMonth; 21292 inst.currentYear = inst.selectedYear; 21293 } 21294 var date = ( day ? ( typeof day === "object" ? day : 21295 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 21296 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 21297 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 21298 } 21299} ); 21300 21301/* 21302 * Bind hover events for datepicker elements. 21303 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 21304 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 21305 */ 21306function datepicker_bindHover( dpDiv ) { 21307 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 21308 return dpDiv.on( "mouseout", selector, function() { 21309 $( this ).removeClass( "ui-state-hover" ); 21310 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 21311 $( this ).removeClass( "ui-datepicker-prev-hover" ); 21312 } 21313 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 21314 $( this ).removeClass( "ui-datepicker-next-hover" ); 21315 } 21316 } ) 21317 .on( "mouseover", selector, datepicker_handleMouseover ); 21318} 21319 21320function datepicker_handleMouseover() { 21321 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 21322 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 21323 $( this ).addClass( "ui-state-hover" ); 21324 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 21325 $( this ).addClass( "ui-datepicker-prev-hover" ); 21326 } 21327 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 21328 $( this ).addClass( "ui-datepicker-next-hover" ); 21329 } 21330 } 21331} 21332 21333/* jQuery extend now ignores nulls! */ 21334function datepicker_extendRemove( target, props ) { 21335 $.extend( target, props ); 21336 for ( var name in props ) { 21337 if ( props[ name ] == null ) { 21338 target[ name ] = props[ name ]; 21339 } 21340 } 21341 return target; 21342} 21343 21344/* Invoke the datepicker functionality. 21345 @param options string - a command, optionally followed by additional parameters or 21346 Object - settings for attaching new datepicker functionality 21347 @return jQuery object */ 21348$.fn.datepicker = function( options ) { 21349 21350 /* Verify an empty collection wasn't passed - Fixes #6976 */ 21351 if ( !this.length ) { 21352 return this; 21353 } 21354 21355 /* Initialise the date picker. */ 21356 if ( !$.datepicker.initialized ) { 21357 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 21358 $.datepicker.initialized = true; 21359 } 21360 21361 /* Append datepicker main container to body if not exist. */ 21362 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 21363 $( "body" ).append( $.datepicker.dpDiv ); 21364 } 21365 21366 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 21367 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 21368 return $.datepicker[ "_" + options + "Datepicker" ]. 21369 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 21370 } 21371 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 21372 return $.datepicker[ "_" + options + "Datepicker" ]. 21373 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 21374 } 21375 return this.each( function() { 21376 if ( typeof options === "string" ) { 21377 $.datepicker[ "_" + options + "Datepicker" ] 21378 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 21379 } else { 21380 $.datepicker._attachDatepicker( this, options ); 21381 } 21382 } ); 21383}; 21384 21385$.datepicker = new Datepicker(); // singleton instance 21386$.datepicker.initialized = false; 21387$.datepicker.uuid = new Date().getTime(); 21388$.datepicker.version = "1.1
vendor: 7,177 bytes, lines 21388-21685
213883.0"; 21389 21390return $.datepicker; 21391 21392} ); 21393 21394 21395 21396 21397/*! 21398 * jQuery UI Mouse 1.13.0 21399 * http://jqueryui.com 21400 * 21401 * Copyright jQuery Foundation and other contributors 21402 * Released under the MIT license. 21403 * http://jquery.org/license 21404 */ 21405 21406//>>label: Mouse 21407//>>group: Widgets 21408//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 21409//>>docs: http://api.jqueryui.com/mouse/ 21410 21411( function( factory ) { 21412 "use strict"; 21413 21414 if ( typeof define === "function" && define.amd ) { 21415 21416 // AMD. Register as an anonymous module. 21417 define( [ 21418 "jquery", 21419 "../ie", 21420 "../version", 21421 "../widget" 21422 ], factory ); 21423 } else { 21424 21425 // Browser globals 21426 factory( jQuery ); 21427 } 21428} )( function( $ ) { 21429"use strict"; 21430 21431var mouseHandled = false; 21432$( document ).on( "mouseup", function() { 21433 mouseHandled = false; 21434} ); 21435 21436return $.widget( "ui.mouse", { 21437 version: "1.13.0", 21438 options: { 21439 cancel: "input, textarea, button, select, option", 21440 distance: 1, 21441 delay: 0 21442 }, 21443 _mouseInit: function() { 21444 var that = this; 21445 21446 this.element 21447 .on( "mousedown." + this.widgetName, function( event ) { 21448 return that._mouseDown( event ); 21449 } ) 21450 .on( "click." + this.widgetName, function( event ) { 21451 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 21452 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 21453 event.stopImmediatePropagation(); 21454 return false; 21455 } 21456 } ); 21457 21458 this.started = false; 21459 }, 21460 21461 // TODO: make sure destroying one instance of mouse doesn't mess with 21462 // other instances of mouse 21463 _mouseDestroy: function() { 21464 this.element.off( "." + this.widgetName ); 21465 if ( this._mouseMoveDelegate ) { 21466 this.document 21467 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 21468 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 21469 } 21470 }, 21471 21472 _mouseDown: function( event ) { 21473 21474 // don't let more than one widget handle mouseStart 21475 if ( mouseHandled ) { 21476 return; 21477 } 21478 21479 this._mouseMoved = false; 21480 21481 // We may have missed mouseup (out of window) 21482 if ( this._mouseStarted ) { 21483 this._mouseUp( event ); 21484 } 21485 21486 this._mouseDownEvent = event; 21487 21488 var that = this, 21489 btnIsLeft = ( event.which === 1 ), 21490 21491 // event.target.nodeName works around a bug in IE 8 with 21492 // disabled inputs (#7620) 21493 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 21494 $( event.target ).closest( this.options.cancel ).length : false ); 21495 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 21496 return true; 21497 } 21498 21499 this.mouseDelayMet = !this.options.delay; 21500 if ( !this.mouseDelayMet ) { 21501 this._mouseDelayTimer = setTimeout( function() { 21502 that.mouseDelayMet = true; 21503 }, this.options.delay ); 21504 } 21505 21506 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 21507 this._mouseStarted = ( this._mouseStart( event ) !== false ); 21508 if ( !this._mouseStarted ) { 21509 event.preventDefault(); 21510 return true; 21511 } 21512 } 21513 21514 // Click event may never have fired (Gecko & Opera) 21515 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 21516 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 21517 } 21518 21519 // These delegates are required to keep context 21520 this._mouseMoveDelegate = function( event ) { 21521 return that._mouseMove( event ); 21522 }; 21523 this._mouseUpDelegate = function( event ) { 21524 return that._mouseUp( event ); 21525 }; 21526 21527 this.document 21528 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 21529 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 21530 21531 event.preventDefault(); 21532 21533 mouseHandled = true; 21534 return true; 21535 }, 21536 21537 _mouseMove: function( event ) { 21538 21539 // Only check for mouseups outside the document if you've moved inside the document 21540 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 21541 // fire a mousemove event if content is placed under the cursor. See #7778 21542 // Support: IE <9 21543 if ( this._mouseMoved ) { 21544 21545 // IE mouseup check - mouseup happened when mouse was out of window 21546 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 21547 !event.button ) { 21548 return this._mouseUp( event ); 21549 21550 // Iframe mouseup check - mouseup occurred in another document 21551 } else if ( !event.which ) { 21552 21553 // Support: Safari <=8 - 9 21554 // Safari sets which to 0 if you press any of the following keys 21555 // during a drag (#14461) 21556 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 21557 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 21558 this.ignoreMissingWhich = true; 21559 } else if ( !this.ignoreMissingWhich ) { 21560 return this._mouseUp( event ); 21561 } 21562 } 21563 } 21564 21565 if ( event.which || event.button ) { 21566 this._mouseMoved = true; 21567 } 21568 21569 if ( this._mouseStarted ) { 21570 this._mouseDrag( event ); 21571 return event.preventDefault(); 21572 } 21573 21574 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 21575 this._mouseStarted = 21576 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 21577 if ( this._mouseStarted ) { 21578 this._mouseDrag( event ); 21579 } else { 21580 this._mouseUp( event ); 21581 } 21582 } 21583 21584 return !this._mouseStarted; 21585 }, 21586 21587 _mouseUp: function( event ) { 21588 this.document 21589 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 21590 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 21591 21592 if ( this._mouseStarted ) { 21593 this._mouseStarted = false; 21594 21595 if ( event.target === this._mouseDownEvent.target ) { 21596 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 21597 } 21598 21599 this._mouseStop( event ); 21600 } 21601 21602 if ( this._mouseDelayTimer ) { 21603 clearTimeout( this._mouseDelayTimer ); 21604 delete this._mouseDelayTimer; 21605 } 21606 21607 this.ignoreMissingWhich = false; 21608 mouseHandled = false; 21609 event.preventDefault(); 21610 }, 21611 21612 _mouseDistanceMet: function( event ) { 21613 return ( Math.max( 21614 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 21615 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 21616 ) >= this.options.distance 21617 ); 21618 }, 21619 21620 _mouseDelayMet: function( /* event */ ) { 21621 return this.mouseDelayMet; 21622 }, 21623 21624 // These are placeholder methods, to be overriden by extending plugin 21625 _mouseStart: function( /* event */ ) {}, 21626 _mouseDrag: function( /* event */ ) {}, 21627 _mouseStop: function( /* event */ ) {}, 21628 _mouseCapture: function( /* event */ ) { 21629 return true; 21630 } 21631} ); 21632 21633} ); 21634 21635 21636 21637 21638 21639 21640 21641 21642 21643/*! 21644 * jQuery UI Draggable 1.13.0 21645 * http://jqueryui.com 21646 * 21647 * Copyright jQuery Foundation and other contributors 21648 * Released under the MIT license. 21649 * http://jquery.org/license 21650 */ 21651 21652//>>label: Draggable 21653//>>group: Interactions 21654//>>description: Enables dragging functionality for any element. 21655//>>docs: http://api.jqueryui.com/draggable/ 21656//>>demos: http://jqueryui.com/draggable/ 21657//>>css.structure: ../../themes/base/draggable.css 21658 21659( function( factory ) { 21660 "use strict"; 21661 21662 if ( typeof define === "function" && define.amd ) { 21663 21664 // AMD. Register as an anonymous module. 21665 define( [ 21666 "jquery", 21667 "./mouse", 21668 "../data", 21669 "../plugin", 21670 "../safe-active-element", 21671 "../safe-blur", 21672 "../scroll-parent", 21673 "../version", 21674 "../widget" 21675 ], factory ); 21676 } else { 21677 21678 // Browser globals 21679 factory( jQuery ); 21680 } 21681} )( function( $ ) { 21682"use strict"; 21683 21684$.widget( "ui.draggable", $.ui.mouse, { 21685 version: "1.13.0
vendor: 8,684 bytes, lines 21685-22031
21685", 21686 widgetEventPrefix: "drag", 21687 options: { 21688 addClasses: true, 21689 appendTo: "parent", 21690 axis: false, 21691 connectToSortable: false, 21692 containment: false, 21693 cursor: "auto", 21694 cursorAt: false, 21695 grid: false, 21696 handle: false, 21697 helper: "original", 21698 iframeFix: false, 21699 opacity: false, 21700 refreshPositions: false, 21701 revert: false, 21702 revertDuration: 500, 21703 scope: "default", 21704 scroll: true, 21705 scrollSensitivity: 20, 21706 scrollSpeed: 20, 21707 snap: false, 21708 snapMode: "both", 21709 snapTolerance: 20, 21710 stack: false, 21711 zIndex: false, 21712 21713 // Callbacks 21714 drag: null, 21715 start: null, 21716 stop: null 21717 }, 21718 _create: function() { 21719 21720 if ( this.options.helper === "original" ) { 21721 this._setPositionRelative(); 21722 } 21723 if ( this.options.addClasses ) { 21724 this._addClass( "ui-draggable" ); 21725 } 21726 this._setHandleClassName(); 21727 21728 this._mouseInit(); 21729 }, 21730 21731 _setOption: function( key, value ) { 21732 this._super( key, value ); 21733 if ( key === "handle" ) { 21734 this._removeHandleClassName(); 21735 this._setHandleClassName(); 21736 } 21737 }, 21738 21739 _destroy: function() { 21740 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 21741 this.destroyOnClear = true; 21742 return; 21743 } 21744 this._removeHandleClassName(); 21745 this._mouseDestroy(); 21746 }, 21747 21748 _mouseCapture: function( event ) { 21749 var o = this.options; 21750 21751 // Among others, prevent a drag on a resizable-handle 21752 if ( this.helper || o.disabled || 21753 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 21754 return false; 21755 } 21756 21757 //Quit if we're not on a valid handle 21758 this.handle = this._getHandle( event ); 21759 if ( !this.handle ) { 21760 return false; 21761 } 21762 21763 this._blurActiveElement( event ); 21764 21765 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 21766 21767 return true; 21768 21769 }, 21770 21771 _blockFrames: function( selector ) { 21772 this.iframeBlocks = this.document.find( selector ).map( function() { 21773 var iframe = $( this ); 21774 21775 return $( "<div>" ) 21776 .css( "position", "absolute" ) 21777 .appendTo( iframe.parent() ) 21778 .outerWidth( iframe.outerWidth() ) 21779 .outerHeight( iframe.outerHeight() ) 21780 .offset( iframe.offset() )[ 0 ]; 21781 } ); 21782 }, 21783 21784 _unblockFrames: function() { 21785 if ( this.iframeBlocks ) { 21786 this.iframeBlocks.remove(); 21787 delete this.iframeBlocks; 21788 } 21789 }, 21790 21791 _blurActiveElement: function( event ) { 21792 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 21793 target = $( event.target ); 21794 21795 // Don't blur if the event occurred on an element that is within 21796 // the currently focused element 21797 // See #10527, #12472 21798 if ( target.closest( activeElement ).length ) { 21799 return; 21800 } 21801 21802 // Blur any element that currently has focus, see #4261 21803 $.ui.safeBlur( activeElement ); 21804 }, 21805 21806 _mouseStart: function( event ) { 21807 21808 var o = this.options; 21809 21810 //Create and append the visible helper 21811 this.helper = this._createHelper( event ); 21812 21813 this._addClass( this.helper, "ui-draggable-dragging" ); 21814 21815 //Cache the helper size 21816 this._cacheHelperProportions(); 21817 21818 //If ddmanager is used for droppables, set the global draggable 21819 if ( $.ui.ddmanager ) { 21820 $.ui.ddmanager.current = this; 21821 } 21822 21823 /* 21824 * - Position generation - 21825 * This block generates everything position related - it's the core of draggables. 21826 */ 21827 21828 //Cache the margins of the original element 21829 this._cacheMargins(); 21830 21831 //Store the helper's css position 21832 this.cssPosition = this.helper.css( "position" ); 21833 this.scrollParent = this.helper.scrollParent( true ); 21834 this.offsetParent = this.helper.offsetParent(); 21835 this.hasFixedAncestor = this.helper.parents().filter( function() { 21836 return $( this ).css( "position" ) === "fixed"; 21837 } ).length > 0; 21838 21839 //The element's absolute position on the page minus margins 21840 this.positionAbs = this.element.offset(); 21841 this._refreshOffsets( event ); 21842 21843 //Generate the original position 21844 this.originalPosition = this.position = this._generatePosition( event, false ); 21845 this.originalPageX = event.pageX; 21846 this.originalPageY = event.pageY; 21847 21848 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 21849 if ( o.cursorAt ) { 21850 this._adjustOffsetFromHelper( o.cursorAt ); 21851 } 21852 21853 //Set a containment if given in the options 21854 this._setContainment(); 21855 21856 //Trigger event + callbacks 21857 if ( this._trigger( "start", event ) === false ) { 21858 this._clear(); 21859 return false; 21860 } 21861 21862 //Recache the helper size 21863 this._cacheHelperProportions(); 21864 21865 //Prepare the droppable offsets 21866 if ( $.ui.ddmanager && !o.dropBehaviour ) { 21867 $.ui.ddmanager.prepareOffsets( this, event ); 21868 } 21869 21870 // Execute the drag once - this causes the helper not to be visible before getting its 21871 // correct position 21872 this._mouseDrag( event, true ); 21873 21874 // If the ddmanager is used for droppables, inform the manager that dragging has started 21875 // (see #5003) 21876 if ( $.ui.ddmanager ) { 21877 $.ui.ddmanager.dragStart( this, event ); 21878 } 21879 21880 return true; 21881 }, 21882 21883 _refreshOffsets: function( event ) { 21884 this.offset = { 21885 top: this.positionAbs.top - this.margins.top, 21886 left: this.positionAbs.left - this.margins.left, 21887 scroll: false, 21888 parent: this._getParentOffset(), 21889 relative: this._getRelativeOffset() 21890 }; 21891 21892 this.offset.click = { 21893 left: event.pageX - this.offset.left, 21894 top: event.pageY - this.offset.top 21895 }; 21896 }, 21897 21898 _mouseDrag: function( event, noPropagation ) { 21899 21900 // reset any necessary cached properties (see #5009) 21901 if ( this.hasFixedAncestor ) { 21902 this.offset.parent = this._getParentOffset(); 21903 } 21904 21905 //Compute the helpers position 21906 this.position = this._generatePosition( event, true ); 21907 this.positionAbs = this._convertPositionTo( "absolute" ); 21908 21909 //Call plugins and callbacks and use the resulting position if something is returned 21910 if ( !noPropagation ) { 21911 var ui = this._uiHash(); 21912 if ( this._trigger( "drag", event, ui ) === false ) { 21913 this._mouseUp( new $.Event( "mouseup", event ) ); 21914 return false; 21915 } 21916 this.position = ui.position; 21917 } 21918 21919 this.helper[ 0 ].style.left = this.position.left + "px"; 21920 this.helper[ 0 ].style.top = this.position.top + "px"; 21921 21922 if ( $.ui.ddmanager ) { 21923 $.ui.ddmanager.drag( this, event ); 21924 } 21925 21926 return false; 21927 }, 21928 21929 _mouseStop: function( event ) { 21930 21931 //If we are using droppables, inform the manager about the drop 21932 var that = this, 21933 dropped = false; 21934 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 21935 dropped = $.ui.ddmanager.drop( this, event ); 21936 } 21937 21938 //if a drop comes from outside (a sortable) 21939 if ( this.dropped ) { 21940 dropped = this.dropped; 21941 this.dropped = false; 21942 } 21943 21944 if ( ( this.options.revert === "invalid" && !dropped ) || 21945 ( this.options.revert === "valid" && dropped ) || 21946 this.options.revert === true || ( typeof this.options.revert === "function" && 21947 this.options.revert.call( this.element, dropped ) ) 21948 ) { 21949 $( this.helper ).animate( 21950 this.originalPosition, 21951 parseInt( this.options.revertDuration, 10 ), 21952 function() { 21953 if ( that._trigger( "stop", event ) !== false ) { 21954 that._clear(); 21955 } 21956 } 21957 ); 21958 } else { 21959 if ( this._trigger( "stop", event ) !== false ) { 21960 this._clear(); 21961 } 21962 } 21963 21964 return false; 21965 }, 21966 21967 _mouseUp: function( event ) { 21968 this._unblockFrames(); 21969 21970 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 21971 // (see #5003) 21972 if ( $.ui.ddmanager ) { 21973 $.ui.ddmanager.dragStop( this, event ); 21974 } 21975 21976 // Only need to focus if the event occurred on the draggable itself, see #10527 21977 if ( this.handleElement.is( event.target ) ) { 21978 21979 // The interaction is over; whether or not the click resulted in a drag, 21980 // focus the element 21981 this.element.trigger( "focus" ); 21982 } 21983 21984 return $.ui.mouse.prototype._mouseUp.call( this, event ); 21985 }, 21986 21987 cancel: function() { 21988 21989 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 21990 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 21991 } else { 21992 this._clear(); 21993 } 21994 21995 return this; 21996 21997 }, 21998 21999 _getHandle: function( event ) { 22000 return this.options.handle ? 22001 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 22002 true; 22003 }, 22004 22005 _setHandleClassName: function() { 22006 this.handleElement = this.options.handle ? 22007 this.element.find( this.options.handle ) : this.element; 22008 this._addClass( this.handleElement, "ui-draggable-handle" ); 22009 }, 22010 22011 _removeHandleClassName: function() { 22012 this._removeClass( this.handleElement, "ui-draggable-handle" ); 22013 }, 22014 22015 _createHelper: function( event ) { 22016 22017 var o = this.options, 22018 helperIsFunction = typeof o.helper === "function", 22019 helper = helperIsFunction ? 22020 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 22021 ( o.helper === "clone" ? 22022 this.element.clone().removeAttr( "id" ) : 22023 this.element ); 22024 22025 if ( !helper.parents( "body" ).length ) { 22026 helper.appendTo( ( o.appendTo === "parent" ? 22027 this.element[ 0 ].parentNode : 22028 o.appendTo ) ); 22029 } 22030 22031 //
22031Http
vendor: 25,918 bytes, lines 22031-22898
22031://bugs.jqueryui.com/ticket/9446 22032 // a helper function can return the original element 22033 // which wouldn't have been set to relative in _create 22034 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 22035 this._setPositionRelative(); 22036 } 22037 22038 if ( helper[ 0 ] !== this.element[ 0 ] && 22039 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 22040 helper.css( "position", "absolute" ); 22041 } 22042 22043 return helper; 22044 22045 }, 22046 22047 _setPositionRelative: function() { 22048 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 22049 this.element[ 0 ].style.position = "relative"; 22050 } 22051 }, 22052 22053 _adjustOffsetFromHelper: function( obj ) { 22054 if ( typeof obj === "string" ) { 22055 obj = obj.split( " " ); 22056 } 22057 if ( Array.isArray( obj ) ) { 22058 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 22059 } 22060 if ( "left" in obj ) { 22061 this.offset.click.left = obj.left + this.margins.left; 22062 } 22063 if ( "right" in obj ) { 22064 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 22065 } 22066 if ( "top" in obj ) { 22067 this.offset.click.top = obj.top + this.margins.top; 22068 } 22069 if ( "bottom" in obj ) { 22070 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 22071 } 22072 }, 22073 22074 _isRootNode: function( element ) { 22075 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 22076 }, 22077 22078 _getParentOffset: function() { 22079 22080 //Get the offsetParent and cache its position 22081 var po = this.offsetParent.offset(), 22082 document = this.document[ 0 ]; 22083 22084 // This is a special case where we need to modify a offset calculated on start, since the 22085 // following happened: 22086 // 1. The position of the helper is absolute, so it's position is calculated based on the 22087 // next positioned parent 22088 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 22089 // the document, which means that the scroll is included in the initial calculation of the 22090 // offset of the parent, and never recalculated upon drag 22091 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 22092 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 22093 po.left += this.scrollParent.scrollLeft(); 22094 po.top += this.scrollParent.scrollTop(); 22095 } 22096 22097 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 22098 po = { top: 0, left: 0 }; 22099 } 22100 22101 return { 22102 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 22103 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 22104 }; 22105 22106 }, 22107 22108 _getRelativeOffset: function() { 22109 if ( this.cssPosition !== "relative" ) { 22110 return { top: 0, left: 0 }; 22111 } 22112 22113 var p = this.element.position(), 22114 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 22115 22116 return { 22117 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 22118 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 22119 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 22120 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 22121 }; 22122 22123 }, 22124 22125 _cacheMargins: function() { 22126 this.margins = { 22127 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 22128 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 22129 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 22130 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 22131 }; 22132 }, 22133 22134 _cacheHelperProportions: function() { 22135 this.helperProportions = { 22136 width: this.helper.outerWidth(), 22137 height: this.helper.outerHeight() 22138 }; 22139 }, 22140 22141 _setContainment: function() { 22142 22143 var isUserScrollable, c, ce, 22144 o = this.options, 22145 document = this.document[ 0 ]; 22146 22147 this.relativeContainer = null; 22148 22149 if ( !o.containment ) { 22150 this.containment = null; 22151 return; 22152 } 22153 22154 if ( o.containment === "window" ) { 22155 this.containment = [ 22156 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 22157 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 22158 $( window ).scrollLeft() + $( window ).width() - 22159 this.helperProportions.width - this.margins.left, 22160 $( window ).scrollTop() + 22161 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 22162 this.helperProportions.height - this.margins.top 22163 ]; 22164 return; 22165 } 22166 22167 if ( o.containment === "document" ) { 22168 this.containment = [ 22169 0, 22170 0, 22171 $( document ).width() - this.helperProportions.width - this.margins.left, 22172 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 22173 this.helperProportions.height - this.margins.top 22174 ]; 22175 return; 22176 } 22177 22178 if ( o.containment.constructor === Array ) { 22179 this.containment = o.containment; 22180 return; 22181 } 22182 22183 if ( o.containment === "parent" ) { 22184 o.containment = this.helper[ 0 ].parentNode; 22185 } 22186 22187 c = $( o.containment ); 22188 ce = c[ 0 ]; 22189 22190 if ( !ce ) { 22191 return; 22192 } 22193 22194 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 22195 22196 this.containment = [ 22197 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 22198 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 22199 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 22200 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 22201 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 22202 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 22203 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 22204 this.helperProportions.width - 22205 this.margins.left - 22206 this.margins.right, 22207 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 22208 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 22209 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 22210 this.helperProportions.height - 22211 this.margins.top - 22212 this.margins.bottom 22213 ]; 22214 this.relativeContainer = c; 22215 }, 22216 22217 _convertPositionTo: function( d, pos ) { 22218 22219 if ( !pos ) { 22220 pos = this.position; 22221 } 22222 22223 var mod = d === "absolute" ? 1 : -1, 22224 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 22225 22226 return { 22227 top: ( 22228 22229 // The absolute mouse position 22230 pos.top + 22231 22232 // Only for relative positioned nodes: Relative offset from element to offset parent 22233 this.offset.relative.top * mod + 22234 22235 // The offsetParent's offset without borders (offset + border) 22236 this.offset.parent.top * mod - 22237 ( ( this.cssPosition === "fixed" ? 22238 -this.offset.scroll.top : 22239 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 22240 ), 22241 left: ( 22242 22243 // The absolute mouse position 22244 pos.left + 22245 22246 // Only for relative positioned nodes: Relative offset from element to offset parent 22247 this.offset.relative.left * mod + 22248 22249 // The offsetParent's offset without borders (offset + border) 22250 this.offset.parent.left * mod - 22251 ( ( this.cssPosition === "fixed" ? 22252 -this.offset.scroll.left : 22253 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 22254 ) 22255 }; 22256 22257 }, 22258 22259 _generatePosition: function( event, constrainPosition ) { 22260 22261 var containment, co, top, left, 22262 o = this.options, 22263 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 22264 pageX = event.pageX, 22265 pageY = event.pageY; 22266 22267 // Cache the scroll 22268 if ( !scrollIsRootNode || !this.offset.scroll ) { 22269 this.offset.scroll = { 22270 top: this.scrollParent.scrollTop(), 22271 left: this.scrollParent.scrollLeft() 22272 }; 22273 } 22274 22275 /* 22276 * - Position constraining - 22277 * Constrain the position to a mix of grid, containment. 22278 */ 22279 22280 // If we are not dragging yet, we won't check for options 22281 if ( constrainPosition ) { 22282 if ( this.containment ) { 22283 if ( this.relativeContainer ) { 22284 co = this.relativeContainer.offset(); 22285 containment = [ 22286 this.containment[ 0 ] + co.left, 22287 this.containment[ 1 ] + co.top, 22288 this.containment[ 2 ] + co.left, 22289 this.containment[ 3 ] + co.top 22290 ]; 22291 } else { 22292 containment = this.containment; 22293 } 22294 22295 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 22296 pageX = containment[ 0 ] + this.offset.click.left; 22297 } 22298 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 22299 pageY = containment[ 1 ] + this.offset.click.top; 22300 } 22301 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 22302 pageX = containment[ 2 ] + this.offset.click.left; 22303 } 22304 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 22305 pageY = containment[ 3 ] + this.offset.click.top; 22306 } 22307 } 22308 22309 if ( o.grid ) { 22310 22311 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 22312 // argument errors in IE (see ticket #6950) 22313 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 22314 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 22315 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 22316 top - this.offset.click.top > containment[ 3 ] ) ? 22317 top : 22318 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 22319 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 22320 22321 left = o.grid[ 0 ] ? this.originalPageX + 22322 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 22323 this.originalPageX; 22324 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 22325 left - this.offset.click.left > containment[ 2 ] ) ? 22326 left : 22327 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 22328 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 22329 } 22330 22331 if ( o.axis === "y" ) { 22332 pageX = this.originalPageX; 22333 } 22334 22335 if ( o.axis === "x" ) { 22336 pageY = this.originalPageY; 22337 } 22338 } 22339 22340 return { 22341 top: ( 22342 22343 // The absolute mouse position 22344 pageY - 22345 22346 // Click offset (relative to the element) 22347 this.offset.click.top - 22348 22349 // Only for relative positioned nodes: Relative offset from element to offset parent 22350 this.offset.relative.top - 22351 22352 // The offsetParent's offset without borders (offset + border) 22353 this.offset.parent.top + 22354 ( this.cssPosition === "fixed" ? 22355 -this.offset.scroll.top : 22356 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 22357 ), 22358 left: ( 22359 22360 // The absolute mouse position 22361 pageX - 22362 22363 // Click offset (relative to the element) 22364 this.offset.click.left - 22365 22366 // Only for relative positioned nodes: Relative offset from element to offset parent 22367 this.offset.relative.left - 22368 22369 // The offsetParent's offset without borders (offset + border) 22370 this.offset.parent.left + 22371 ( this.cssPosition === "fixed" ? 22372 -this.offset.scroll.left : 22373 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 22374 ) 22375 }; 22376 22377 }, 22378 22379 _clear: function() { 22380 this._removeClass( this.helper, "ui-draggable-dragging" ); 22381 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 22382 this.helper.remove(); 22383 } 22384 this.helper = null; 22385 this.cancelHelperRemoval = false; 22386 if ( this.destroyOnClear ) { 22387 this.destroy(); 22388 } 22389 }, 22390 22391 // From now on bulk stuff - mainly helpers 22392 22393 _trigger: function( type, event, ui ) { 22394 ui = ui || this._uiHash(); 22395 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 22396 22397 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 22398 if ( /^(drag|start|stop)/.test( type ) ) { 22399 this.positionAbs = this._convertPositionTo( "absolute" ); 22400 ui.offset = this.positionAbs; 22401 } 22402 return $.Widget.prototype._trigger.call( this, type, event, ui ); 22403 }, 22404 22405 plugins: {}, 22406 22407 _uiHash: function() { 22408 return { 22409 helper: this.helper, 22410 position: this.position, 22411 originalPosition: this.originalPosition, 22412 offset: this.positionAbs 22413 }; 22414 } 22415 22416} ); 22417 22418$.ui.plugin.add( "draggable", "connectToSortable", { 22419 start: function( event, ui, draggable ) { 22420 var uiSortable = $.extend( {}, ui, { 22421 item: draggable.element 22422 } ); 22423 22424 draggable.sortables = []; 22425 $( draggable.options.connectToSortable ).each( function() { 22426 var sortable = $( this ).sortable( "instance" ); 22427 22428 if ( sortable && !sortable.options.disabled ) { 22429 draggable.sortables.push( sortable ); 22430 22431 // RefreshPositions is called at drag start to refresh the containerCache 22432 // which is used in drag. This ensures it's initialized and synchronized 22433 // with any changes that might have happened on the page since initialization. 22434 sortable.refreshPositions(); 22435 sortable._trigger( "activate", event, uiSortable ); 22436 } 22437 } ); 22438 }, 22439 stop: function( event, ui, draggable ) { 22440 var uiSortable = $.extend( {}, ui, { 22441 item: draggable.element 22442 } ); 22443 22444 draggable.cancelHelperRemoval = false; 22445 22446 $.each( draggable.sortables, function() { 22447 var sortable = this; 22448 22449 if ( sortable.isOver ) { 22450 sortable.isOver = 0; 22451 22452 // Allow this sortable to handle removing the helper 22453 draggable.cancelHelperRemoval = true; 22454 sortable.cancelHelperRemoval = false; 22455 22456 // Use _storedCSS To restore properties in the sortable, 22457 // as this also handles revert (#9675) since the draggable 22458 // may have modified them in unexpected ways (#8809) 22459 sortable._storedCSS = { 22460 position: sortable.placeholder.css( "position" ), 22461 top: sortable.placeholder.css( "top" ), 22462 left: sortable.placeholder.css( "left" ) 22463 }; 22464 22465 sortable._mouseStop( event ); 22466 22467 // Once drag has ended, the sortable should return to using 22468 // its original helper, not the shared helper from draggable 22469 sortable.options.helper = sortable.options._helper; 22470 } else { 22471 22472 // Prevent this Sortable from removing the helper. 22473 // However, don't set the draggable to remove the helper 22474 // either as another connected Sortable may yet handle the removal. 22475 sortable.cancelHelperRemoval = true; 22476 22477 sortable._trigger( "deactivate", event, uiSortable ); 22478 } 22479 } ); 22480 }, 22481 drag: function( event, ui, draggable ) { 22482 $.each( draggable.sortables, function() { 22483 var innermostIntersecting = false, 22484 sortable = this; 22485 22486 // Copy over variables that sortable's _intersectsWith uses 22487 sortable.positionAbs = draggable.positionAbs; 22488 sortable.helperProportions = draggable.helperProportions; 22489 sortable.offset.click = draggable.offset.click; 22490 22491 if ( sortable._intersectsWith( sortable.containerCache ) ) { 22492 innermostIntersecting = true; 22493 22494 $.each( draggable.sortables, function() { 22495 22496 // Copy over variables that sortable's _intersectsWith uses 22497 this.positionAbs = draggable.positionAbs; 22498 this.helperProportions = draggable.helperProportions; 22499 this.offset.click = draggable.offset.click; 22500 22501 if ( this !== sortable && 22502 this._intersectsWith( this.containerCache ) && 22503 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 22504 innermostIntersecting = false; 22505 } 22506 22507 return innermostIntersecting; 22508 } ); 22509 } 22510 22511 if ( innermostIntersecting ) { 22512 22513 // If it intersects, we use a little isOver variable and set it once, 22514 // so that the move-in stuff gets fired only once. 22515 if ( !sortable.isOver ) { 22516 sortable.isOver = 1; 22517 22518 // Store draggable's parent in case we need to reappend to it later. 22519 draggable._parent = ui.helper.parent(); 22520 22521 sortable.currentItem = ui.helper 22522 .appendTo( sortable.element ) 22523 .data( "ui-sortable-item", true ); 22524 22525 // Store helper option to later restore it 22526 sortable.options._helper = sortable.options.helper; 22527 22528 sortable.options.helper = function() { 22529 return ui.helper[ 0 ]; 22530 }; 22531 22532 // Fire the start events of the sortable with our passed browser event, 22533 // and our own helper (so it doesn't create a new one) 22534 event.target = sortable.currentItem[ 0 ]; 22535 sortable._mouseCapture( event, true ); 22536 sortable._mouseStart( event, true, true ); 22537 22538 // Because the browser event is way off the new appended portlet, 22539 // modify necessary variables to reflect the changes 22540 sortable.offset.click.top = draggable.offset.click.top; 22541 sortable.offset.click.left = draggable.offset.click.left; 22542 sortable.offset.parent.left -= draggable.offset.parent.left - 22543 sortable.offset.parent.left; 22544 sortable.offset.parent.top -= draggable.offset.parent.top - 22545 sortable.offset.parent.top; 22546 22547 draggable._trigger( "toSortable", event ); 22548 22549 // Inform draggable that the helper is in a valid drop zone, 22550 // used solely in the revert option to handle "valid/invalid". 22551 draggable.dropped = sortable.element; 22552 22553 // Need to refreshPositions of all sortables in the case that 22554 // adding to one sortable changes the location of the other sortables (#9675) 22555 $.each( draggable.sortables, function() { 22556 this.refreshPositions(); 22557 } ); 22558 22559 // Hack so receive/update callbacks work (mostly) 22560 draggable.currentItem = draggable.element; 22561 sortable.fromOutside = draggable; 22562 } 22563 22564 if ( sortable.currentItem ) { 22565 sortable._mouseDrag( event ); 22566 22567 // Copy the sortable's position because the draggable's can potentially reflect 22568 // a relative position, while sortable is always absolute, which the dragged 22569 // element has now become. (#8809) 22570 ui.position = sortable.position; 22571 } 22572 } else { 22573 22574 // If it doesn't intersect with the sortable, and it intersected before, 22575 // we fake the drag stop of the sortable, but make sure it doesn't remove 22576 // the helper by using cancelHelperRemoval. 22577 if ( sortable.isOver ) { 22578 22579 sortable.isOver = 0; 22580 sortable.cancelHelperRemoval = true; 22581 22582 // Calling sortable's mouseStop would trigger a revert, 22583 // so revert must be temporarily false until after mouseStop is called. 22584 sortable.options._revert = sortable.options.revert; 22585 sortable.options.revert = false; 22586 22587 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 22588 sortable._mouseStop( event, true ); 22589 22590 // Restore sortable behaviors that were modfied 22591 // when the draggable entered the sortable area (#9481) 22592 sortable.options.revert = sortable.options._revert; 22593 sortable.options.helper = sortable.options._helper; 22594 22595 if ( sortable.placeholder ) { 22596 sortable.placeholder.remove(); 22597 } 22598 22599 // Restore and recalculate the draggable's offset considering the sortable 22600 // may have modified them in unexpected ways. (#8809, #10669) 22601 ui.helper.appendTo( draggable._parent ); 22602 draggable._refreshOffsets( event ); 22603 ui.position = draggable._generatePosition( event, true ); 22604 22605 draggable._trigger( "fromSortable", event ); 22606 22607 // Inform draggable that the helper is no longer in a valid drop zone 22608 draggable.dropped = false; 22609 22610 // Need to refreshPositions of all sortables just in case removing 22611 // from one sortable changes the location of other sortables (#9675) 22612 $.each( draggable.sortables, function() { 22613 this.refreshPositions(); 22614 } ); 22615 } 22616 } 22617 } ); 22618 } 22619} ); 22620 22621$.ui.plugin.add( "draggable", "cursor", { 22622 start: function( event, ui, instance ) { 22623 var t = $( "body" ), 22624 o = instance.options; 22625 22626 if ( t.css( "cursor" ) ) { 22627 o._cursor = t.css( "cursor" ); 22628 } 22629 t.css( "cursor", o.cursor ); 22630 }, 22631 stop: function( event, ui, instance ) { 22632 var o = instance.options; 22633 if ( o._cursor ) { 22634 $( "body" ).css( "cursor", o._cursor ); 22635 } 22636 } 22637} ); 22638 22639$.ui.plugin.add( "draggable", "opacity", { 22640 start: function( event, ui, instance ) { 22641 var t = $( ui.helper ), 22642 o = instance.options; 22643 if ( t.css( "opacity" ) ) { 22644 o._opacity = t.css( "opacity" ); 22645 } 22646 t.css( "opacity", o.opacity ); 22647 }, 22648 stop: function( event, ui, instance ) { 22649 var o = instance.options; 22650 if ( o._opacity ) { 22651 $( ui.helper ).css( "opacity", o._opacity ); 22652 } 22653 } 22654} ); 22655 22656$.ui.plugin.add( "draggable", "scroll", { 22657 start: function( event, ui, i ) { 22658 if ( !i.scrollParentNotHidden ) { 22659 i.scrollParentNotHidden = i.helper.scrollParent( false ); 22660 } 22661 22662 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 22663 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 22664 i.overflowOffset = i.scrollParentNotHidden.offset(); 22665 } 22666 }, 22667 drag: function( event, ui, i ) { 22668 22669 var o = i.options, 22670 scrolled = false, 22671 scrollParent = i.scrollParentNotHidden[ 0 ], 22672 document = i.document[ 0 ]; 22673 22674 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 22675 if ( !o.axis || o.axis !== "x" ) { 22676 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 22677 o.scrollSensitivity ) { 22678 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 22679 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 22680 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 22681 } 22682 } 22683 22684 if ( !o.axis || o.axis !== "y" ) { 22685 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 22686 o.scrollSensitivity ) { 22687 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 22688 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 22689 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 22690 } 22691 } 22692 22693 } else { 22694 22695 if ( !o.axis || o.axis !== "x" ) { 22696 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 22697 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 22698 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 22699 o.scrollSensitivity ) { 22700 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 22701 } 22702 } 22703 22704 if ( !o.axis || o.axis !== "y" ) { 22705 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 22706 scrolled = $( document ).scrollLeft( 22707 $( document ).scrollLeft() - o.scrollSpeed 22708 ); 22709 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 22710 o.scrollSensitivity ) { 22711 scrolled = $( document ).scrollLeft( 22712 $( document ).scrollLeft() + o.scrollSpeed 22713 ); 22714 } 22715 } 22716 22717 } 22718 22719 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 22720 $.ui.ddmanager.prepareOffsets( i, event ); 22721 } 22722 22723 } 22724} ); 22725 22726$.ui.plugin.add( "draggable", "snap", { 22727 start: function( event, ui, i ) { 22728 22729 var o = i.options; 22730 22731 i.snapElements = []; 22732 22733 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 22734 .each( function() { 22735 var $t = $( this ), 22736 $o = $t.offset(); 22737 if ( this !== i.element[ 0 ] ) { 22738 i.snapElements.push( { 22739 item: this, 22740 width: $t.outerWidth(), height: $t.outerHeight(), 22741 top: $o.top, left: $o.left 22742 } ); 22743 } 22744 } ); 22745 22746 }, 22747 drag: function( event, ui, inst ) { 22748 22749 var ts, bs, ls, rs, l, r, t, b, i, first, 22750 o = inst.options, 22751 d = o.snapTolerance, 22752 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 22753 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 22754 22755 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 22756 22757 l = inst.snapElements[ i ].left - inst.margins.left; 22758 r = l + inst.snapElements[ i ].width; 22759 t = inst.snapElements[ i ].top - inst.margins.top; 22760 b = t + inst.snapElements[ i ].height; 22761 22762 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 22763 !$.contains( inst.snapElements[ i ].item.ownerDocument, 22764 inst.snapElements[ i ].item ) ) { 22765 if ( inst.snapElements[ i ].snapping ) { 22766 if ( inst.options.snap.release ) { 22767 inst.options.snap.release.call( 22768 inst.element, 22769 event, 22770 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 22771 ); 22772 } 22773 } 22774 inst.snapElements[ i ].snapping = false; 22775 continue; 22776 } 22777 22778 if ( o.snapMode !== "inner" ) { 22779 ts = Math.abs( t - y2 ) <= d; 22780 bs = Math.abs( b - y1 ) <= d; 22781 ls = Math.abs( l - x2 ) <= d; 22782 rs = Math.abs( r - x1 ) <= d; 22783 if ( ts ) { 22784 ui.position.top = inst._convertPositionTo( "relative", { 22785 top: t - inst.helperProportions.height, 22786 left: 0 22787 } ).top; 22788 } 22789 if ( bs ) { 22790 ui.position.top = inst._convertPositionTo( "relative", { 22791 top: b, 22792 left: 0 22793 } ).top; 22794 } 22795 if ( ls ) { 22796 ui.position.left = inst._convertPositionTo( "relative", { 22797 top: 0, 22798 left: l - inst.helperProportions.width 22799 } ).left; 22800 } 22801 if ( rs ) { 22802 ui.position.left = inst._convertPositionTo( "relative", { 22803 top: 0, 22804 left: r 22805 } ).left; 22806 } 22807 } 22808 22809 first = ( ts || bs || ls || rs ); 22810 22811 if ( o.snapMode !== "outer" ) { 22812 ts = Math.abs( t - y1 ) <= d; 22813 bs = Math.abs( b - y2 ) <= d; 22814 ls = Math.abs( l - x1 ) <= d; 22815 rs = Math.abs( r - x2 ) <= d; 22816 if ( ts ) { 22817 ui.position.top = inst._convertPositionTo( "relative", { 22818 top: t, 22819 left: 0 22820 } ).top; 22821 } 22822 if ( bs ) { 22823 ui.position.top = inst._convertPositionTo( "relative", { 22824 top: b - inst.helperProportions.height, 22825 left: 0 22826 } ).top; 22827 } 22828 if ( ls ) { 22829 ui.position.left = inst._convertPositionTo( "relative", { 22830 top: 0, 22831 left: l 22832 } ).left; 22833 } 22834 if ( rs ) { 22835 ui.position.left = inst._convertPositionTo( "relative", { 22836 top: 0, 22837 left: r - inst.helperProportions.width 22838 } ).left; 22839 } 22840 } 22841 22842 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 22843 if ( inst.options.snap.snap ) { 22844 inst.options.snap.snap.call( 22845 inst.element, 22846 event, 22847 $.extend( inst._uiHash(), { 22848 snapItem: inst.snapElements[ i ].item 22849 } ) ); 22850 } 22851 } 22852 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 22853 22854 } 22855 22856 } 22857} ); 22858 22859$.ui.plugin.add( "draggable", "stack", { 22860 start: function( event, ui, instance ) { 22861 var min, 22862 o = instance.options, 22863 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 22864 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 22865 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 22866 } ); 22867 22868 if ( !group.length ) { 22869 return; 22870 } 22871 22872 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 22873 $( group ).each( function( i ) { 22874 $( this ).css( "zIndex", min + i ); 22875 } ); 22876 this.css( "zIndex", ( min + group.length ) ); 22877 } 22878} ); 22879 22880$.ui.plugin.add( "draggable", "zIndex", { 22881 start: function( event, ui, instance ) { 22882 var t = $( ui.helper ), 22883 o = instance.options; 22884 22885 if ( t.css( "zIndex" ) ) { 22886 o._zIndex = t.css( "zIndex" ); 22887 } 22888 t.css( "zIndex", o.zIndex ); 22889 }, 22890 stop: function( event, ui, instance ) { 22891 var o = instance.options; 22892 22893 if ( o._zIndex ) { 22894 $( ui.helper ).css( "zIndex", o._zIndex ); 22895 } 22896 } 22897} ); 22898
22899return $.ui.draggable; 22900 22901} ); 22902 22903 22904 22905 22906 22907 22908/*! 22909 * jQuery UI Resizable 1.13.0 22910 * http://jqueryui.com 22911 * 22912 * Copyright jQuery Foundation and other contributors 22913 * Released under the MIT license. 22914 * http://jquery.org/license 22915 */ 22916 22917//>>label: Resizable 22918//>>group: Interactions 22919//>>description: Enables resize functionality for any element. 22920//>>docs: http://api.jqueryui.com/resizable/ 22921//>>demos: http://jqueryui.com/resizable/ 22922//>>css.structure: ../../themes/base/core.css 22923//>>css.structure: ../../themes/base/resizable.css 22924//>>css.theme: ../../themes/base/theme.css 22925 22926( function( factory ) { 22927 "use strict"; 22928 22929 if ( typeof define === "function" && define.amd ) { 22930 22931 // AMD. Register as an anonymous module. 22932 define( [ 22933 "jquery", 22934 "./mouse", 22935 "../disable-selection", 22936 "../plugin", 22937 "../version", 22938 "../widget" 22939 ], factory ); 22940 } else { 22941 22942 // Browser globals 22943 factory( jQuery ); 22944 } 22945} )( function( $ ) { 22946"use strict"; 22947 22948$.widget( "ui.resizable", $.ui.mouse, { 22949 version: "1.13.0
vendor: 11,739 bytes, lines 22949-23442
22949", 22950 widgetEventPrefix: "resize", 22951 options: { 22952 alsoResize: false, 22953 animate: false, 22954 animateDuration: "slow", 22955 animateEasing: "swing", 22956 aspectRatio: false, 22957 autoHide: false, 22958 classes: { 22959 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 22960 }, 22961 containment: false, 22962 ghost: false, 22963 grid: false, 22964 handles: "e,s,se", 22965 helper: false, 22966 maxHeight: null, 22967 maxWidth: null, 22968 minHeight: 10, 22969 minWidth: 10, 22970 22971 // See #7960 22972 zIndex: 90, 22973 22974 // Callbacks 22975 resize: null, 22976 start: null, 22977 stop: null 22978 }, 22979 22980 _num: function( value ) { 22981 return parseFloat( value ) || 0; 22982 }, 22983 22984 _isNumber: function( value ) { 22985 return !isNaN( parseFloat( value ) ); 22986 }, 22987 22988 _hasScroll: function( el, a ) { 22989 22990 if ( $( el ).css( "overflow" ) === "hidden" ) { 22991 return false; 22992 } 22993 22994 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 22995 has = false; 22996 22997 if ( el[ scroll ] > 0 ) { 22998 return true; 22999 } 23000 23001 // TODO: determine which cases actually cause this to happen 23002 // if the element doesn't have the scroll set, see if it's possible to 23003 // set the scroll 23004 try { 23005 el[ scroll ] = 1; 23006 has = ( el[ scroll ] > 0 ); 23007 el[ scroll ] = 0; 23008 } catch ( e ) { 23009 23010 // `el` might be a string, then setting `scroll` will throw 23011 // an error in strict mode; ignore it. 23012 } 23013 return has; 23014 }, 23015 23016 _create: function() { 23017 23018 var margins, 23019 o = this.options, 23020 that = this; 23021 this._addClass( "ui-resizable" ); 23022 23023 $.extend( this, { 23024 _aspectRatio: !!( o.aspectRatio ), 23025 aspectRatio: o.aspectRatio, 23026 originalElement: this.element, 23027 _proportionallyResizeElements: [], 23028 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 23029 } ); 23030 23031 // Wrap the element if it cannot hold child nodes 23032 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 23033 23034 this.element.wrap( 23035 $( "<div class='ui-wrapper'></div>" ).css( { 23036 overflow: "hidden", 23037 position: this.element.css( "position" ), 23038 width: this.element.outerWidth(), 23039 height: this.element.outerHeight(), 23040 top: this.element.css( "top" ), 23041 left: this.element.css( "left" ) 23042 } ) 23043 ); 23044 23045 this.element = this.element.parent().data( 23046 "ui-resizable", this.element.resizable( "instance" ) 23047 ); 23048 23049 this.elementIsWrapper = true; 23050 23051 margins = { 23052 marginTop: this.originalElement.css( "marginTop" ), 23053 marginRight: this.originalElement.css( "marginRight" ), 23054 marginBottom: this.originalElement.css( "marginBottom" ), 23055 marginLeft: this.originalElement.css( "marginLeft" ) 23056 }; 23057 23058 this.element.css( margins ); 23059 this.originalElement.css( "margin", 0 ); 23060 23061 // support: Safari 23062 // Prevent Safari textarea resize 23063 this.originalResizeStyle = this.originalElement.css( "resize" ); 23064 this.originalElement.css( "resize", "none" ); 23065 23066 this._proportionallyResizeElements.push( this.originalElement.css( { 23067 position: "static", 23068 zoom: 1, 23069 display: "block" 23070 } ) ); 23071 23072 // Support: IE9 23073 // avoid IE jump (hard set the margin) 23074 this.originalElement.css( margins ); 23075 23076 this._proportionallyResize(); 23077 } 23078 23079 this._setupHandles(); 23080 23081 if ( o.autoHide ) { 23082 $( this.element ) 23083 .on( "mouseenter", function() { 23084 if ( o.disabled ) { 23085 return; 23086 } 23087 that._removeClass( "ui-resizable-autohide" ); 23088 that._handles.show(); 23089 } ) 23090 .on( "mouseleave", function() { 23091 if ( o.disabled ) { 23092 return; 23093 } 23094 if ( !that.resizing ) { 23095 that._addClass( "ui-resizable-autohide" ); 23096 that._handles.hide(); 23097 } 23098 } ); 23099 } 23100 23101 this._mouseInit(); 23102 }, 23103 23104 _destroy: function() { 23105 23106 this._mouseDestroy(); 23107 this._addedHandles.remove(); 23108 23109 var wrapper, 23110 _destroy = function( exp ) { 23111 $( exp ) 23112 .removeData( "resizable" ) 23113 .removeData( "ui-resizable" ) 23114 .off( ".resizable" ); 23115 }; 23116 23117 // TODO: Unwrap at same DOM position 23118 if ( this.elementIsWrapper ) { 23119 _destroy( this.element ); 23120 wrapper = this.element; 23121 this.originalElement.css( { 23122 position: wrapper.css( "position" ), 23123 width: wrapper.outerWidth(), 23124 height: wrapper.outerHeight(), 23125 top: wrapper.css( "top" ), 23126 left: wrapper.css( "left" ) 23127 } ).insertAfter( wrapper ); 23128 wrapper.remove(); 23129 } 23130 23131 this.originalElement.css( "resize", this.originalResizeStyle ); 23132 _destroy( this.originalElement ); 23133 23134 return this; 23135 }, 23136 23137 _setOption: function( key, value ) { 23138 this._super( key, value ); 23139 23140 switch ( key ) { 23141 case "handles": 23142 this._removeHandles(); 23143 this._setupHandles(); 23144 break; 23145 case "aspectRatio": 23146 this._aspectRatio = !!value; 23147 break; 23148 default: 23149 break; 23150 } 23151 }, 23152 23153 _setupHandles: function() { 23154 var o = this.options, handle, i, n, hname, axis, that = this; 23155 this.handles = o.handles || 23156 ( !$( ".ui-resizable-handle", this.element ).length ? 23157 "e,s,se" : { 23158 n: ".ui-resizable-n", 23159 e: ".ui-resizable-e", 23160 s: ".ui-resizable-s", 23161 w: ".ui-resizable-w", 23162 se: ".ui-resizable-se", 23163 sw: ".ui-resizable-sw", 23164 ne: ".ui-resizable-ne", 23165 nw: ".ui-resizable-nw" 23166 } ); 23167 23168 this._handles = $(); 23169 this._addedHandles = $(); 23170 if ( this.handles.constructor === String ) { 23171 23172 if ( this.handles === "all" ) { 23173 this.handles = "n,e,s,w,se,sw,ne,nw"; 23174 } 23175 23176 n = this.handles.split( "," ); 23177 this.handles = {}; 23178 23179 for ( i = 0; i < n.length; i++ ) { 23180 23181 handle = String.prototype.trim.call( n[ i ] ); 23182 hname = "ui-resizable-" + handle; 23183 axis = $( "<div>" ); 23184 this._addClass( axis, "ui-resizable-handle " + hname ); 23185 23186 axis.css( { zIndex: o.zIndex } ); 23187 23188 this.handles[ handle ] = ".ui-resizable-" + handle; 23189 if ( !this.element.children( this.handles[ handle ] ).length ) { 23190 this.element.append( axis ); 23191 this._addedHandles = this._addedHandles.add( axis ); 23192 } 23193 } 23194 23195 } 23196 23197 this._renderAxis = function( target ) { 23198 23199 var i, axis, padPos, padWrapper; 23200 23201 target = target || this.element; 23202 23203 for ( i in this.handles ) { 23204 23205 if ( this.handles[ i ].constructor === String ) { 23206 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 23207 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 23208 this.handles[ i ] = $( this.handles[ i ] ); 23209 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 23210 } 23211 23212 if ( this.elementIsWrapper && 23213 this.originalElement[ 0 ] 23214 .nodeName 23215 .match( /^(textarea|input|select|button)$/i ) ) { 23216 axis = $( this.handles[ i ], this.element ); 23217 23218 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 23219 axis.outerHeight() : 23220 axis.outerWidth(); 23221 23222 padPos = [ "padding", 23223 /ne|nw|n/.test( i ) ? "Top" : 23224 /se|sw|s/.test( i ) ? "Bottom" : 23225 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 23226 23227 target.css( padPos, padWrapper ); 23228 23229 this._proportionallyResize(); 23230 } 23231 23232 this._handles = this._handles.add( this.handles[ i ] ); 23233 } 23234 }; 23235 23236 // TODO: make renderAxis a prototype function 23237 this._renderAxis( this.element ); 23238 23239 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 23240 this._handles.disableSelection(); 23241 23242 this._handles.on( "mouseover", function() { 23243 if ( !that.resizing ) { 23244 if ( this.className ) { 23245 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 23246 } 23247 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 23248 } 23249 } ); 23250 23251 if ( o.autoHide ) { 23252 this._handles.hide(); 23253 this._addClass( "ui-resizable-autohide" ); 23254 } 23255 }, 23256 23257 _removeHandles: function() { 23258 this._addedHandles.remove(); 23259 }, 23260 23261 _mouseCapture: function( event ) { 23262 var i, handle, 23263 capture = false; 23264 23265 for ( i in this.handles ) { 23266 handle = $( this.handles[ i ] )[ 0 ]; 23267 if ( handle === event.target || $.contains( handle, event.target ) ) { 23268 capture = true; 23269 } 23270 } 23271 23272 return !this.options.disabled && capture; 23273 }, 23274 23275 _mouseStart: function( event ) { 23276 23277 var curleft, curtop, cursor, 23278 o = this.options, 23279 el = this.element; 23280 23281 this.resizing = true; 23282 23283 this._renderProxy(); 23284 23285 curleft = this._num( this.helper.css( "left" ) ); 23286 curtop = this._num( this.helper.css( "top" ) ); 23287 23288 if ( o.containment ) { 23289 curleft += $( o.containment ).scrollLeft() || 0; 23290 curtop += $( o.containment ).scrollTop() || 0; 23291 } 23292 23293 this.offset = this.helper.offset(); 23294 this.position = { left: curleft, top: curtop }; 23295 23296 this.size = this._helper ? { 23297 width: this.helper.width(), 23298 height: this.helper.height() 23299 } : { 23300 width: el.width(), 23301 height: el.height() 23302 }; 23303 23304 this.originalSize = this._helper ? { 23305 width: el.outerWidth(), 23306 height: el.outerHeight() 23307 } : { 23308 width: el.width(), 23309 height: el.height() 23310 }; 23311 23312 this.sizeDiff = { 23313 width: el.outerWidth() - el.width(), 23314 height: el.outerHeight() - el.height() 23315 }; 23316 23317 this.originalPosition = { left: curleft, top: curtop }; 23318 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 23319 23320 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 23321 o.aspectRatio : 23322 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 23323 23324 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 23325 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 23326 23327 this._addClass( "ui-resizable-resizing" ); 23328 this._propagate( "start", event ); 23329 return true; 23330 }, 23331 23332 _mouseDrag: function( event ) { 23333 23334 var data, props, 23335 smp = this.originalMousePosition, 23336 a = this.axis, 23337 dx = ( event.pageX - smp.left ) || 0, 23338 dy = ( event.pageY - smp.top ) || 0, 23339 trigger = this._change[ a ]; 23340 23341 this._updatePrevProperties(); 23342 23343 if ( !trigger ) { 23344 return false; 23345 } 23346 23347 data = trigger.apply( this, [ event, dx, dy ] ); 23348 23349 this._updateVirtualBoundaries( event.shiftKey ); 23350 if ( this._aspectRatio || event.shiftKey ) { 23351 data = this._updateRatio( data, event ); 23352 } 23353 23354 data = this._respectSize( data, event ); 23355 23356 this._updateCache( data ); 23357 23358 this._propagate( "resize", event ); 23359 23360 props = this._applyChanges(); 23361 23362 if ( !this._helper && this._proportionallyResizeElements.length ) { 23363 this._proportionallyResize(); 23364 } 23365 23366 if ( !$.isEmptyObject( props ) ) { 23367 this._updatePrevProperties(); 23368 this._trigger( "resize", event, this.ui() ); 23369 this._applyChanges(); 23370 } 23371 23372 return false; 23373 }, 23374 23375 _mouseStop: function( event ) { 23376 23377 this.resizing = false; 23378 var pr, ista, soffseth, soffsetw, s, left, top, 23379 o = this.options, that = this; 23380 23381 if ( this._helper ) { 23382 23383 pr = this._proportionallyResizeElements; 23384 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 23385 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 23386 soffsetw = ista ? 0 : that.sizeDiff.width; 23387 23388 s = { 23389 width: ( that.helper.width() - soffsetw ), 23390 height: ( that.helper.height() - soffseth ) 23391 }; 23392 left = ( parseFloat( that.element.css( "left" ) ) + 23393 ( that.position.left - that.originalPosition.left ) ) || null; 23394 top = ( parseFloat( that.element.css( "top" ) ) + 23395 ( that.position.top - that.originalPosition.top ) ) || null; 23396 23397 if ( !o.animate ) { 23398 this.element.css( $.extend( s, { top: top, left: left } ) ); 23399 } 23400 23401 that.helper.height( that.size.height ); 23402 that.helper.width( that.size.width ); 23403 23404 if ( this._helper && !o.animate ) { 23405 this._proportionallyResize(); 23406 } 23407 } 23408 23409 $( "body" ).css( "cursor", "auto" ); 23410 23411 this._removeClass( "ui-resizable-resizing" ); 23412 23413 this._propagate( "stop", event ); 23414 23415 if ( this._helper ) { 23416 this.helper.remove(); 23417 } 23418 23419 return false; 23420 23421 }, 23422 23423 _updatePrevProperties: function() { 23424 this.prevPosition = { 23425 top: this.position.top, 23426 left: this.position.left 23427 }; 23428 this.prevSize = { 23429 width: this.size.width, 23430 height: this.size.height 23431 }; 23432 }, 23433 23434 _applyChanges: function() { 23435 var props = {}; 23436 23437 if ( this.position.top !== this.prevPosition.top ) { 23438 props.top = this.position.top + "px"; 23439 } 23440 if ( this.position.left !== this.prevPosition.left ) { 23441 props.left = this.position.left + "px"; 23442 }
vendor: 9,533 bytes, lines 23443-23810
23443 if ( this.size.width !== this.prevSize.width ) { 23444 props.width = this.size.width + "px"; 23445 } 23446 if ( this.size.height !== this.prevSize.height ) { 23447 props.height = this.size.height + "px"; 23448 } 23449 23450 this.helper.css( props ); 23451 23452 return props; 23453 }, 23454 23455 _updateVirtualBoundaries: function( forceAspectRatio ) { 23456 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 23457 o = this.options; 23458 23459 b = { 23460 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 23461 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 23462 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 23463 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 23464 }; 23465 23466 if ( this._aspectRatio || forceAspectRatio ) { 23467 pMinWidth = b.minHeight * this.aspectRatio; 23468 pMinHeight = b.minWidth / this.aspectRatio; 23469 pMaxWidth = b.maxHeight * this.aspectRatio; 23470 pMaxHeight = b.maxWidth / this.aspectRatio; 23471 23472 if ( pMinWidth > b.minWidth ) { 23473 b.minWidth = pMinWidth; 23474 } 23475 if ( pMinHeight > b.minHeight ) { 23476 b.minHeight = pMinHeight; 23477 } 23478 if ( pMaxWidth < b.maxWidth ) { 23479 b.maxWidth = pMaxWidth; 23480 } 23481 if ( pMaxHeight < b.maxHeight ) { 23482 b.maxHeight = pMaxHeight; 23483 } 23484 } 23485 this._vBoundaries = b; 23486 }, 23487 23488 _updateCache: function( data ) { 23489 this.offset = this.helper.offset(); 23490 if ( this._isNumber( data.left ) ) { 23491 this.position.left = data.left; 23492 } 23493 if ( this._isNumber( data.top ) ) { 23494 this.position.top = data.top; 23495 } 23496 if ( this._isNumber( data.height ) ) { 23497 this.size.height = data.height; 23498 } 23499 if ( this._isNumber( data.width ) ) { 23500 this.size.width = data.width; 23501 } 23502 }, 23503 23504 _updateRatio: function( data ) { 23505 23506 var cpos = this.position, 23507 csize = this.size, 23508 a = this.axis; 23509 23510 if ( this._isNumber( data.height ) ) { 23511 data.width = ( data.height * this.aspectRatio ); 23512 } else if ( this._isNumber( data.width ) ) { 23513 data.height = ( data.width / this.aspectRatio ); 23514 } 23515 23516 if ( a === "sw" ) { 23517 data.left = cpos.left + ( csize.width - data.width ); 23518 data.top = null; 23519 } 23520 if ( a === "nw" ) { 23521 data.top = cpos.top + ( csize.height - data.height ); 23522 data.left = cpos.left + ( csize.width - data.width ); 23523 } 23524 23525 return data; 23526 }, 23527 23528 _respectSize: function( data ) { 23529 23530 var o = this._vBoundaries, 23531 a = this.axis, 23532 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 23533 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 23534 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 23535 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 23536 dw = this.originalPosition.left + this.originalSize.width, 23537 dh = this.originalPosition.top + this.originalSize.height, 23538 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 23539 if ( isminw ) { 23540 data.width = o.minWidth; 23541 } 23542 if ( isminh ) { 23543 data.height = o.minHeight; 23544 } 23545 if ( ismaxw ) { 23546 data.width = o.maxWidth; 23547 } 23548 if ( ismaxh ) { 23549 data.height = o.maxHeight; 23550 } 23551 23552 if ( isminw && cw ) { 23553 data.left = dw - o.minWidth; 23554 } 23555 if ( ismaxw && cw ) { 23556 data.left = dw - o.maxWidth; 23557 } 23558 if ( isminh && ch ) { 23559 data.top = dh - o.minHeight; 23560 } 23561 if ( ismaxh && ch ) { 23562 data.top = dh - o.maxHeight; 23563 } 23564 23565 // Fixing jump error on top/left - bug #2330 23566 if ( !data.width && !data.height && !data.left && data.top ) { 23567 data.top = null; 23568 } else if ( !data.width && !data.height && !data.top && data.left ) { 23569 data.left = null; 23570 } 23571 23572 return data; 23573 }, 23574 23575 _getPaddingPlusBorderDimensions: function( element ) { 23576 var i = 0, 23577 widths = [], 23578 borders = [ 23579 element.css( "borderTopWidth" ), 23580 element.css( "borderRightWidth" ), 23581 element.css( "borderBottomWidth" ), 23582 element.css( "borderLeftWidth" ) 23583 ], 23584 paddings = [ 23585 element.css( "paddingTop" ), 23586 element.css( "paddingRight" ), 23587 element.css( "paddingBottom" ), 23588 element.css( "paddingLeft" ) 23589 ]; 23590 23591 for ( ; i < 4; i++ ) { 23592 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 23593 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 23594 } 23595 23596 return { 23597 height: widths[ 0 ] + widths[ 2 ], 23598 width: widths[ 1 ] + widths[ 3 ] 23599 }; 23600 }, 23601 23602 _proportionallyResize: function() { 23603 23604 if ( !this._proportionallyResizeElements.length ) { 23605 return; 23606 } 23607 23608 var prel, 23609 i = 0, 23610 element = this.helper || this.element; 23611 23612 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 23613 23614 prel = this._proportionallyResizeElements[ i ]; 23615 23616 // TODO: Seems like a bug to cache this.outerDimensions 23617 // considering that we are in a loop. 23618 if ( !this.outerDimensions ) { 23619 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 23620 } 23621 23622 prel.css( { 23623 height: ( element.height() - this.outerDimensions.height ) || 0, 23624 width: ( element.width() - this.outerDimensions.width ) || 0 23625 } ); 23626 23627 } 23628 23629 }, 23630 23631 _renderProxy: function() { 23632 23633 var el = this.element, o = this.options; 23634 this.elementOffset = el.offset(); 23635 23636 if ( this._helper ) { 23637 23638 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); 23639 23640 this._addClass( this.helper, this._helper ); 23641 this.helper.css( { 23642 width: this.element.outerWidth(), 23643 height: this.element.outerHeight(), 23644 position: "absolute", 23645 left: this.elementOffset.left + "px", 23646 top: this.elementOffset.top + "px", 23647 zIndex: ++o.zIndex //TODO: Don't modify option 23648 } ); 23649 23650 this.helper 23651 .appendTo( "body" ) 23652 .disableSelection(); 23653 23654 } else { 23655 this.helper = this.element; 23656 } 23657 23658 }, 23659 23660 _change: { 23661 e: function( event, dx ) { 23662 return { width: this.originalSize.width + dx }; 23663 }, 23664 w: function( event, dx ) { 23665 var cs = this.originalSize, sp = this.originalPosition; 23666 return { left: sp.left + dx, width: cs.width - dx }; 23667 }, 23668 n: function( event, dx, dy ) { 23669 var cs = this.originalSize, sp = this.originalPosition; 23670 return { top: sp.top + dy, height: cs.height - dy }; 23671 }, 23672 s: function( event, dx, dy ) { 23673 return { height: this.originalSize.height + dy }; 23674 }, 23675 se: function( event, dx, dy ) { 23676 return $.extend( this._change.s.apply( this, arguments ), 23677 this._change.e.apply( this, [ event, dx, dy ] ) ); 23678 }, 23679 sw: function( event, dx, dy ) { 23680 return $.extend( this._change.s.apply( this, arguments ), 23681 this._change.w.apply( this, [ event, dx, dy ] ) ); 23682 }, 23683 ne: function( event, dx, dy ) { 23684 return $.extend( this._change.n.apply( this, arguments ), 23685 this._change.e.apply( this, [ event, dx, dy ] ) ); 23686 }, 23687 nw: function( event, dx, dy ) { 23688 return $.extend( this._change.n.apply( this, arguments ), 23689 this._change.w.apply( this, [ event, dx, dy ] ) ); 23690 } 23691 }, 23692 23693 _propagate: function( n, event ) { 23694 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 23695 if ( n !== "resize" ) { 23696 this._trigger( n, event, this.ui() ); 23697 } 23698 }, 23699 23700 plugins: {}, 23701 23702 ui: function() { 23703 return { 23704 originalElement: this.originalElement, 23705 element: this.element, 23706 helper: this.helper, 23707 position: this.position, 23708 size: this.size, 23709 originalSize: this.originalSize, 23710 originalPosition: this.originalPosition 23711 }; 23712 } 23713 23714} ); 23715 23716/* 23717 * Resizable Extensions 23718 */ 23719 23720$.ui.plugin.add( "resizable", "animate", { 23721 23722 stop: function( event ) { 23723 var that = $( this ).resizable( "instance" ), 23724 o = that.options, 23725 pr = that._proportionallyResizeElements, 23726 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 23727 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 23728 soffsetw = ista ? 0 : that.sizeDiff.width, 23729 style = { 23730 width: ( that.size.width - soffsetw ), 23731 height: ( that.size.height - soffseth ) 23732 }, 23733 left = ( parseFloat( that.element.css( "left" ) ) + 23734 ( that.position.left - that.originalPosition.left ) ) || null, 23735 top = ( parseFloat( that.element.css( "top" ) ) + 23736 ( that.position.top - that.originalPosition.top ) ) || null; 23737 23738 that.element.animate( 23739 $.extend( style, top && left ? { top: top, left: left } : {} ), { 23740 duration: o.animateDuration, 23741 easing: o.animateEasing, 23742 step: function() { 23743 23744 var data = { 23745 width: parseFloat( that.element.css( "width" ) ), 23746 height: parseFloat( that.element.css( "height" ) ), 23747 top: parseFloat( that.element.css( "top" ) ), 23748 left: parseFloat( that.element.css( "left" ) ) 23749 }; 23750 23751 if ( pr && pr.length ) { 23752 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 23753 } 23754 23755 // Propagating resize, and updating values for each animation step 23756 that._updateCache( data ); 23757 that._propagate( "resize", event ); 23758 23759 } 23760 } 23761 ); 23762 } 23763 23764} ); 23765 23766$.ui.plugin.add( "resizable", "containment", { 23767 23768 start: function() { 23769 var element, p, co, ch, cw, width, height, 23770 that = $( this ).resizable( "instance" ), 23771 o = that.options, 23772 el = that.element, 23773 oc = o.containment, 23774 ce = ( oc instanceof $ ) ? 23775 oc.get( 0 ) : 23776 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 23777 23778 if ( !ce ) { 23779 return; 23780 } 23781 23782 that.containerElement = $( ce ); 23783 23784 if ( /document/.test( oc ) || oc === document ) { 23785 that.containerOffset = { 23786 left: 0, 23787 top: 0 23788 }; 23789 that.containerPosition = { 23790 left: 0, 23791 top: 0 23792 }; 23793 23794 that.parentData = { 23795 element: $( document ), 23796 left: 0, 23797 top: 0, 23798 width: $( document ).width(), 23799 height: $( document ).height() || document.body.parentNode.scrollHeight 23800 }; 23801 } else { 23802 element = $( ce ); 23803 p = []; 23804 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 23805 p[ i ] = that._num( element.css( "padding" + name ) ); 23806 } ); 23807 23808 that.containerOffset = element.offset(); 23809 that.containerPosition = element.position(); 23810 that.containerSize = {
vendor: 5,871 bytes, lines 23811-24035
23811 height: ( element.innerHeight() - p[ 3 ] ), 23812 width: ( element.innerWidth() - p[ 1 ] ) 23813 }; 23814 23815 co = that.containerOffset; 23816 ch = that.containerSize.height; 23817 cw = that.containerSize.width; 23818 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); 23819 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); 23820 23821 that.parentData = { 23822 element: ce, 23823 left: co.left, 23824 top: co.top, 23825 width: width, 23826 height: height 23827 }; 23828 } 23829 }, 23830 23831 resize: function( event ) { 23832 var woset, hoset, isParent, isOffsetRelative, 23833 that = $( this ).resizable( "instance" ), 23834 o = that.options, 23835 co = that.containerOffset, 23836 cp = that.position, 23837 pRatio = that._aspectRatio || event.shiftKey, 23838 cop = { 23839 top: 0, 23840 left: 0 23841 }, 23842 ce = that.containerElement, 23843 continueResize = true; 23844 23845 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 23846 cop = co; 23847 } 23848 23849 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 23850 that.size.width = that.size.width + 23851 ( that._helper ? 23852 ( that.position.left - co.left ) : 23853 ( that.position.left - cop.left ) ); 23854 23855 if ( pRatio ) { 23856 that.size.height = that.size.width / that.aspectRatio; 23857 continueResize = false; 23858 } 23859 that.position.left = o.helper ? co.left : 0; 23860 } 23861 23862 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 23863 that.size.height = that.size.height + 23864 ( that._helper ? 23865 ( that.position.top - co.top ) : 23866 that.position.top ); 23867 23868 if ( pRatio ) { 23869 that.size.width = that.size.height * that.aspectRatio; 23870 continueResize = false; 23871 } 23872 that.position.top = that._helper ? co.top : 0; 23873 } 23874 23875 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 23876 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 23877 23878 if ( isParent && isOffsetRelative ) { 23879 that.offset.left = that.parentData.left + that.position.left; 23880 that.offset.top = that.parentData.top + that.position.top; 23881 } else { 23882 that.offset.left = that.element.offset().left; 23883 that.offset.top = that.element.offset().top; 23884 } 23885 23886 woset = Math.abs( that.sizeDiff.width + 23887 ( that._helper ? 23888 that.offset.left - cop.left : 23889 ( that.offset.left - co.left ) ) ); 23890 23891 hoset = Math.abs( that.sizeDiff.height + 23892 ( that._helper ? 23893 that.offset.top - cop.top : 23894 ( that.offset.top - co.top ) ) ); 23895 23896 if ( woset + that.size.width >= that.parentData.width ) { 23897 that.size.width = that.parentData.width - woset; 23898 if ( pRatio ) { 23899 that.size.height = that.size.width / that.aspectRatio; 23900 continueResize = false; 23901 } 23902 } 23903 23904 if ( hoset + that.size.height >= that.parentData.height ) { 23905 that.size.height = that.parentData.height - hoset; 23906 if ( pRatio ) { 23907 that.size.width = that.size.height * that.aspectRatio; 23908 continueResize = false; 23909 } 23910 } 23911 23912 if ( !continueResize ) { 23913 that.position.left = that.prevPosition.left; 23914 that.position.top = that.prevPosition.top; 23915 that.size.width = that.prevSize.width; 23916 that.size.height = that.prevSize.height; 23917 } 23918 }, 23919 23920 stop: function() { 23921 var that = $( this ).resizable( "instance" ), 23922 o = that.options, 23923 co = that.containerOffset, 23924 cop = that.containerPosition, 23925 ce = that.containerElement, 23926 helper = $( that.helper ), 23927 ho = helper.offset(), 23928 w = helper.outerWidth() - that.sizeDiff.width, 23929 h = helper.outerHeight() - that.sizeDiff.height; 23930 23931 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 23932 $( this ).css( { 23933 left: ho.left - cop.left - co.left, 23934 width: w, 23935 height: h 23936 } ); 23937 } 23938 23939 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 23940 $( this ).css( { 23941 left: ho.left - cop.left - co.left, 23942 width: w, 23943 height: h 23944 } ); 23945 } 23946 } 23947} ); 23948 23949$.ui.plugin.add( "resizable", "alsoResize", { 23950 23951 start: function() { 23952 var that = $( this ).resizable( "instance" ), 23953 o = that.options; 23954 23955 $( o.alsoResize ).each( function() { 23956 var el = $( this ); 23957 el.data( "ui-resizable-alsoresize", { 23958 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 23959 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 23960 } ); 23961 } ); 23962 }, 23963 23964 resize: function( event, ui ) { 23965 var that = $( this ).resizable( "instance" ), 23966 o = that.options, 23967 os = that.originalSize, 23968 op = that.originalPosition, 23969 delta = { 23970 height: ( that.size.height - os.height ) || 0, 23971 width: ( that.size.width - os.width ) || 0, 23972 top: ( that.position.top - op.top ) || 0, 23973 left: ( that.position.left - op.left ) || 0 23974 }; 23975 23976 $( o.alsoResize ).each( function() { 23977 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 23978 css = el.parents( ui.originalElement[ 0 ] ).length ? 23979 [ "width", "height" ] : 23980 [ "width", "height", "top", "left" ]; 23981 23982 $.each( css, function( i, prop ) { 23983 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 23984 if ( sum && sum >= 0 ) { 23985 style[ prop ] = sum || null; 23986 } 23987 } ); 23988 23989 el.css( style ); 23990 } ); 23991 }, 23992 23993 stop: function() { 23994 $( this ).removeData( "ui-resizable-alsoresize" ); 23995 } 23996} ); 23997 23998$.ui.plugin.add( "resizable", "ghost", { 23999 24000 start: function() { 24001 24002 var that = $( this ).resizable( "instance" ), cs = that.size; 24003 24004 that.ghost = that.originalElement.clone(); 24005 that.ghost.css( { 24006 opacity: 0.25, 24007 display: "block", 24008 position: "relative", 24009 height: cs.height, 24010 width: cs.width, 24011 margin: 0, 24012 left: 0, 24013 top: 0 24014 } ); 24015 24016 that._addClass( that.ghost, "ui-resizable-ghost" ); 24017 24018 // DEPRECATED 24019 // TODO: remove after 1.12 24020 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 24021 24022 // Ghost option 24023 that.ghost.addClass( this.options.ghost ); 24024 } 24025 24026 that.ghost.appendTo( that.helper ); 24027 24028 }, 24029 24030 resize: function() { 24031 var that = $( this ).resizable( "instance" ); 24032 if ( that.ghost ) { 24033 that.ghost.css( { 24034 position: "relative", 24035 height: that.size.height,
vendor: 3,370 bytes, lines 24036-24190
24036 width: that.size.width 24037 } ); 24038 } 24039 }, 24040 24041 stop: function() { 24042 var that = $( this ).resizable( "instance" ); 24043 if ( that.ghost && that.helper ) { 24044 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 24045 } 24046 } 24047 24048} ); 24049 24050$.ui.plugin.add( "resizable", "grid", { 24051 24052 resize: function() { 24053 var outerDimensions, 24054 that = $( this ).resizable( "instance" ), 24055 o = that.options, 24056 cs = that.size, 24057 os = that.originalSize, 24058 op = that.originalPosition, 24059 a = that.axis, 24060 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 24061 gridX = ( grid[ 0 ] || 1 ), 24062 gridY = ( grid[ 1 ] || 1 ), 24063 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 24064 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 24065 newWidth = os.width + ox, 24066 newHeight = os.height + oy, 24067 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 24068 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 24069 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 24070 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 24071 24072 o.grid = grid; 24073 24074 if ( isMinWidth ) { 24075 newWidth += gridX; 24076 } 24077 if ( isMinHeight ) { 24078 newHeight += gridY; 24079 } 24080 if ( isMaxWidth ) { 24081 newWidth -= gridX; 24082 } 24083 if ( isMaxHeight ) { 24084 newHeight -= gridY; 24085 } 24086 24087 if ( /^(se|s|e)$/.test( a ) ) { 24088 that.size.width = newWidth; 24089 that.size.height = newHeight; 24090 } else if ( /^(ne)$/.test( a ) ) { 24091 that.size.width = newWidth; 24092 that.size.height = newHeight; 24093 that.position.top = op.top - oy; 24094 } else if ( /^(sw)$/.test( a ) ) { 24095 that.size.width = newWidth; 24096 that.size.height = newHeight; 24097 that.position.left = op.left - ox; 24098 } else { 24099 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 24100 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 24101 } 24102 24103 if ( newHeight - gridY > 0 ) { 24104 that.size.height = newHeight; 24105 that.position.top = op.top - oy; 24106 } else { 24107 newHeight = gridY - outerDimensions.height; 24108 that.size.height = newHeight; 24109 that.position.top = op.top + os.height - newHeight; 24110 } 24111 if ( newWidth - gridX > 0 ) { 24112 that.size.width = newWidth; 24113 that.position.left = op.left - ox; 24114 } else { 24115 newWidth = gridX - outerDimensions.width; 24116 that.size.width = newWidth; 24117 that.position.left = op.left + os.width - newWidth; 24118 } 24119 } 24120 } 24121 24122} ); 24123 24124return $.ui.resizable; 24125 24126} ); 24127 24128 24129 24130 24131 24132 24133 24134 24135 24136 24137 24138 24139 24140 24141/*! 24142 * jQuery UI Dialog 1.13.0 24143 * http://jqueryui.com 24144 * 24145 * Copyright jQuery Foundation and other contributors 24146 * Released under the MIT license. 24147 * http://jquery.org/license 24148 */ 24149 24150//>>label: Dialog 24151//>>group: Widgets 24152//>>description: Displays customizable dialog windows. 24153//>>docs: http://api.jqueryui.com/dialog/ 24154//>>demos: http://jqueryui.com/dialog/ 24155//>>css.structure: ../../themes/base/core.css 24156//>>css.structure: ../../themes/base/dialog.css 24157//>>css.theme: ../../themes/base/theme.css 24158 24159( function( factory ) { 24160 "use strict"; 24161 24162 if ( typeof define === "function" && define.amd ) { 24163 24164 // AMD. Register as an anonymous module. 24165 define( [ 24166 "jquery", 24167 "./button", 24168 "./draggable", 24169 "./mouse", 24170 "./resizable", 24171 "../focusable", 24172 "../keycode", 24173 "../position", 24174 "../safe-active-element", 24175 "../safe-blur", 24176 "../tabbable", 24177 "../unique-id", 24178 "../version", 24179 "../widget" 24180 ], factory ); 24181 } else { 24182 24183 // Browser globals 24184 factory( jQuery ); 24185 } 24186} )( function( $ ) { 24187"use strict"; 24188 24189$.widget( "ui.dialog", { 24190 version: "1.13.0
vendor: 20,928 bytes, lines 24190-25024
24190", 24191 options: { 24192 appendTo: "body", 24193 autoOpen: true, 24194 buttons: [], 24195 classes: { 24196 "ui-dialog": "ui-corner-all", 24197 "ui-dialog-titlebar": "ui-corner-all" 24198 }, 24199 closeOnEscape: true, 24200 closeText: "Close", 24201 draggable: true, 24202 hide: null, 24203 height: "auto", 24204 maxHeight: null, 24205 maxWidth: null, 24206 minHeight: 150, 24207 minWidth: 150, 24208 modal: false, 24209 position: { 24210 my: "center", 24211 at: "center", 24212 of: window, 24213 collision: "fit", 24214 24215 // Ensure the titlebar is always visible 24216 using: function( pos ) { 24217 var topOffset = $( this ).css( pos ).offset().top; 24218 if ( topOffset < 0 ) { 24219 $( this ).css( "top", pos.top - topOffset ); 24220 } 24221 } 24222 }, 24223 resizable: true, 24224 show: null, 24225 title: null, 24226 width: 300, 24227 24228 // Callbacks 24229 beforeClose: null, 24230 close: null, 24231 drag: null, 24232 dragStart: null, 24233 dragStop: null, 24234 focus: null, 24235 open: null, 24236 resize: null, 24237 resizeStart: null, 24238 resizeStop: null 24239 }, 24240 24241 sizeRelatedOptions: { 24242 buttons: true, 24243 height: true, 24244 maxHeight: true, 24245 maxWidth: true, 24246 minHeight: true, 24247 minWidth: true, 24248 width: true 24249 }, 24250 24251 resizableRelatedOptions: { 24252 maxHeight: true, 24253 maxWidth: true, 24254 minHeight: true, 24255 minWidth: true 24256 }, 24257 24258 _create: function() { 24259 this.originalCss = { 24260 display: this.element[ 0 ].style.display, 24261 width: this.element[ 0 ].style.width, 24262 minHeight: this.element[ 0 ].style.minHeight, 24263 maxHeight: this.element[ 0 ].style.maxHeight, 24264 height: this.element[ 0 ].style.height 24265 }; 24266 this.originalPosition = { 24267 parent: this.element.parent(), 24268 index: this.element.parent().children().index( this.element ) 24269 }; 24270 this.originalTitle = this.element.attr( "title" ); 24271 if ( this.options.title == null && this.originalTitle != null ) { 24272 this.options.title = this.originalTitle; 24273 } 24274 24275 // Dialogs can't be disabled 24276 if ( this.options.disabled ) { 24277 this.options.disabled = false; 24278 } 24279 24280 this._createWrapper(); 24281 24282 this.element 24283 .show() 24284 .removeAttr( "title" ) 24285 .appendTo( this.uiDialog ); 24286 24287 this._addClass( "ui-dialog-content", "ui-widget-content" ); 24288 24289 this._createTitlebar(); 24290 this._createButtonPane(); 24291 24292 if ( this.options.draggable && $.fn.draggable ) { 24293 this._makeDraggable(); 24294 } 24295 if ( this.options.resizable && $.fn.resizable ) { 24296 this._makeResizable(); 24297 } 24298 24299 this._isOpen = false; 24300 24301 this._trackFocus(); 24302 }, 24303 24304 _init: function() { 24305 if ( this.options.autoOpen ) { 24306 this.open(); 24307 } 24308 }, 24309 24310 _appendTo: function() { 24311 var element = this.options.appendTo; 24312 if ( element && ( element.jquery || element.nodeType ) ) { 24313 return $( element ); 24314 } 24315 return this.document.find( element || "body" ).eq( 0 ); 24316 }, 24317 24318 _destroy: function() { 24319 var next, 24320 originalPosition = this.originalPosition; 24321 24322 this._untrackInstance(); 24323 this._destroyOverlay(); 24324 24325 this.element 24326 .removeUniqueId() 24327 .css( this.originalCss ) 24328 24329 // Without detaching first, the following becomes really slow 24330 .detach(); 24331 24332 this.uiDialog.remove(); 24333 24334 if ( this.originalTitle ) { 24335 this.element.attr( "title", this.originalTitle ); 24336 } 24337 24338 next = originalPosition.parent.children().eq( originalPosition.index ); 24339 24340 // Don't try to place the dialog next to itself (#8613) 24341 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 24342 next.before( this.element ); 24343 } else { 24344 originalPosition.parent.append( this.element ); 24345 } 24346 }, 24347 24348 widget: function() { 24349 return this.uiDialog; 24350 }, 24351 24352 disable: $.noop, 24353 enable: $.noop, 24354 24355 close: function( event ) { 24356 var that = this; 24357 24358 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 24359 return; 24360 } 24361 24362 this._isOpen = false; 24363 this._focusedElement = null; 24364 this._destroyOverlay(); 24365 this._untrackInstance(); 24366 24367 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 24368 24369 // Hiding a focused element doesn't trigger blur in WebKit 24370 // so in case we have nothing to focus on, explicitly blur the active element 24371 // https://bugs.webkit.org/show_bug.cgi?id=47182 24372 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); 24373 } 24374 24375 this._hide( this.uiDialog, this.options.hide, function() { 24376 that._trigger( "close", event ); 24377 } ); 24378 }, 24379 24380 isOpen: function() { 24381 return this._isOpen; 24382 }, 24383 24384 moveToTop: function() { 24385 this._moveToTop(); 24386 }, 24387 24388 _moveToTop: function( event, silent ) { 24389 var moved = false, 24390 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 24391 return +$( this ).css( "z-index" ); 24392 } ).get(), 24393 zIndexMax = Math.max.apply( null, zIndices ); 24394 24395 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 24396 this.uiDialog.css( "z-index", zIndexMax + 1 ); 24397 moved = true; 24398 } 24399 24400 if ( moved && !silent ) { 24401 this._trigger( "focus", event ); 24402 } 24403 return moved; 24404 }, 24405 24406 open: function() { 24407 var that = this; 24408 if ( this._isOpen ) { 24409 if ( this._moveToTop() ) { 24410 this._focusTabbable(); 24411 } 24412 return; 24413 } 24414 24415 this._isOpen = true; 24416 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 24417 24418 this._size(); 24419 this._position(); 24420 this._createOverlay(); 24421 this._moveToTop( null, true ); 24422 24423 // Ensure the overlay is moved to the top with the dialog, but only when 24424 // opening. The overlay shouldn't move after the dialog is open so that 24425 // modeless dialogs opened after the modal dialog stack properly. 24426 if ( this.overlay ) { 24427 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 24428 } 24429 24430 this._show( this.uiDialog, this.options.show, function() { 24431 that._focusTabbable(); 24432 that._trigger( "focus" ); 24433 } ); 24434 24435 // Track the dialog immediately upon opening in case a focus event 24436 // somehow occurs outside of the dialog before an element inside the 24437 // dialog is focused (#10152) 24438 this._makeFocusTarget(); 24439 24440 this._trigger( "open" ); 24441 }, 24442 24443 _focusTabbable: function() { 24444 24445 // Set focus to the first match: 24446 // 1. An element that was focused previously 24447 // 2. First element inside the dialog matching [autofocus] 24448 // 3. Tabbable element inside the content element 24449 // 4. Tabbable element inside the buttonpane 24450 // 5. The close button 24451 // 6. The dialog itself 24452 var hasFocus = this._focusedElement; 24453 if ( !hasFocus ) { 24454 hasFocus = this.element.find( "[autofocus]" ); 24455 } 24456 if ( !hasFocus.length ) { 24457 hasFocus = this.element.find( ":tabbable" ); 24458 } 24459 if ( !hasFocus.length ) { 24460 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 24461 } 24462 if ( !hasFocus.length ) { 24463 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 24464 } 24465 if ( !hasFocus.length ) { 24466 hasFocus = this.uiDialog; 24467 } 24468 hasFocus.eq( 0 ).trigger( "focus" ); 24469 }, 24470 24471 _restoreTabbableFocus: function() { 24472 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 24473 isActive = this.uiDialog[ 0 ] === activeElement || 24474 $.contains( this.uiDialog[ 0 ], activeElement ); 24475 if ( !isActive ) { 24476 this._focusTabbable(); 24477 } 24478 }, 24479 24480 _keepFocus: function( event ) { 24481 event.preventDefault(); 24482 this._restoreTabbableFocus(); 24483 24484 // support: IE 24485 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 24486 // so we check again later 24487 this._delay( this._restoreTabbableFocus ); 24488 }, 24489 24490 _createWrapper: function() { 24491 this.uiDialog = $( "<div>" ) 24492 .hide() 24493 .attr( { 24494 24495 // Setting tabIndex makes the div focusable 24496 tabIndex: -1, 24497 role: "dialog" 24498 } ) 24499 .appendTo( this._appendTo() ); 24500 24501 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 24502 this._on( this.uiDialog, { 24503 keydown: function( event ) { 24504 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 24505 event.keyCode === $.ui.keyCode.ESCAPE ) { 24506 event.preventDefault(); 24507 this.close( event ); 24508 return; 24509 } 24510 24511 // Prevent tabbing out of dialogs 24512 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 24513 return; 24514 } 24515 var tabbables = this.uiDialog.find( ":tabbable" ), 24516 first = tabbables.first(), 24517 last = tabbables.last(); 24518 24519 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 24520 !event.shiftKey ) { 24521 this._delay( function() { 24522 first.trigger( "focus" ); 24523 } ); 24524 event.preventDefault(); 24525 } else if ( ( event.target === first[ 0 ] || 24526 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 24527 this._delay( function() { 24528 last.trigger( "focus" ); 24529 } ); 24530 event.preventDefault(); 24531 } 24532 }, 24533 mousedown: function( event ) { 24534 if ( this._moveToTop( event ) ) { 24535 this._focusTabbable(); 24536 } 24537 } 24538 } ); 24539 24540 // We assume that any existing aria-describedby attribute means 24541 // that the dialog content is marked up properly 24542 // otherwise we brute force the content as the description 24543 if ( !this.element.find( "[aria-describedby]" ).length ) { 24544 this.uiDialog.attr( { 24545 "aria-describedby": this.element.uniqueId().attr( "id" ) 24546 } ); 24547 } 24548 }, 24549 24550 _createTitlebar: function() { 24551 var uiDialogTitle; 24552 24553 this.uiDialogTitlebar = $( "<div>" ); 24554 this._addClass( this.uiDialogTitlebar, 24555 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 24556 this._on( this.uiDialogTitlebar, { 24557 mousedown: function( event ) { 24558 24559 // Don't prevent click on close button (#8838) 24560 // Focusing a dialog that is partially scrolled out of view 24561 // causes the browser to scroll it into view, preventing the click event 24562 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 24563 24564 // Dialog isn't getting focus when dragging (#8063) 24565 this.uiDialog.trigger( "focus" ); 24566 } 24567 } 24568 } ); 24569 24570 // Support: IE 24571 // Use type="button" to prevent enter keypresses in textboxes from closing the 24572 // dialog in IE (#9312) 24573 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 24574 .button( { 24575 label: $( "<a>" ).text( this.options.closeText ).html(), 24576 icon: "ui-icon-closethick", 24577 showLabel: false 24578 } ) 24579 .appendTo( this.uiDialogTitlebar ); 24580 24581 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 24582 this._on( this.uiDialogTitlebarClose, { 24583 click: function( event ) { 24584 event.preventDefault(); 24585 this.close( event ); 24586 } 24587 } ); 24588 24589 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); 24590 this._addClass( uiDialogTitle, "ui-dialog-title" ); 24591 this._title( uiDialogTitle ); 24592 24593 this.uiDialogTitlebar.prependTo( this.uiDialog ); 24594 24595 this.uiDialog.attr( { 24596 "aria-labelledby": uiDialogTitle.attr( "id" ) 24597 } ); 24598 }, 24599 24600 _title: function( title ) { 24601 if ( this.options.title ) { 24602 title.text( this.options.title ); 24603 } else { 24604 title.html( " " ); 24605 } 24606 }, 24607 24608 _createButtonPane: function() { 24609 this.uiDialogButtonPane = $( "<div>" ); 24610 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 24611 "ui-widget-content ui-helper-clearfix" ); 24612 24613 this.uiButtonSet = $( "<div>" ) 24614 .appendTo( this.uiDialogButtonPane ); 24615 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 24616 24617 this._createButtons(); 24618 }, 24619 24620 _createButtons: function() { 24621 var that = this, 24622 buttons = this.options.buttons; 24623 24624 // If we already have a button pane, remove it 24625 this.uiDialogButtonPane.remove(); 24626 this.uiButtonSet.empty(); 24627 24628 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { 24629 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 24630 return; 24631 } 24632 24633 $.each( buttons, function( name, props ) { 24634 var click, buttonOptions; 24635 props = typeof props === "function" ? 24636 { click: props, text: name } : 24637 props; 24638 24639 // Default to a non-submitting button 24640 props = $.extend( { type: "button" }, props ); 24641 24642 // Change the context for the click callback to be the main element 24643 click = props.click; 24644 buttonOptions = { 24645 icon: props.icon, 24646 iconPosition: props.iconPosition, 24647 showLabel: props.showLabel, 24648 24649 // Deprecated options 24650 icons: props.icons, 24651 text: props.text 24652 }; 24653 24654 delete props.click; 24655 delete props.icon; 24656 delete props.iconPosition; 24657 delete props.showLabel; 24658 24659 // Deprecated options 24660 delete props.icons; 24661 if ( typeof props.text === "boolean" ) { 24662 delete props.text; 24663 } 24664 24665 $( "<button></button>", props ) 24666 .button( buttonOptions ) 24667 .appendTo( that.uiButtonSet ) 24668 .on( "click", function() { 24669 click.apply( that.element[ 0 ], arguments ); 24670 } ); 24671 } ); 24672 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 24673 this.uiDialogButtonPane.appendTo( this.uiDialog ); 24674 }, 24675 24676 _makeDraggable: function() { 24677 var that = this, 24678 options = this.options; 24679 24680 function filteredUi( ui ) { 24681 return { 24682 position: ui.position, 24683 offset: ui.offset 24684 }; 24685 } 24686 24687 this.uiDialog.draggable( { 24688 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 24689 handle: ".ui-dialog-titlebar", 24690 containment: "document", 24691 start: function( event, ui ) { 24692 that._addClass( $( this ), "ui-dialog-dragging" ); 24693 that._blockFrames(); 24694 that._trigger( "dragStart", event, filteredUi( ui ) ); 24695 }, 24696 drag: function( event, ui ) { 24697 that._trigger( "drag", event, filteredUi( ui ) ); 24698 }, 24699 stop: function( event, ui ) { 24700 var left = ui.offset.left - that.document.scrollLeft(), 24701 top = ui.offset.top - that.document.scrollTop(); 24702 24703 options.position = { 24704 my: "left top", 24705 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 24706 "top" + ( top >= 0 ? "+" : "" ) + top, 24707 of: that.window 24708 }; 24709 that._removeClass( $( this ), "ui-dialog-dragging" ); 24710 that._unblockFrames(); 24711 that._trigger( "dragStop", event, filteredUi( ui ) ); 24712 } 24713 } ); 24714 }, 24715 24716 _makeResizable: function() { 24717 var that = this, 24718 options = this.options, 24719 handles = options.resizable, 24720 24721 // .ui-resizable has position: relative defined in the stylesheet 24722 // but dialogs have to use absolute or fixed positioning 24723 position = this.uiDialog.css( "position" ), 24724 resizeHandles = typeof handles === "string" ? 24725 handles : 24726 "n,e,s,w,se,sw,ne,nw"; 24727 24728 function filteredUi( ui ) { 24729 return { 24730 originalPosition: ui.originalPosition, 24731 originalSize: ui.originalSize, 24732 position: ui.position, 24733 size: ui.size 24734 }; 24735 } 24736 24737 this.uiDialog.resizable( { 24738 cancel: ".ui-dialog-content", 24739 containment: "document", 24740 alsoResize: this.element, 24741 maxWidth: options.maxWidth, 24742 maxHeight: options.maxHeight, 24743 minWidth: options.minWidth, 24744 minHeight: this._minHeight(), 24745 handles: resizeHandles, 24746 start: function( event, ui ) { 24747 that._addClass( $( this ), "ui-dialog-resizing" ); 24748 that._blockFrames(); 24749 that._trigger( "resizeStart", event, filteredUi( ui ) ); 24750 }, 24751 resize: function( event, ui ) { 24752 that._trigger( "resize", event, filteredUi( ui ) ); 24753 }, 24754 stop: function( event, ui ) { 24755 var offset = that.uiDialog.offset(), 24756 left = offset.left - that.document.scrollLeft(), 24757 top = offset.top - that.document.scrollTop(); 24758 24759 options.height = that.uiDialog.height(); 24760 options.width = that.uiDialog.width(); 24761 options.position = { 24762 my: "left top", 24763 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 24764 "top" + ( top >= 0 ? "+" : "" ) + top, 24765 of: that.window 24766 }; 24767 that._removeClass( $( this ), "ui-dialog-resizing" ); 24768 that._unblockFrames(); 24769 that._trigger( "resizeStop", event, filteredUi( ui ) ); 24770 } 24771 } ) 24772 .css( "position", position ); 24773 }, 24774 24775 _trackFocus: function() { 24776 this._on( this.widget(), { 24777 focusin: function( event ) { 24778 this._makeFocusTarget(); 24779 this._focusedElement = $( event.target ); 24780 } 24781 } ); 24782 }, 24783 24784 _makeFocusTarget: function() { 24785 this._untrackInstance(); 24786 this._trackingInstances().unshift( this ); 24787 }, 24788 24789 _untrackInstance: function() { 24790 var instances = this._trackingInstances(), 24791 exists = $.inArray( this, instances ); 24792 if ( exists !== -1 ) { 24793 instances.splice( exists, 1 ); 24794 } 24795 }, 24796 24797 _trackingInstances: function() { 24798 var instances = this.document.data( "ui-dialog-instances" ); 24799 if ( !instances ) { 24800 instances = []; 24801 this.document.data( "ui-dialog-instances", instances ); 24802 } 24803 return instances; 24804 }, 24805 24806 _minHeight: function() { 24807 var options = this.options; 24808 24809 return options.height === "auto" ? 24810 options.minHeight : 24811 Math.min( options.minHeight, options.height ); 24812 }, 24813 24814 _position: function() { 24815 24816 // Need to show the dialog to get the actual offset in the position plugin 24817 var isVisible = this.uiDialog.is( ":visible" ); 24818 if ( !isVisible ) { 24819 this.uiDialog.show(); 24820 } 24821 this.uiDialog.position( this.options.position ); 24822 if ( !isVisible ) { 24823 this.uiDialog.hide(); 24824 } 24825 }, 24826 24827 _setOptions: function( options ) { 24828 var that = this, 24829 resize = false, 24830 resizableOptions = {}; 24831 24832 $.each( options, function( key, value ) { 24833 that._setOption( key, value ); 24834 24835 if ( key in that.sizeRelatedOptions ) { 24836 resize = true; 24837 } 24838 if ( key in that.resizableRelatedOptions ) { 24839 resizableOptions[ key ] = value; 24840 } 24841 } ); 24842 24843 if ( resize ) { 24844 this._size(); 24845 this._position(); 24846 } 24847 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 24848 this.uiDialog.resizable( "option", resizableOptions ); 24849 } 24850 }, 24851 24852 _setOption: function( key, value ) { 24853 var isDraggable, isResizable, 24854 uiDialog = this.uiDialog; 24855 24856 if ( key === "disabled" ) { 24857 return; 24858 } 24859 24860 this._super( key, value ); 24861 24862 if ( key === "appendTo" ) { 24863 this.uiDialog.appendTo( this._appendTo() ); 24864 } 24865 24866 if ( key === "buttons" ) { 24867 this._createButtons(); 24868 } 24869 24870 if ( key === "closeText" ) { 24871 this.uiDialogTitlebarClose.button( { 24872 24873 // Ensure that we always pass a string 24874 label: $( "<a>" ).text( "" + this.options.closeText ).html() 24875 } ); 24876 } 24877 24878 if ( key === "draggable" ) { 24879 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 24880 if ( isDraggable && !value ) { 24881 uiDialog.draggable( "destroy" ); 24882 } 24883 24884 if ( !isDraggable && value ) { 24885 this._makeDraggable(); 24886 } 24887 } 24888 24889 if ( key === "position" ) { 24890 this._position(); 24891 } 24892 24893 if ( key === "resizable" ) { 24894 24895 // currently resizable, becoming non-resizable 24896 isResizable = uiDialog.is( ":data(ui-resizable)" ); 24897 if ( isResizable && !value ) { 24898 uiDialog.resizable( "destroy" ); 24899 } 24900 24901 // Currently resizable, changing handles 24902 if ( isResizable && typeof value === "string" ) { 24903 uiDialog.resizable( "option", "handles", value ); 24904 } 24905 24906 // Currently non-resizable, becoming resizable 24907 if ( !isResizable && value !== false ) { 24908 this._makeResizable(); 24909 } 24910 } 24911 24912 if ( key === "title" ) { 24913 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 24914 } 24915 }, 24916 24917 _size: function() { 24918 24919 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 24920 // divs will both have width and height set, so we need to reset them 24921 var nonContentHeight, minContentHeight, maxContentHeight, 24922 options = this.options; 24923 24924 // Reset content sizing 24925 this.element.show().css( { 24926 width: "auto", 24927 minHeight: 0, 24928 maxHeight: "none", 24929 height: 0 24930 } ); 24931 24932 if ( options.minWidth > options.width ) { 24933 options.width = options.minWidth; 24934 } 24935 24936 // Reset wrapper sizing 24937 // determine the height of all the non-content elements 24938 nonContentHeight = this.uiDialog.css( { 24939 height: "auto", 24940 width: options.width 24941 } ) 24942 .outerHeight(); 24943 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 24944 maxContentHeight = typeof options.maxHeight === "number" ? 24945 Math.max( 0, options.maxHeight - nonContentHeight ) : 24946 "none"; 24947 24948 if ( options.height === "auto" ) { 24949 this.element.css( { 24950 minHeight: minContentHeight, 24951 maxHeight: maxContentHeight, 24952 height: "auto" 24953 } ); 24954 } else { 24955 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 24956 } 24957 24958 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 24959 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 24960 } 24961 }, 24962 24963 _blockFrames: function() { 24964 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 24965 var iframe = $( this ); 24966 24967 return $( "<div>" ) 24968 .css( { 24969 position: "absolute", 24970 width: iframe.outerWidth(), 24971 height: iframe.outerHeight() 24972 } ) 24973 .appendTo( iframe.parent() ) 24974 .offset( iframe.offset() )[ 0 ]; 24975 } ); 24976 }, 24977 24978 _unblockFrames: function() { 24979 if ( this.iframeBlocks ) { 24980 this.iframeBlocks.remove(); 24981 delete this.iframeBlocks; 24982 } 24983 }, 24984 24985 _allowInteraction: function( event ) { 24986 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 24987 return true; 24988 } 24989 24990 // TODO: Remove hack when datepicker implements 24991 // the .ui-front logic (#8989) 24992 return !!$( event.target ).closest( ".ui-datepicker" ).length; 24993 }, 24994 24995 _createOverlay: function() { 24996 if ( !this.options.modal ) { 24997 return; 24998 } 24999 25000 var jqMinor = $.fn.jquery.substring( 0, 4 ); 25001 25002 // We use a delay in case the overlay is created from an 25003 // event that we're going to be cancelling (#2804) 25004 var isOpening = true; 25005 this._delay( function() { 25006 isOpening = false; 25007 } ); 25008 25009 if ( !this.document.data( "ui-dialog-overlays" ) ) { 25010 25011 // Prevent use of anchors and inputs 25012 // This doesn't use `_on()` because it is a shared event handler 25013 // across all open modal dialogs. 25014 this.document.on( "focusin.ui-dialog", function( event ) { 25015 if ( isOpening ) { 25016 return; 25017 } 25018 25019 var instance = this._trackingInstances()[ 0 ]; 25020 if ( !instance._allowInteraction( event ) ) { 25021 event.preventDefault(); 25022 instance._focusTabbable(); 25023 25024 // Support: jQuery >=3.4 <3.
250246 only 25025 // Focus re-triggering in jQuery 3.4/3.5 makes the original element 25026 // have its focus event propagated last, breaking the re-targeting. 25027 // Trigger focus in a delay in addition if needed to avoid the issue 25028 // See https://github.com/jquery/jquery/issues/4382 25029 if ( jqMinor === "3.4." || jqMinor === "3.5." ) { 25030 instance._delay( instance._restoreTabbableFocus ); 25031 } 25032 } 25033 }.bind( this ) ); 25034 } 25035 25036 this.overlay = $( "<div>" ) 25037 .appendTo( this._appendTo() ); 25038 25039 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 25040 this._on( this.overlay, { 25041 mousedown: "_keepFocus" 25042 } ); 25043 this.document.data( "ui-dialog-overlays", 25044 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 25045 }, 25046 25047 _destroyOverlay: function() { 25048 if ( !this.options.modal ) { 25049 return; 25050 } 25051 25052 if ( this.overlay ) { 25053 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 25054 25055 if ( !overlays ) { 25056 this.document.off( "focusin.ui-dialog" ); 25057 this.document.removeData( "ui-dialog-overlays" ); 25058 } else { 25059 this.document.data( "ui-dialog-overlays", overlays ); 25060 } 25061 25062 this.overlay.remove(); 25063 this.overlay = null; 25064 } 25065 } 25066} ); 25067 25068// DEPRECATED 25069// TODO: switch return back to widget declaration at top of file when this is removed 25070if ( $.uiBackCompat !== false ) { 25071 25072 // Backcompat for dialogClass option 25073 $.widget( "ui.dialog", $.ui.dialog, { 25074 options: { 25075 dialogClass: "" 25076 }, 25077 _createWrapper: function() { 25078 this._super(); 25079 this.uiDialog.addClass( this.options.dialogClass ); 25080 }, 25081 _setOption: function( key, value ) { 25082 if ( key === "dialogClass" ) { 25083 this.uiDialog 25084 .removeClass( this.options.dialogClass ) 25085 .addClass( value ); 25086 } 25087 this._superApply( arguments ); 25088 } 25089 } ); 25090} 25091 25092return $.ui.dialog; 25093 25094} ); 25095 25096 25097 25098 25099 25100/*! 25101 * jQuery UI Droppable 1.13.0 25102 * http://jqueryui.com 25103 * 25104 * Copyright jQuery Foundation and other contributors 25105 * Released under the MIT license. 25106 * http://jquery.org/license 25107 */ 25108 25109//>>label: Droppable 25110//>>group: Interactions 25111//>>description: Enables drop targets for draggable elements. 25112//>>docs: http://api.jqueryui.com/droppable/ 25113//>>demos: http://jqueryui.com/droppable/ 25114 25115( function( factory ) { 25116 "use strict"; 25117 25118 if ( typeof define === "function" && define.amd ) { 25119 25120 // AMD. Register as an anonymous module. 25121 define( [ 25122 "jquery", 25123 "./draggable", 25124 "./mouse", 25125 "../version", 25126 "../widget" 25127 ], factory ); 25128 } else { 25129 25130 // Browser globals 25131 factory( jQuery ); 25132 } 25133} )( function( $ ) { 25134"use strict"; 25135 25136$.widget( "ui.droppable", { 25137 version: "1.13.0
vendor: 11,311 bytes, lines 25137-25565
25137", 25138 widgetEventPrefix: "drop", 25139 options: { 25140 accept: "*", 25141 addClasses: true, 25142 greedy: false, 25143 scope: "default", 25144 tolerance: "intersect", 25145 25146 // Callbacks 25147 activate: null, 25148 deactivate: null, 25149 drop: null, 25150 out: null, 25151 over: null 25152 }, 25153 _create: function() { 25154 25155 var proportions, 25156 o = this.options, 25157 accept = o.accept; 25158 25159 this.isover = false; 25160 this.isout = true; 25161 25162 this.accept = typeof accept === "function" ? accept : function( d ) { 25163 return d.is( accept ); 25164 }; 25165 25166 this.proportions = function( /* valueToWrite */ ) { 25167 if ( arguments.length ) { 25168 25169 // Store the droppable's proportions 25170 proportions = arguments[ 0 ]; 25171 } else { 25172 25173 // Retrieve or derive the droppable's proportions 25174 return proportions ? 25175 proportions : 25176 proportions = { 25177 width: this.element[ 0 ].offsetWidth, 25178 height: this.element[ 0 ].offsetHeight 25179 }; 25180 } 25181 }; 25182 25183 this._addToManager( o.scope ); 25184 25185 if ( o.addClasses ) { 25186 this._addClass( "ui-droppable" ); 25187 } 25188 25189 }, 25190 25191 _addToManager: function( scope ) { 25192 25193 // Add the reference and positions to the manager 25194 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 25195 $.ui.ddmanager.droppables[ scope ].push( this ); 25196 }, 25197 25198 _splice: function( drop ) { 25199 var i = 0; 25200 for ( ; i < drop.length; i++ ) { 25201 if ( drop[ i ] === this ) { 25202 drop.splice( i, 1 ); 25203 } 25204 } 25205 }, 25206 25207 _destroy: function() { 25208 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 25209 25210 this._splice( drop ); 25211 }, 25212 25213 _setOption: function( key, value ) { 25214 25215 if ( key === "accept" ) { 25216 this.accept = typeof value === "function" ? value : function( d ) { 25217 return d.is( value ); 25218 }; 25219 } else if ( key === "scope" ) { 25220 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 25221 25222 this._splice( drop ); 25223 this._addToManager( value ); 25224 } 25225 25226 this._super( key, value ); 25227 }, 25228 25229 _activate: function( event ) { 25230 var draggable = $.ui.ddmanager.current; 25231 25232 this._addActiveClass(); 25233 if ( draggable ) { 25234 this._trigger( "activate", event, this.ui( draggable ) ); 25235 } 25236 }, 25237 25238 _deactivate: function( event ) { 25239 var draggable = $.ui.ddmanager.current; 25240 25241 this._removeActiveClass(); 25242 if ( draggable ) { 25243 this._trigger( "deactivate", event, this.ui( draggable ) ); 25244 } 25245 }, 25246 25247 _over: function( event ) { 25248 25249 var draggable = $.ui.ddmanager.current; 25250 25251 // Bail if draggable and droppable are same element 25252 if ( !draggable || ( draggable.currentItem || 25253 draggable.element )[ 0 ] === this.element[ 0 ] ) { 25254 return; 25255 } 25256 25257 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 25258 draggable.element ) ) ) { 25259 this._addHoverClass(); 25260 this._trigger( "over", event, this.ui( draggable ) ); 25261 } 25262 25263 }, 25264 25265 _out: function( event ) { 25266 25267 var draggable = $.ui.ddmanager.current; 25268 25269 // Bail if draggable and droppable are same element 25270 if ( !draggable || ( draggable.currentItem || 25271 draggable.element )[ 0 ] === this.element[ 0 ] ) { 25272 return; 25273 } 25274 25275 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 25276 draggable.element ) ) ) { 25277 this._removeHoverClass(); 25278 this._trigger( "out", event, this.ui( draggable ) ); 25279 } 25280 25281 }, 25282 25283 _drop: function( event, custom ) { 25284 25285 var draggable = custom || $.ui.ddmanager.current, 25286 childrenIntersection = false; 25287 25288 // Bail if draggable and droppable are same element 25289 if ( !draggable || ( draggable.currentItem || 25290 draggable.element )[ 0 ] === this.element[ 0 ] ) { 25291 return false; 25292 } 25293 25294 this.element 25295 .find( ":data(ui-droppable)" ) 25296 .not( ".ui-draggable-dragging" ) 25297 .each( function() { 25298 var inst = $( this ).droppable( "instance" ); 25299 if ( 25300 inst.options.greedy && 25301 !inst.options.disabled && 25302 inst.options.scope === draggable.options.scope && 25303 inst.accept.call( 25304 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 25305 ) && 25306 $.ui.intersect( 25307 draggable, 25308 $.extend( inst, { offset: inst.element.offset() } ), 25309 inst.options.tolerance, event 25310 ) 25311 ) { 25312 childrenIntersection = true; 25313 return false; 25314 } 25315 } ); 25316 if ( childrenIntersection ) { 25317 return false; 25318 } 25319 25320 if ( this.accept.call( this.element[ 0 ], 25321 ( draggable.currentItem || draggable.element ) ) ) { 25322 this._removeActiveClass(); 25323 this._removeHoverClass(); 25324 25325 this._trigger( "drop", event, this.ui( draggable ) ); 25326 return this.element; 25327 } 25328 25329 return false; 25330 25331 }, 25332 25333 ui: function( c ) { 25334 return { 25335 draggable: ( c.currentItem || c.element ), 25336 helper: c.helper, 25337 position: c.position, 25338 offset: c.positionAbs 25339 }; 25340 }, 25341 25342 // Extension points just to make backcompat sane and avoid duplicating logic 25343 // TODO: Remove in 1.14 along with call to it below 25344 _addHoverClass: function() { 25345 this._addClass( "ui-droppable-hover" ); 25346 }, 25347 25348 _removeHoverClass: function() { 25349 this._removeClass( "ui-droppable-hover" ); 25350 }, 25351 25352 _addActiveClass: function() { 25353 this._addClass( "ui-droppable-active" ); 25354 }, 25355 25356 _removeActiveClass: function() { 25357 this._removeClass( "ui-droppable-active" ); 25358 } 25359} ); 25360 25361$.ui.intersect = ( function() { 25362 function isOverAxis( x, reference, size ) { 25363 return ( x >= reference ) && ( x < ( reference + size ) ); 25364 } 25365 25366 return function( draggable, droppable, toleranceMode, event ) { 25367 25368 if ( !droppable.offset ) { 25369 return false; 25370 } 25371 25372 var x1 = ( draggable.positionAbs || 25373 draggable.position.absolute ).left + draggable.margins.left, 25374 y1 = ( draggable.positionAbs || 25375 draggable.position.absolute ).top + draggable.margins.top, 25376 x2 = x1 + draggable.helperProportions.width, 25377 y2 = y1 + draggable.helperProportions.height, 25378 l = droppable.offset.left, 25379 t = droppable.offset.top, 25380 r = l + droppable.proportions().width, 25381 b = t + droppable.proportions().height; 25382 25383 switch ( toleranceMode ) { 25384 case "fit": 25385 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 25386 case "intersect": 25387 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 25388 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 25389 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 25390 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 25391 case "pointer": 25392 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 25393 isOverAxis( event.pageX, l, droppable.proportions().width ); 25394 case "touch": 25395 return ( 25396 ( y1 >= t && y1 <= b ) || // Top edge touching 25397 ( y2 >= t && y2 <= b ) || // Bottom edge touching 25398 ( y1 < t && y2 > b ) // Surrounded vertically 25399 ) && ( 25400 ( x1 >= l && x1 <= r ) || // Left edge touching 25401 ( x2 >= l && x2 <= r ) || // Right edge touching 25402 ( x1 < l && x2 > r ) // Surrounded horizontally 25403 ); 25404 default: 25405 return false; 25406 } 25407 }; 25408} )(); 25409 25410/* 25411 This manager tracks offsets of draggables and droppables 25412*/ 25413$.ui.ddmanager = { 25414 current: null, 25415 droppables: { "default": [] }, 25416 prepareOffsets: function( t, event ) { 25417 25418 var i, j, 25419 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 25420 type = event ? event.type : null, // workaround for #2317 25421 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 25422 25423 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 25424 25425 // No disabled and non-accepted 25426 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 25427 ( t.currentItem || t.element ) ) ) ) { 25428 continue; 25429 } 25430 25431 // Filter out elements in the current dragged item 25432 for ( j = 0; j < list.length; j++ ) { 25433 if ( list[ j ] === m[ i ].element[ 0 ] ) { 25434 m[ i ].proportions().height = 0; 25435 continue droppablesLoop; 25436 } 25437 } 25438 25439 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 25440 if ( !m[ i ].visible ) { 25441 continue; 25442 } 25443 25444 // Activate the droppable if used directly from draggables 25445 if ( type === "mousedown" ) { 25446 m[ i ]._activate.call( m[ i ], event ); 25447 } 25448 25449 m[ i ].offset = m[ i ].element.offset(); 25450 m[ i ].proportions( { 25451 width: m[ i ].element[ 0 ].offsetWidth, 25452 height: m[ i ].element[ 0 ].offsetHeight 25453 } ); 25454 25455 } 25456 25457 }, 25458 drop: function( draggable, event ) { 25459 25460 var dropped = false; 25461 25462 // Create a copy of the droppables in case the list changes during the drop (#9116) 25463 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 25464 25465 if ( !this.options ) { 25466 return; 25467 } 25468 if ( !this.options.disabled && this.visible && 25469 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 25470 dropped = this._drop.call( this, event ) || dropped; 25471 } 25472 25473 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 25474 ( draggable.currentItem || draggable.element ) ) ) { 25475 this.isout = true; 25476 this.isover = false; 25477 this._deactivate.call( this, event ); 25478 } 25479 25480 } ); 25481 return dropped; 25482 25483 }, 25484 dragStart: function( draggable, event ) { 25485 25486 // Listen for scrolling so that if the dragging causes scrolling the position of the 25487 // droppables can be recalculated (see #5003) 25488 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 25489 if ( !draggable.options.refreshPositions ) { 25490 $.ui.ddmanager.prepareOffsets( draggable, event ); 25491 } 25492 } ); 25493 }, 25494 drag: function( draggable, event ) { 25495 25496 // If you have a highly dynamic page, you might try this option. It renders positions 25497 // every time you move the mouse. 25498 if ( draggable.options.refreshPositions ) { 25499 $.ui.ddmanager.prepareOffsets( draggable, event ); 25500 } 25501 25502 // Run through all droppables and check their positions based on specific tolerance options 25503 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 25504 25505 if ( this.options.disabled || this.greedyChild || !this.visible ) { 25506 return; 25507 } 25508 25509 var parentInstance, scope, parent, 25510 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 25511 c = !intersects && this.isover ? 25512 "isout" : 25513 ( intersects && !this.isover ? "isover" : null ); 25514 if ( !c ) { 25515 return; 25516 } 25517 25518 if ( this.options.greedy ) { 25519 25520 // find droppable parents with same scope 25521 scope = this.options.scope; 25522 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 25523 return $( this ).droppable( "instance" ).options.scope === scope; 25524 } ); 25525 25526 if ( parent.length ) { 25527 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 25528 parentInstance.greedyChild = ( c === "isover" ); 25529 } 25530 } 25531 25532 // We just moved into a greedy child 25533 if ( parentInstance && c === "isover" ) { 25534 parentInstance.isover = false; 25535 parentInstance.isout = true; 25536 parentInstance._out.call( parentInstance, event ); 25537 } 25538 25539 this[ c ] = true; 25540 this[ c === "isout" ? "isover" : "isout" ] = false; 25541 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 25542 25543 // We just moved out of a greedy child 25544 if ( parentInstance && c === "isout" ) { 25545 parentInstance.isout = false; 25546 parentInstance.isover = true; 25547 parentInstance._over.call( parentInstance, event ); 25548 } 25549 } ); 25550 25551 }, 25552 dragStop: function( draggable, event ) { 25553 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 25554 25555 // Call prepareOffsets one final time since IE does not fire return scroll events when 25556 // overflow was caused by drag (see #5003) 25557 if ( !draggable.options.refreshPositions ) { 25558 $.ui.ddmanager.prepareOffsets( draggable, event ); 25559 } 25560 } 25561}; 25562 25563// DEPRECATED 25564// TODO: switch return back to widget declaration at top of file when this is removed 25565if ( $.uiBackCompat
25565!== false ) { 25566 25567 // Backcompat for activeClass and hoverClass options 25568 $.widget( "ui.droppable", $.ui.droppable, { 25569 options: { 25570 hoverClass: false, 25571 activeClass: false 25572 }, 25573 _addActiveClass: function() { 25574 this._super(); 25575 if ( this.options.activeClass ) { 25576 this.element.addClass( this.options.activeClass ); 25577 } 25578 }, 25579 _removeActiveClass: function() { 25580 this._super(); 25581 if ( this.options.activeClass ) { 25582 this.element.removeClass( this.options.activeClass ); 25583 } 25584 }, 25585 _addHoverClass: function() { 25586 this._super(); 25587 if ( this.options.hoverClass ) { 25588 this.element.addClass( this.options.hoverClass ); 25589 } 25590 }, 25591 _removeHoverClass: function() { 25592 this._super(); 25593 if ( this.options.hoverClass ) { 25594 this.element.removeClass( this.options.hoverClass ); 25595 } 25596 } 25597 } ); 25598} 25599 25600return $.ui.droppable; 25601 25602} ); 25603 25604 25605 25606/*! 25607 * jQuery UI Progressbar 1.13.0 25608 * http://jqueryui.com 25609 * 25610 * Copyright jQuery Foundation and other contributors 25611 * Released under the MIT license. 25612 * http://jquery.org/license 25613 */ 25614 25615//>>label: Progressbar 25616//>>group: Widgets 25617/* eslint-disable max-len */ 25618//>>
vendor: 4,806 bytes, lines 25618-25828
25618description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 25619/* eslint-enable max-len */ 25620//>>docs: http://api.jqueryui.com/progressbar/ 25621//>>demos: http://jqueryui.com/progressbar/ 25622//>>css.structure: ../../themes/base/core.css 25623//>>css.structure: ../../themes/base/progressbar.css 25624//>>css.theme: ../../themes/base/theme.css 25625 25626( function( factory ) { 25627 "use strict"; 25628 25629 if ( typeof define === "function" && define.amd ) { 25630 25631 // AMD. Register as an anonymous module. 25632 define( [ 25633 "jquery", 25634 "../version", 25635 "../widget" 25636 ], factory ); 25637 } else { 25638 25639 // Browser globals 25640 factory( jQuery ); 25641 } 25642} )( function( $ ) { 25643"use strict"; 25644 25645return $.widget( "ui.progressbar", { 25646 version: "1.13.0", 25647 options: { 25648 classes: { 25649 "ui-progressbar": "ui-corner-all", 25650 "ui-progressbar-value": "ui-corner-left", 25651 "ui-progressbar-complete": "ui-corner-right" 25652 }, 25653 max: 100, 25654 value: 0, 25655 25656 change: null, 25657 complete: null 25658 }, 25659 25660 min: 0, 25661 25662 _create: function() { 25663 25664 // Constrain initial value 25665 this.oldValue = this.options.value = this._constrainedValue(); 25666 25667 this.element.attr( { 25668 25669 // Only set static values; aria-valuenow and aria-valuemax are 25670 // set inside _refreshValue() 25671 role: "progressbar", 25672 "aria-valuemin": this.min 25673 } ); 25674 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 25675 25676 this.valueDiv = $( "<div>" ).appendTo( this.element ); 25677 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 25678 this._refreshValue(); 25679 }, 25680 25681 _destroy: function() { 25682 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 25683 25684 this.valueDiv.remove(); 25685 }, 25686 25687 value: function( newValue ) { 25688 if ( newValue === undefined ) { 25689 return this.options.value; 25690 } 25691 25692 this.options.value = this._constrainedValue( newValue ); 25693 this._refreshValue(); 25694 }, 25695 25696 _constrainedValue: function( newValue ) { 25697 if ( newValue === undefined ) { 25698 newValue = this.options.value; 25699 } 25700 25701 this.indeterminate = newValue === false; 25702 25703 // Sanitize value 25704 if ( typeof newValue !== "number" ) { 25705 newValue = 0; 25706 } 25707 25708 return this.indeterminate ? false : 25709 Math.min( this.options.max, Math.max( this.min, newValue ) ); 25710 }, 25711 25712 _setOptions: function( options ) { 25713 25714 // Ensure "value" option is set after other values (like max) 25715 var value = options.value; 25716 delete options.value; 25717 25718 this._super( options ); 25719 25720 this.options.value = this._constrainedValue( value ); 25721 this._refreshValue(); 25722 }, 25723 25724 _setOption: function( key, value ) { 25725 if ( key === "max" ) { 25726 25727 // Don't allow a max less than min 25728 value = Math.max( this.min, value ); 25729 } 25730 this._super( key, value ); 25731 }, 25732 25733 _setOptionDisabled: function( value ) { 25734 this._super( value ); 25735 25736 this.element.attr( "aria-disabled", value ); 25737 this._toggleClass( null, "ui-state-disabled", !!value ); 25738 }, 25739 25740 _percentage: function() { 25741 return this.indeterminate ? 25742 100 : 25743 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 25744 }, 25745 25746 _refreshValue: function() { 25747 var value = this.options.value, 25748 percentage = this._percentage(); 25749 25750 this.valueDiv 25751 .toggle( this.indeterminate || value > this.min ) 25752 .width( percentage.toFixed( 0 ) + "%" ); 25753 25754 this 25755 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 25756 value === this.options.max ) 25757 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 25758 25759 if ( this.indeterminate ) { 25760 this.element.removeAttr( "aria-valuenow" ); 25761 if ( !this.overlayDiv ) { 25762 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 25763 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 25764 } 25765 } else { 25766 this.element.attr( { 25767 "aria-valuemax": this.options.max, 25768 "aria-valuenow": value 25769 } ); 25770 if ( this.overlayDiv ) { 25771 this.overlayDiv.remove(); 25772 this.overlayDiv = null; 25773 } 25774 } 25775 25776 if ( this.oldValue !== value ) { 25777 this.oldValue = value; 25778 this._trigger( "change" ); 25779 } 25780 if ( value === this.options.max ) { 25781 this._trigger( "complete" ); 25782 } 25783 } 25784} ); 25785 25786} ); 25787 25788 25789 25790 25791/*! 25792 * jQuery UI Selectable 1.13.0 25793 * http://jqueryui.com 25794 * 25795 * Copyright jQuery Foundation and other contributors 25796 * Released under the MIT license. 25797 * http://jquery.org/license 25798 */ 25799 25800//>>label: Selectable 25801//>>group: Interactions 25802//>>description: Allows groups of elements to be selected with the mouse. 25803//>>docs: http://api.jqueryui.com/selectable/ 25804//>>demos: http://jqueryui.com/selectable/ 25805//>>css.structure: ../../themes/base/selectable.css 25806 25807( function( factory ) { 25808 "use strict"; 25809 25810 if ( typeof define === "function" && define.amd ) { 25811 25812 // AMD. Register as an anonymous module. 25813 define( [ 25814 "jquery", 25815 "./mouse", 25816 "../version", 25817 "../widget" 25818 ], factory ); 25819 } else { 25820 25821 // Browser globals 25822 factory( jQuery ); 25823 } 25824} )( function( $ ) { 25825"use strict"; 25826 25827return $.widget( "ui.selectable", $.ui.mouse, { 25828 version: "1.13.0
vendor: 7,293 bytes, lines 25828-26106
25828", 25829 options: { 25830 appendTo: "body", 25831 autoRefresh: true, 25832 distance: 0, 25833 filter: "*", 25834 tolerance: "touch", 25835 25836 // Callbacks 25837 selected: null, 25838 selecting: null, 25839 start: null, 25840 stop: null, 25841 unselected: null, 25842 unselecting: null 25843 }, 25844 _create: function() { 25845 var that = this; 25846 25847 this._addClass( "ui-selectable" ); 25848 25849 this.dragged = false; 25850 25851 // Cache selectee children based on filter 25852 this.refresh = function() { 25853 that.elementPos = $( that.element[ 0 ] ).offset(); 25854 that.selectees = $( that.options.filter, that.element[ 0 ] ); 25855 that._addClass( that.selectees, "ui-selectee" ); 25856 that.selectees.each( function() { 25857 var $this = $( this ), 25858 selecteeOffset = $this.offset(), 25859 pos = { 25860 left: selecteeOffset.left - that.elementPos.left, 25861 top: selecteeOffset.top - that.elementPos.top 25862 }; 25863 $.data( this, "selectable-item", { 25864 element: this, 25865 $element: $this, 25866 left: pos.left, 25867 top: pos.top, 25868 right: pos.left + $this.outerWidth(), 25869 bottom: pos.top + $this.outerHeight(), 25870 startselected: false, 25871 selected: $this.hasClass( "ui-selected" ), 25872 selecting: $this.hasClass( "ui-selecting" ), 25873 unselecting: $this.hasClass( "ui-unselecting" ) 25874 } ); 25875 } ); 25876 }; 25877 this.refresh(); 25878 25879 this._mouseInit(); 25880 25881 this.helper = $( "<div>" ); 25882 this._addClass( this.helper, "ui-selectable-helper" ); 25883 }, 25884 25885 _destroy: function() { 25886 this.selectees.removeData( "selectable-item" ); 25887 this._mouseDestroy(); 25888 }, 25889 25890 _mouseStart: function( event ) { 25891 var that = this, 25892 options = this.options; 25893 25894 this.opos = [ event.pageX, event.pageY ]; 25895 this.elementPos = $( this.element[ 0 ] ).offset(); 25896 25897 if ( this.options.disabled ) { 25898 return; 25899 } 25900 25901 this.selectees = $( options.filter, this.element[ 0 ] ); 25902 25903 this._trigger( "start", event ); 25904 25905 $( options.appendTo ).append( this.helper ); 25906 25907 // position helper (lasso) 25908 this.helper.css( { 25909 "left": event.pageX, 25910 "top": event.pageY, 25911 "width": 0, 25912 "height": 0 25913 } ); 25914 25915 if ( options.autoRefresh ) { 25916 this.refresh(); 25917 } 25918 25919 this.selectees.filter( ".ui-selected" ).each( function() { 25920 var selectee = $.data( this, "selectable-item" ); 25921 selectee.startselected = true; 25922 if ( !event.metaKey && !event.ctrlKey ) { 25923 that._removeClass( selectee.$element, "ui-selected" ); 25924 selectee.selected = false; 25925 that._addClass( selectee.$element, "ui-unselecting" ); 25926 selectee.unselecting = true; 25927 25928 // selectable UNSELECTING callback 25929 that._trigger( "unselecting", event, { 25930 unselecting: selectee.element 25931 } ); 25932 } 25933 } ); 25934 25935 $( event.target ).parents().addBack().each( function() { 25936 var doSelect, 25937 selectee = $.data( this, "selectable-item" ); 25938 if ( selectee ) { 25939 doSelect = ( !event.metaKey && !event.ctrlKey ) || 25940 !selectee.$element.hasClass( "ui-selected" ); 25941 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 25942 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 25943 selectee.unselecting = !doSelect; 25944 selectee.selecting = doSelect; 25945 selectee.selected = doSelect; 25946 25947 // selectable (UN)SELECTING callback 25948 if ( doSelect ) { 25949 that._trigger( "selecting", event, { 25950 selecting: selectee.element 25951 } ); 25952 } else { 25953 that._trigger( "unselecting", event, { 25954 unselecting: selectee.element 25955 } ); 25956 } 25957 return false; 25958 } 25959 } ); 25960 25961 }, 25962 25963 _mouseDrag: function( event ) { 25964 25965 this.dragged = true; 25966 25967 if ( this.options.disabled ) { 25968 return; 25969 } 25970 25971 var tmp, 25972 that = this, 25973 options = this.options, 25974 x1 = this.opos[ 0 ], 25975 y1 = this.opos[ 1 ], 25976 x2 = event.pageX, 25977 y2 = event.pageY; 25978 25979 if ( x1 > x2 ) { 25980 tmp = x2; x2 = x1; x1 = tmp; 25981 } 25982 if ( y1 > y2 ) { 25983 tmp = y2; y2 = y1; y1 = tmp; 25984 } 25985 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 25986 25987 this.selectees.each( function() { 25988 var selectee = $.data( this, "selectable-item" ), 25989 hit = false, 25990 offset = {}; 25991 25992 //prevent helper from being selected if appendTo: selectable 25993 if ( !selectee || selectee.element === that.element[ 0 ] ) { 25994 return; 25995 } 25996 25997 offset.left = selectee.left + that.elementPos.left; 25998 offset.right = selectee.right + that.elementPos.left; 25999 offset.top = selectee.top + that.elementPos.top; 26000 offset.bottom = selectee.bottom + that.elementPos.top; 26001 26002 if ( options.tolerance === "touch" ) { 26003 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 26004 offset.bottom < y1 ) ); 26005 } else if ( options.tolerance === "fit" ) { 26006 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 26007 offset.bottom < y2 ); 26008 } 26009 26010 if ( hit ) { 26011 26012 // SELECT 26013 if ( selectee.selected ) { 26014 that._removeClass( selectee.$element, "ui-selected" ); 26015 selectee.selected = false; 26016 } 26017 if ( selectee.unselecting ) { 26018 that._removeClass( selectee.$element, "ui-unselecting" ); 26019 selectee.unselecting = false; 26020 } 26021 if ( !selectee.selecting ) { 26022 that._addClass( selectee.$element, "ui-selecting" ); 26023 selectee.selecting = true; 26024 26025 // selectable SELECTING callback 26026 that._trigger( "selecting", event, { 26027 selecting: selectee.element 26028 } ); 26029 } 26030 } else { 26031 26032 // UNSELECT 26033 if ( selectee.selecting ) { 26034 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 26035 that._removeClass( selectee.$element, "ui-selecting" ); 26036 selectee.selecting = false; 26037 that._addClass( selectee.$element, "ui-selected" ); 26038 selectee.selected = true; 26039 } else { 26040 that._removeClass( selectee.$element, "ui-selecting" ); 26041 selectee.selecting = false; 26042 if ( selectee.startselected ) { 26043 that._addClass( selectee.$element, "ui-unselecting" ); 26044 selectee.unselecting = true; 26045 } 26046 26047 // selectable UNSELECTING callback 26048 that._trigger( "unselecting", event, { 26049 unselecting: selectee.element 26050 } ); 26051 } 26052 } 26053 if ( selectee.selected ) { 26054 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 26055 that._removeClass( selectee.$element, "ui-selected" ); 26056 selectee.selected = false; 26057 26058 that._addClass( selectee.$element, "ui-unselecting" ); 26059 selectee.unselecting = true; 26060 26061 // selectable UNSELECTING callback 26062 that._trigger( "unselecting", event, { 26063 unselecting: selectee.element 26064 } ); 26065 } 26066 } 26067 } 26068 } ); 26069 26070 return false; 26071 }, 26072 26073 _mouseStop: function( event ) { 26074 var that = this; 26075 26076 this.dragged = false; 26077 26078 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 26079 var selectee = $.data( this, "selectable-item" ); 26080 that._removeClass( selectee.$element, "ui-unselecting" ); 26081 selectee.unselecting = false; 26082 selectee.startselected = false; 26083 that._trigger( "unselected", event, { 26084 unselected: selectee.element 26085 } ); 26086 } ); 26087 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 26088 var selectee = $.data( this, "selectable-item" ); 26089 that._removeClass( selectee.$element, "ui-selecting" ) 26090 ._addClass( selectee.$element, "ui-selected" ); 26091 selectee.selecting = false; 26092 selectee.selected = true; 26093 selectee.startselected = true; 26094 that._trigger( "selected", event, { 26095 selected: selectee.element 26096 } ); 26097 } ); 26098 this._trigger( "stop", event ); 26099 26100 this.helper.remove(); 26101 26102 return false; 26103 } 26104 26105} ); 26106
vendor: 1,979 bytes, lines 26107-26202
26107} ); 26108 26109 26110 26111 26112 26113 26114 26115 26116 26117/*! 26118 * jQuery UI Selectmenu 1.13.0 26119 * http://jqueryui.com 26120 * 26121 * Copyright jQuery Foundation and other contributors 26122 * Released under the MIT license. 26123 * http://jquery.org/license 26124 */ 26125 26126//>>label: Selectmenu 26127//>>group: Widgets 26128/* eslint-disable max-len */ 26129//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. 26130/* eslint-enable max-len */ 26131//>>docs: http://api.jqueryui.com/selectmenu/ 26132//>>demos: http://jqueryui.com/selectmenu/ 26133//>>css.structure: ../../themes/base/core.css 26134//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 26135//>>css.theme: ../../themes/base/theme.css 26136 26137( function( factory ) { 26138 "use strict"; 26139 26140 if ( typeof define === "function" && define.amd ) { 26141 26142 // AMD. Register as an anonymous module. 26143 define( [ 26144 "jquery", 26145 "./menu", 26146 "../form-reset-mixin", 26147 "../keycode", 26148 "../labels", 26149 "../position", 26150 "../unique-id", 26151 "../version", 26152 "../widget" 26153 ], factory ); 26154 } else { 26155 26156 // Browser globals 26157 factory( jQuery ); 26158 } 26159} )( function( $ ) { 26160"use strict"; 26161 26162return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 26163 version: "1.13.0", 26164 defaultElement: "<select>", 26165 options: { 26166 appendTo: null, 26167 classes: { 26168 "ui-selectmenu-button-open": "ui-corner-top", 26169 "ui-selectmenu-button-closed": "ui-corner-all" 26170 }, 26171 disabled: null, 26172 icons: { 26173 button: "ui-icon-triangle-1-s" 26174 }, 26175 position: { 26176 my: "left top", 26177 at: "left bottom", 26178 collision: "none" 26179 }, 26180 width: false, 26181 26182 // Callbacks 26183 change: null, 26184 close: null, 26185 focus: null, 26186 open: null, 26187 select: null 26188 }, 26189 26190 _create: function() { 26191 var selectmenuId = this.element.uniqueId().attr( "id" ); 26192 this.ids = { 26193 element: selectmenuId, 26194 button: selectmenuId + "-button", 26195 menu: selectmenuId + "-menu" 26196 }; 26197 26198 this._drawButton(); 26199 this._drawMenu(); 26200 this._bindFormResetHandler(); 26201 26202 this._rendered = false;
vendor: 5,200 bytes, lines 26203-26409
26203 this.menuItems = $(); 26204 }, 26205 26206 _drawButton: function() { 26207 var icon, 26208 that = this, 26209 item = this._parseOption( 26210 this.element.find( "option:selected" ), 26211 this.element[ 0 ].selectedIndex 26212 ); 26213 26214 // Associate existing label with the new button 26215 this.labels = this.element.labels().attr( "for", this.ids.button ); 26216 this._on( this.labels, { 26217 click: function( event ) { 26218 this.button.trigger( "focus" ); 26219 event.preventDefault(); 26220 } 26221 } ); 26222 26223 // Hide original select element 26224 this.element.hide(); 26225 26226 // Create button 26227 this.button = $( "<span>", { 26228 tabindex: this.options.disabled ? -1 : 0, 26229 id: this.ids.button, 26230 role: "combobox", 26231 "aria-expanded": "false", 26232 "aria-autocomplete": "list", 26233 "aria-owns": this.ids.menu, 26234 "aria-haspopup": "true", 26235 title: this.element.attr( "title" ) 26236 } ) 26237 .insertAfter( this.element ); 26238 26239 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 26240 "ui-button ui-widget" ); 26241 26242 icon = $( "<span>" ).appendTo( this.button ); 26243 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 26244 this.buttonItem = this._renderButtonItem( item ) 26245 .appendTo( this.button ); 26246 26247 if ( this.options.width !== false ) { 26248 this._resizeButton(); 26249 } 26250 26251 this._on( this.button, this._buttonEvents ); 26252 this.button.one( "focusin", function() { 26253 26254 // Delay rendering the menu items until the button receives focus. 26255 // The menu may have already been rendered via a programmatic open. 26256 if ( !that._rendered ) { 26257 that._refreshMenu(); 26258 } 26259 } ); 26260 }, 26261 26262 _drawMenu: function() { 26263 var that = this; 26264 26265 // Create menu 26266 this.menu = $( "<ul>", { 26267 "aria-hidden": "true", 26268 "aria-labelledby": this.ids.button, 26269 id: this.ids.menu 26270 } ); 26271 26272 // Wrap menu 26273 this.menuWrap = $( "<div>" ).append( this.menu ); 26274 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 26275 this.menuWrap.appendTo( this._appendTo() ); 26276 26277 // Initialize menu widget 26278 this.menuInstance = this.menu 26279 .menu( { 26280 classes: { 26281 "ui-menu": "ui-corner-bottom" 26282 }, 26283 role: "listbox", 26284 select: function( event, ui ) { 26285 event.preventDefault(); 26286 26287 // Support: IE8 26288 // If the item was selected via a click, the text selection 26289 // will be destroyed in IE 26290 that._setSelection(); 26291 26292 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 26293 }, 26294 focus: function( event, ui ) { 26295 var item = ui.item.data( "ui-selectmenu-item" ); 26296 26297 // Prevent inital focus from firing and check if its a newly focused item 26298 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 26299 that._trigger( "focus", event, { item: item } ); 26300 if ( !that.isOpen ) { 26301 that._select( item, event ); 26302 } 26303 } 26304 that.focusIndex = item.index; 26305 26306 that.button.attr( "aria-activedescendant", 26307 that.menuItems.eq( item.index ).attr( "id" ) ); 26308 } 26309 } ) 26310 .menu( "instance" ); 26311 26312 // Don't close the menu on mouseleave 26313 this.menuInstance._off( this.menu, "mouseleave" ); 26314 26315 // Cancel the menu's collapseAll on document click 26316 this.menuInstance._closeOnDocumentClick = function() { 26317 return false; 26318 }; 26319 26320 // Selects often contain empty items, but never contain dividers 26321 this.menuInstance._isDivider = function() { 26322 return false; 26323 }; 26324 }, 26325 26326 refresh: function() { 26327 this._refreshMenu(); 26328 this.buttonItem.replaceWith( 26329 this.buttonItem = this._renderButtonItem( 26330 26331 // Fall back to an empty object in case there are no options 26332 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 26333 ) 26334 ); 26335 if ( this.options.width === null ) { 26336 this._resizeButton(); 26337 } 26338 }, 26339 26340 _refreshMenu: function() { 26341 var item, 26342 options = this.element.find( "option" ); 26343 26344 this.menu.empty(); 26345 26346 this._parseOptions( options ); 26347 this._renderMenu( this.menu, this.items ); 26348 26349 this.menuInstance.refresh(); 26350 this.menuItems = this.menu.find( "li" ) 26351 .not( ".ui-selectmenu-optgroup" ) 26352 .find( ".ui-menu-item-wrapper" ); 26353 26354 this._rendered = true; 26355 26356 if ( !options.length ) { 26357 return; 26358 } 26359 26360 item = this._getSelectedItem(); 26361 26362 // Update the menu to have the correct item focused 26363 this.menuInstance.focus( null, item ); 26364 this._setAria( item.data( "ui-selectmenu-item" ) ); 26365 26366 // Set disabled state 26367 this._setOption( "disabled", this.element.prop( "disabled" ) ); 26368 }, 26369 26370 open: function( event ) { 26371 if ( this.options.disabled ) { 26372 return; 26373 } 26374 26375 // If this is the first time the menu is being opened, render the items 26376 if ( !this._rendered ) { 26377 this._refreshMenu(); 26378 } else { 26379 26380 // Menu clears focus on close, reset focus to selected item 26381 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 26382 this.menuInstance.focus( null, this._getSelectedItem() ); 26383 } 26384 26385 // If there are no options, don't open the menu 26386 if ( !this.menuItems.length ) { 26387 return; 26388 } 26389 26390 this.isOpen = true; 26391 this._toggleAttr(); 26392 this._resizeMenu(); 26393 this._position(); 26394 26395 this._on( this.document, this._documentClick ); 26396 26397 this._trigger( "open", event ); 26398 }, 26399 26400 _position: function() { 26401 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 26402 }, 26403 26404 close: function( event ) { 26405 if ( !this.isOpen ) { 26406 return; 26407 } 26408 26409 this.isOpen = false;
vendor: 2,743 bytes, lines 26410-26536
26410 this._toggleAttr(); 26411 26412 this.range = null; 26413 this._off( this.document ); 26414 26415 this._trigger( "close", event ); 26416 }, 26417 26418 widget: function() { 26419 return this.button; 26420 }, 26421 26422 menuWidget: function() { 26423 return this.menu; 26424 }, 26425 26426 _renderButtonItem: function( item ) { 26427 var buttonItem = $( "<span>" ); 26428 26429 this._setText( buttonItem, item.label ); 26430 this._addClass( buttonItem, "ui-selectmenu-text" ); 26431 26432 return buttonItem; 26433 }, 26434 26435 _renderMenu: function( ul, items ) { 26436 var that = this, 26437 currentOptgroup = ""; 26438 26439 $.each( items, function( index, item ) { 26440 var li; 26441 26442 if ( item.optgroup !== currentOptgroup ) { 26443 li = $( "<li>", { 26444 text: item.optgroup 26445 } ); 26446 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 26447 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 26448 " ui-state-disabled" : 26449 "" ) ); 26450 26451 li.appendTo( ul ); 26452 26453 currentOptgroup = item.optgroup; 26454 } 26455 26456 that._renderItemData( ul, item ); 26457 } ); 26458 }, 26459 26460 _renderItemData: function( ul, item ) { 26461 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 26462 }, 26463 26464 _renderItem: function( ul, item ) { 26465 var li = $( "<li>" ), 26466 wrapper = $( "<div>", { 26467 title: item.element.attr( "title" ) 26468 } ); 26469 26470 if ( item.disabled ) { 26471 this._addClass( li, null, "ui-state-disabled" ); 26472 } 26473 this._setText( wrapper, item.label ); 26474 26475 return li.append( wrapper ).appendTo( ul ); 26476 }, 26477 26478 _setText: function( element, value ) { 26479 if ( value ) { 26480 element.text( value ); 26481 } else { 26482 element.html( " " ); 26483 } 26484 }, 26485 26486 _move: function( direction, event ) { 26487 var item, next, 26488 filter = ".ui-menu-item"; 26489 26490 if ( this.isOpen ) { 26491 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 26492 } else { 26493 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 26494 filter += ":not(.ui-state-disabled)"; 26495 } 26496 26497 if ( direction === "first" || direction === "last" ) { 26498 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 26499 } else { 26500 next = item[ direction + "All" ]( filter ).eq( 0 ); 26501 } 26502 26503 if ( next.length ) { 26504 this.menuInstance.focus( event, next ); 26505 } 26506 }, 26507 26508 _getSelectedItem: function() { 26509 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 26510 }, 26511 26512 _toggle: function( event ) { 26513 this[ this.isOpen ? "close" : "open" ]( event ); 26514 }, 26515 26516 _setSelection: function() { 26517 var selection; 26518 26519 if ( !this.range ) { 26520 return; 26521 } 26522 26523 if ( window.getSelection ) { 26524 selection = window.getSelection(); 26525 selection.removeAllRanges(); 26526 selection.addRange( this.range ); 26527 26528 // Support: IE8 26529 } else { 26530 this.range.select(); 26531 } 26532 26533 // Support: IE 26534 // Setting the text selection kills the button focus in IE, but 26535 // restoring the focus doesn't kill the selection. 26536 this.button.focus(
vendor: 5,664 bytes, lines 26536-26777
26536); 26537 }, 26538 26539 _documentClick: { 26540 mousedown: function( event ) { 26541 if ( !this.isOpen ) { 26542 return; 26543 } 26544 26545 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 26546 $.escapeSelector( this.ids.button ) ).length ) { 26547 this.close( event ); 26548 } 26549 } 26550 }, 26551 26552 _buttonEvents: { 26553 26554 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 26555 mousedown: function() { 26556 var selection; 26557 26558 if ( window.getSelection ) { 26559 selection = window.getSelection(); 26560 if ( selection.rangeCount ) { 26561 this.range = selection.getRangeAt( 0 ); 26562 } 26563 26564 // Support: IE8 26565 } else { 26566 this.range = document.selection.createRange(); 26567 } 26568 }, 26569 26570 click: function( event ) { 26571 this._setSelection(); 26572 this._toggle( event ); 26573 }, 26574 26575 keydown: function( event ) { 26576 var preventDefault = true; 26577 switch ( event.keyCode ) { 26578 case $.ui.keyCode.TAB: 26579 case $.ui.keyCode.ESCAPE: 26580 this.close( event ); 26581 preventDefault = false; 26582 break; 26583 case $.ui.keyCode.ENTER: 26584 if ( this.isOpen ) { 26585 this._selectFocusedItem( event ); 26586 } 26587 break; 26588 case $.ui.keyCode.UP: 26589 if ( event.altKey ) { 26590 this._toggle( event ); 26591 } else { 26592 this._move( "prev", event ); 26593 } 26594 break; 26595 case $.ui.keyCode.DOWN: 26596 if ( event.altKey ) { 26597 this._toggle( event ); 26598 } else { 26599 this._move( "next", event ); 26600 } 26601 break; 26602 case $.ui.keyCode.SPACE: 26603 if ( this.isOpen ) { 26604 this._selectFocusedItem( event ); 26605 } else { 26606 this._toggle( event ); 26607 } 26608 break; 26609 case $.ui.keyCode.LEFT: 26610 this._move( "prev", event ); 26611 break; 26612 case $.ui.keyCode.RIGHT: 26613 this._move( "next", event ); 26614 break; 26615 case $.ui.keyCode.HOME: 26616 case $.ui.keyCode.PAGE_UP: 26617 this._move( "first", event ); 26618 break; 26619 case $.ui.keyCode.END: 26620 case $.ui.keyCode.PAGE_DOWN: 26621 this._move( "last", event ); 26622 break; 26623 default: 26624 this.menu.trigger( event ); 26625 preventDefault = false; 26626 } 26627 26628 if ( preventDefault ) { 26629 event.preventDefault(); 26630 } 26631 } 26632 }, 26633 26634 _selectFocusedItem: function( event ) { 26635 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 26636 if ( !item.hasClass( "ui-state-disabled" ) ) { 26637 this._select( item.data( "ui-selectmenu-item" ), event ); 26638 } 26639 }, 26640 26641 _select: function( item, event ) { 26642 var oldIndex = this.element[ 0 ].selectedIndex; 26643 26644 // Change native select element 26645 this.element[ 0 ].selectedIndex = item.index; 26646 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 26647 this._setAria( item ); 26648 this._trigger( "select", event, { item: item } ); 26649 26650 if ( item.index !== oldIndex ) { 26651 this._trigger( "change", event, { item: item } ); 26652 } 26653 26654 this.close( event ); 26655 }, 26656 26657 _setAria: function( item ) { 26658 var id = this.menuItems.eq( item.index ).attr( "id" ); 26659 26660 this.button.attr( { 26661 "aria-labelledby": id, 26662 "aria-activedescendant": id 26663 } ); 26664 this.menu.attr( "aria-activedescendant", id ); 26665 }, 26666 26667 _setOption: function( key, value ) { 26668 if ( key === "icons" ) { 26669 var icon = this.button.find( "span.ui-icon" ); 26670 this._removeClass( icon, null, this.options.icons.button ) 26671 ._addClass( icon, null, value.button ); 26672 } 26673 26674 this._super( key, value ); 26675 26676 if ( key === "appendTo" ) { 26677 this.menuWrap.appendTo( this._appendTo() ); 26678 } 26679 26680 if ( key === "width" ) { 26681 this._resizeButton(); 26682 } 26683 }, 26684 26685 _setOptionDisabled: function( value ) { 26686 this._super( value ); 26687 26688 this.menuInstance.option( "disabled", value ); 26689 this.button.attr( "aria-disabled", value ); 26690 this._toggleClass( this.button, null, "ui-state-disabled", value ); 26691 26692 this.element.prop( "disabled", value ); 26693 if ( value ) { 26694 this.button.attr( "tabindex", -1 ); 26695 this.close(); 26696 } else { 26697 this.button.attr( "tabindex", 0 ); 26698 } 26699 }, 26700 26701 _appendTo: function() { 26702 var element = this.options.appendTo; 26703 26704 if ( element ) { 26705 element = element.jquery || element.nodeType ? 26706 $( element ) : 26707 this.document.find( element ).eq( 0 ); 26708 } 26709 26710 if ( !element || !element[ 0 ] ) { 26711 element = this.element.closest( ".ui-front, dialog" ); 26712 } 26713 26714 if ( !element.length ) { 26715 element = this.document[ 0 ].body; 26716 } 26717 26718 return element; 26719 }, 26720 26721 _toggleAttr: function() { 26722 this.button.attr( "aria-expanded", this.isOpen ); 26723 26724 // We can't use two _toggleClass() calls here, because we need to make sure 26725 // we always remove classes first and add them second, otherwise if both classes have the 26726 // same theme class, it will be removed after we add it. 26727 this._removeClass( this.button, "ui-selectmenu-button-" + 26728 ( this.isOpen ? "closed" : "open" ) ) 26729 ._addClass( this.button, "ui-selectmenu-button-" + 26730 ( this.isOpen ? "open" : "closed" ) ) 26731 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 26732 26733 this.menu.attr( "aria-hidden", !this.isOpen ); 26734 }, 26735 26736 _resizeButton: function() { 26737 var width = this.options.width; 26738 26739 // For `width: false`, just remove inline style and stop 26740 if ( width === false ) { 26741 this.button.css( "width", "" ); 26742 return; 26743 } 26744 26745 // For `width: null`, match the width of the original element 26746 if ( width === null ) { 26747 width = this.element.show().outerWidth(); 26748 this.element.hide(); 26749 } 26750 26751 this.button.outerWidth( width ); 26752 }, 26753 26754 _resizeMenu: function() { 26755 this.menu.outerWidth( Math.max( 26756 this.button.outerWidth(), 26757 26758 // Support: IE10 26759 // IE10 wraps long text (possibly a rounding bug) 26760 // so we add 1px to avoid the wrapping 26761 this.menu.width( "" ).outerWidth() + 1 26762 ) ); 26763 }, 26764 26765 _getCreateOptions: function() { 26766 var options = this._super(); 26767 26768 options.disabled = this.element.prop( "disabled" ); 26769 26770 return options; 26771 }, 26772 26773 _parseOptions: function( options ) { 26774 var that = this, 26775 data = []; 26776 options.each( function( index, item ) { 26777
vendor: 3,996 bytes, lines 26777-26952
26777if ( item.hidden ) { 26778 return; 26779 } 26780 26781 data.push( that._parseOption( $( item ), index ) ); 26782 } ); 26783 this.items = data; 26784 }, 26785 26786 _parseOption: function( option, index ) { 26787 var optgroup = option.parent( "optgroup" ); 26788 26789 return { 26790 element: option, 26791 index: index, 26792 value: option.val(), 26793 label: option.text(), 26794 optgroup: optgroup.attr( "label" ) || "", 26795 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 26796 }; 26797 }, 26798 26799 _destroy: function() { 26800 this._unbindFormResetHandler(); 26801 this.menuWrap.remove(); 26802 this.button.remove(); 26803 this.element.show(); 26804 this.element.removeUniqueId(); 26805 this.labels.attr( "for", this.ids.element ); 26806 } 26807} ] ); 26808 26809} ); 26810 26811 26812 26813 26814 26815/*! 26816 * jQuery UI Slider 1.13.0 26817 * http://jqueryui.com 26818 * 26819 * Copyright jQuery Foundation and other contributors 26820 * Released under the MIT license. 26821 * http://jquery.org/license 26822 */ 26823 26824//>>label: Slider 26825//>>group: Widgets 26826//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 26827//>>docs: http://api.jqueryui.com/slider/ 26828//>>demos: http://jqueryui.com/slider/ 26829//>>css.structure: ../../themes/base/core.css 26830//>>css.structure: ../../themes/base/slider.css 26831//>>css.theme: ../../themes/base/theme.css 26832 26833( function( factory ) { 26834 "use strict"; 26835 26836 if ( typeof define === "function" && define.amd ) { 26837 26838 // AMD. Register as an anonymous module. 26839 define( [ 26840 "jquery", 26841 "./mouse", 26842 "../keycode", 26843 "../version", 26844 "../widget" 26845 ], factory ); 26846 } else { 26847 26848 // Browser globals 26849 factory( jQuery ); 26850 } 26851} )( function( $ ) { 26852"use strict"; 26853 26854return $.widget( "ui.slider", $.ui.mouse, { 26855 version: "1.13.0", 26856 widgetEventPrefix: "slide", 26857 26858 options: { 26859 animate: false, 26860 classes: { 26861 "ui-slider": "ui-corner-all", 26862 "ui-slider-handle": "ui-corner-all", 26863 26864 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 26865 // element, but worked best visually with a variety of themes 26866 "ui-slider-range": "ui-corner-all ui-widget-header" 26867 }, 26868 distance: 0, 26869 max: 100, 26870 min: 0, 26871 orientation: "horizontal", 26872 range: false, 26873 step: 1, 26874 value: 0, 26875 values: null, 26876 26877 // Callbacks 26878 change: null, 26879 slide: null, 26880 start: null, 26881 stop: null 26882 }, 26883 26884 // Number of pages in a slider 26885 // (how many times can you page up/down to go through the whole range) 26886 numPages: 5, 26887 26888 _create: function() { 26889 this._keySliding = false; 26890 this._mouseSliding = false; 26891 this._animateOff = true; 26892 this._handleIndex = null; 26893 this._detectOrientation(); 26894 this._mouseInit(); 26895 this._calculateNewMax(); 26896 26897 this._addClass( "ui-slider ui-slider-" + this.orientation, 26898 "ui-widget ui-widget-content" ); 26899 26900 this._refresh(); 26901 26902 this._animateOff = false; 26903 }, 26904 26905 _refresh: function() { 26906 this._createRange(); 26907 this._createHandles(); 26908 this._setupEvents(); 26909 this._refreshValue(); 26910 }, 26911 26912 _createHandles: function() { 26913 var i, handleCount, 26914 options = this.options, 26915 existingHandles = this.element.find( ".ui-slider-handle" ), 26916 handle = "<span tabindex='0'></span>", 26917 handles = []; 26918 26919 handleCount = ( options.values && options.values.length ) || 1; 26920 26921 if ( existingHandles.length > handleCount ) { 26922 existingHandles.slice( handleCount ).remove(); 26923 existingHandles = existingHandles.slice( 0, handleCount ); 26924 } 26925 26926 for ( i = existingHandles.length; i < handleCount; i++ ) { 26927 handles.push( handle ); 26928 } 26929 26930 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 26931 26932 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 26933 26934 this.handle = this.handles.eq( 0 ); 26935 26936 this.handles.each( function( i ) { 26937 $( this ) 26938 .data( "ui-slider-handle-index", i ) 26939 .attr( "tabIndex", 0 ); 26940 } ); 26941 }, 26942 26943 _createRange: function() { 26944 var options = this.options; 26945 26946 if ( options.range ) { 26947 if ( options.range === true ) { 26948 if ( !options.values ) { 26949 options.values = [ this._valueMin(), this._valueMin() ]; 26950 } else if ( options.values.length && options.values.length !== 2 ) { 26951 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 26952 } else if ( Array
vendor: 6,343 bytes, lines 26952-27198
26952.isArray( options.values ) ) { 26953 options.values = options.values.slice( 0 ); 26954 } 26955 } 26956 26957 if ( !this.range || !this.range.length ) { 26958 this.range = $( "<div>" ) 26959 .appendTo( this.element ); 26960 26961 this._addClass( this.range, "ui-slider-range" ); 26962 } else { 26963 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 26964 26965 // Handle range switching from true to min/max 26966 this.range.css( { 26967 "left": "", 26968 "bottom": "" 26969 } ); 26970 } 26971 if ( options.range === "min" || options.range === "max" ) { 26972 this._addClass( this.range, "ui-slider-range-" + options.range ); 26973 } 26974 } else { 26975 if ( this.range ) { 26976 this.range.remove(); 26977 } 26978 this.range = null; 26979 } 26980 }, 26981 26982 _setupEvents: function() { 26983 this._off( this.handles ); 26984 this._on( this.handles, this._handleEvents ); 26985 this._hoverable( this.handles ); 26986 this._focusable( this.handles ); 26987 }, 26988 26989 _destroy: function() { 26990 this.handles.remove(); 26991 if ( this.range ) { 26992 this.range.remove(); 26993 } 26994 26995 this._mouseDestroy(); 26996 }, 26997 26998 _mouseCapture: function( event ) { 26999 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, 27000 that = this, 27001 o = this.options; 27002 27003 if ( o.disabled ) { 27004 return false; 27005 } 27006 27007 this.elementSize = { 27008 width: this.element.outerWidth(), 27009 height: this.element.outerHeight() 27010 }; 27011 this.elementOffset = this.element.offset(); 27012 27013 position = { x: event.pageX, y: event.pageY }; 27014 normValue = this._normValueFromMouse( position ); 27015 distance = this._valueMax() - this._valueMin() + 1; 27016 this.handles.each( function( i ) { 27017 var thisDistance = Math.abs( normValue - that.values( i ) ); 27018 if ( ( distance > thisDistance ) || 27019 ( distance === thisDistance && 27020 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 27021 distance = thisDistance; 27022 closestHandle = $( this ); 27023 index = i; 27024 } 27025 } ); 27026 27027 allowed = this._start( event, index ); 27028 if ( allowed === false ) { 27029 return false; 27030 } 27031 this._mouseSliding = true; 27032 27033 this._handleIndex = index; 27034 27035 this._addClass( closestHandle, null, "ui-state-active" ); 27036 closestHandle.trigger( "focus" ); 27037 27038 offset = closestHandle.offset(); 27039 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 27040 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 27041 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 27042 top: event.pageY - offset.top - 27043 ( closestHandle.height() / 2 ) - 27044 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 27045 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 27046 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 27047 }; 27048 27049 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 27050 this._slide( event, index, normValue ); 27051 } 27052 this._animateOff = true; 27053 return true; 27054 }, 27055 27056 _mouseStart: function() { 27057 return true; 27058 }, 27059 27060 _mouseDrag: function( event ) { 27061 var position = { x: event.pageX, y: event.pageY }, 27062 normValue = this._normValueFromMouse( position ); 27063 27064 this._slide( event, this._handleIndex, normValue ); 27065 27066 return false; 27067 }, 27068 27069 _mouseStop: function( event ) { 27070 this._removeClass( this.handles, null, "ui-state-active" ); 27071 this._mouseSliding = false; 27072 27073 this._stop( event, this._handleIndex ); 27074 this._change( event, this._handleIndex ); 27075 27076 this._handleIndex = null; 27077 this._clickOffset = null; 27078 this._animateOff = false; 27079 27080 return false; 27081 }, 27082 27083 _detectOrientation: function() { 27084 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 27085 }, 27086 27087 _normValueFromMouse: function( position ) { 27088 var pixelTotal, 27089 pixelMouse, 27090 percentMouse, 27091 valueTotal, 27092 valueMouse; 27093 27094 if ( this.orientation === "horizontal" ) { 27095 pixelTotal = this.elementSize.width; 27096 pixelMouse = position.x - this.elementOffset.left - 27097 ( this._clickOffset ? this._clickOffset.left : 0 ); 27098 } else { 27099 pixelTotal = this.elementSize.height; 27100 pixelMouse = position.y - this.elementOffset.top - 27101 ( this._clickOffset ? this._clickOffset.top : 0 ); 27102 } 27103 27104 percentMouse = ( pixelMouse / pixelTotal ); 27105 if ( percentMouse > 1 ) { 27106 percentMouse = 1; 27107 } 27108 if ( percentMouse < 0 ) { 27109 percentMouse = 0; 27110 } 27111 if ( this.orientation === "vertical" ) { 27112 percentMouse = 1 - percentMouse; 27113 } 27114 27115 valueTotal = this._valueMax() - this._valueMin(); 27116 valueMouse = this._valueMin() + percentMouse * valueTotal; 27117 27118 return this._trimAlignValue( valueMouse ); 27119 }, 27120 27121 _uiHash: function( index, value, values ) { 27122 var uiHash = { 27123 handle: this.handles[ index ], 27124 handleIndex: index, 27125 value: value !== undefined ? value : this.value() 27126 }; 27127 27128 if ( this._hasMultipleValues() ) { 27129 uiHash.value = value !== undefined ? value : this.values( index ); 27130 uiHash.values = values || this.values(); 27131 } 27132 27133 return uiHash; 27134 }, 27135 27136 _hasMultipleValues: function() { 27137 return this.options.values && this.options.values.length; 27138 }, 27139 27140 _start: function( event, index ) { 27141 return this._trigger( "start", event, this._uiHash( index ) ); 27142 }, 27143 27144 _slide: function( event, index, newVal ) { 27145 var allowed, otherVal, 27146 currentValue = this.value(), 27147 newValues = this.values(); 27148 27149 if ( this._hasMultipleValues() ) { 27150 otherVal = this.values( index ? 0 : 1 ); 27151 currentValue = this.values( index ); 27152 27153 if ( this.options.values.length === 2 && this.options.range === true ) { 27154 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 27155 } 27156 27157 newValues[ index ] = newVal; 27158 } 27159 27160 if ( newVal === currentValue ) { 27161 return; 27162 } 27163 27164 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 27165 27166 // A slide can be canceled by returning false from the slide callback 27167 if ( allowed === false ) { 27168 return; 27169 } 27170 27171 if ( this._hasMultipleValues() ) { 27172 this.values( index, newVal ); 27173 } else { 27174 this.value( newVal ); 27175 } 27176 }, 27177 27178 _stop: function( event, index ) { 27179 this._trigger( "stop", event, this._uiHash( index ) ); 27180 }, 27181 27182 _change: function( event, index ) { 27183 if ( !this._keySliding && !this._mouseSliding ) { 27184 27185 //store the last changed value index for reference when handles overlap 27186 this._lastChangedValue = index; 27187 this._trigger( "change", event, this._uiHash( index ) ); 27188 } 27189 }, 27190 27191 value: function( newValue ) { 27192 if ( arguments.length ) { 27193 this.options.value = this._trimAlignValue( newValue ); 27194 this._refreshValue(); 27195 this._change( null, 0 ); 27196 return; 27197 } 27198
vendor: 4,358 bytes, lines 27199-27371
27199 return this._value(); 27200 }, 27201 27202 values: function( index, newValue ) { 27203 var vals, 27204 newValues, 27205 i; 27206 27207 if ( arguments.length > 1 ) { 27208 this.options.values[ index ] = this._trimAlignValue( newValue ); 27209 this._refreshValue(); 27210 this._change( null, index ); 27211 return; 27212 } 27213 27214 if ( arguments.length ) { 27215 if ( Array.isArray( arguments[ 0 ] ) ) { 27216 vals = this.options.values; 27217 newValues = arguments[ 0 ]; 27218 for ( i = 0; i < vals.length; i += 1 ) { 27219 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 27220 this._change( null, i ); 27221 } 27222 this._refreshValue(); 27223 } else { 27224 if ( this._hasMultipleValues() ) { 27225 return this._values( index ); 27226 } else { 27227 return this.value(); 27228 } 27229 } 27230 } else { 27231 return this._values(); 27232 } 27233 }, 27234 27235 _setOption: function( key, value ) { 27236 var i, 27237 valsLength = 0; 27238 27239 if ( key === "range" && this.options.range === true ) { 27240 if ( value === "min" ) { 27241 this.options.value = this._values( 0 ); 27242 this.options.values = null; 27243 } else if ( value === "max" ) { 27244 this.options.value = this._values( this.options.values.length - 1 ); 27245 this.options.values = null; 27246 } 27247 } 27248 27249 if ( Array.isArray( this.options.values ) ) { 27250 valsLength = this.options.values.length; 27251 } 27252 27253 this._super( key, value ); 27254 27255 switch ( key ) { 27256 case "orientation": 27257 this._detectOrientation(); 27258 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 27259 ._addClass( "ui-slider-" + this.orientation ); 27260 this._refreshValue(); 27261 if ( this.options.range ) { 27262 this._refreshRange( value ); 27263 } 27264 27265 // Reset positioning from previous orientation 27266 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 27267 break; 27268 case "value": 27269 this._animateOff = true; 27270 this._refreshValue(); 27271 this._change( null, 0 ); 27272 this._animateOff = false; 27273 break; 27274 case "values": 27275 this._animateOff = true; 27276 this._refreshValue(); 27277 27278 // Start from the last handle to prevent unreachable handles (#9046) 27279 for ( i = valsLength - 1; i >= 0; i-- ) { 27280 this._change( null, i ); 27281 } 27282 this._animateOff = false; 27283 break; 27284 case "step": 27285 case "min": 27286 case "max": 27287 this._animateOff = true; 27288 this._calculateNewMax(); 27289 this._refreshValue(); 27290 this._animateOff = false; 27291 break; 27292 case "range": 27293 this._animateOff = true; 27294 this._refresh(); 27295 this._animateOff = false; 27296 break; 27297 } 27298 }, 27299 27300 _setOptionDisabled: function( value ) { 27301 this._super( value ); 27302 27303 this._toggleClass( null, "ui-state-disabled", !!value ); 27304 }, 27305 27306 //internal value getter 27307 // _value() returns value trimmed by min and max, aligned by step 27308 _value: function() { 27309 var val = this.options.value; 27310 val = this._trimAlignValue( val ); 27311 27312 return val; 27313 }, 27314 27315 //internal values getter 27316 // _values() returns array of values trimmed by min and max, aligned by step 27317 // _values( index ) returns single value trimmed by min and max, aligned by step 27318 _values: function( index ) { 27319 var val, 27320 vals, 27321 i; 27322 27323 if ( arguments.length ) { 27324 val = this.options.values[ index ]; 27325 val = this._trimAlignValue( val ); 27326 27327 return val; 27328 } else if ( this._hasMultipleValues() ) { 27329 27330 // .slice() creates a copy of the array 27331 // this copy gets trimmed by min and max and then returned 27332 vals = this.options.values.slice(); 27333 for ( i = 0; i < vals.length; i += 1 ) { 27334 vals[ i ] = this._trimAlignValue( vals[ i ] ); 27335 } 27336 27337 return vals; 27338 } else { 27339 return []; 27340 } 27341 }, 27342 27343 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 27344 _trimAlignValue: function( val ) { 27345 if ( val <= this._valueMin() ) { 27346 return this._valueMin(); 27347 } 27348 if ( val >= this._valueMax() ) { 27349 return this._valueMax(); 27350 } 27351 var step = ( this.options.step > 0 ) ? this.options.step : 1, 27352 valModStep = ( val - this._valueMin() ) % step, 27353 alignValue = val - valModStep; 27354 27355 if ( Math.abs( valModStep ) * 2 >= step ) { 27356 alignValue += ( valModStep > 0 ) ? step : ( -step ); 27357 } 27358 27359 // Since JavaScript has problems with large floats, round 27360 // the final value to 5 digits after the decimal point (see #4124) 27361 return parseFloat( alignValue.toFixed( 5 ) ); 27362 }, 27363 27364 _calculateNewMax: function() { 27365 var max = this.options.max, 27366 min = this._valueMin(), 27367 step = this.options.step, 27368 aboveMin = Math.round( ( max - min ) / step ) * step; 27369 max = aboveMin + min; 27370 if ( max > this.options.max ) { 27371
vendor: 5,564 bytes, lines 27372-27568
27372 //If max is not divisible by step, rounding off may increase its value 27373 max -= step; 27374 } 27375 this.max = parseFloat( max.toFixed( this._precision() ) ); 27376 }, 27377 27378 _precision: function() { 27379 var precision = this._precisionOf( this.options.step ); 27380 if ( this.options.min !== null ) { 27381 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 27382 } 27383 return precision; 27384 }, 27385 27386 _precisionOf: function( num ) { 27387 var str = num.toString(), 27388 decimal = str.indexOf( "." ); 27389 return decimal === -1 ? 0 : str.length - decimal - 1; 27390 }, 27391 27392 _valueMin: function() { 27393 return this.options.min; 27394 }, 27395 27396 _valueMax: function() { 27397 return this.max; 27398 }, 27399 27400 _refreshRange: function( orientation ) { 27401 if ( orientation === "vertical" ) { 27402 this.range.css( { "width": "", "left": "" } ); 27403 } 27404 if ( orientation === "horizontal" ) { 27405 this.range.css( { "height": "", "bottom": "" } ); 27406 } 27407 }, 27408 27409 _refreshValue: function() { 27410 var lastValPercent, valPercent, value, valueMin, valueMax, 27411 oRange = this.options.range, 27412 o = this.options, 27413 that = this, 27414 animate = ( !this._animateOff ) ? o.animate : false, 27415 _set = {}; 27416 27417 if ( this._hasMultipleValues() ) { 27418 this.handles.each( function( i ) { 27419 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 27420 that._valueMin() ) * 100; 27421 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 27422 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 27423 if ( that.options.range === true ) { 27424 if ( that.orientation === "horizontal" ) { 27425 if ( i === 0 ) { 27426 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27427 left: valPercent + "%" 27428 }, o.animate ); 27429 } 27430 if ( i === 1 ) { 27431 that.range[ animate ? "animate" : "css" ]( { 27432 width: ( valPercent - lastValPercent ) + "%" 27433 }, { 27434 queue: false, 27435 duration: o.animate 27436 } ); 27437 } 27438 } else { 27439 if ( i === 0 ) { 27440 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27441 bottom: ( valPercent ) + "%" 27442 }, o.animate ); 27443 } 27444 if ( i === 1 ) { 27445 that.range[ animate ? "animate" : "css" ]( { 27446 height: ( valPercent - lastValPercent ) + "%" 27447 }, { 27448 queue: false, 27449 duration: o.animate 27450 } ); 27451 } 27452 } 27453 } 27454 lastValPercent = valPercent; 27455 } ); 27456 } else { 27457 value = this.value(); 27458 valueMin = this._valueMin(); 27459 valueMax = this._valueMax(); 27460 valPercent = ( valueMax !== valueMin ) ? 27461 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 27462 0; 27463 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 27464 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 27465 27466 if ( oRange === "min" && this.orientation === "horizontal" ) { 27467 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27468 width: valPercent + "%" 27469 }, o.animate ); 27470 } 27471 if ( oRange === "max" && this.orientation === "horizontal" ) { 27472 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27473 width: ( 100 - valPercent ) + "%" 27474 }, o.animate ); 27475 } 27476 if ( oRange === "min" && this.orientation === "vertical" ) { 27477 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27478 height: valPercent + "%" 27479 }, o.animate ); 27480 } 27481 if ( oRange === "max" && this.orientation === "vertical" ) { 27482 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 27483 height: ( 100 - valPercent ) + "%" 27484 }, o.animate ); 27485 } 27486 } 27487 }, 27488 27489 _handleEvents: { 27490 keydown: function( event ) { 27491 var allowed, curVal, newVal, step, 27492 index = $( event.target ).data( "ui-slider-handle-index" ); 27493 27494 switch ( event.keyCode ) { 27495 case $.ui.keyCode.HOME: 27496 case $.ui.keyCode.END: 27497 case $.ui.keyCode.PAGE_UP: 27498 case $.ui.keyCode.PAGE_DOWN: 27499 case $.ui.keyCode.UP: 27500 case $.ui.keyCode.RIGHT: 27501 case $.ui.keyCode.DOWN: 27502 case $.ui.keyCode.LEFT: 27503 event.preventDefault(); 27504 if ( !this._keySliding ) { 27505 this._keySliding = true; 27506 this._addClass( $( event.target ), null, "ui-state-active" ); 27507 allowed = this._start( event, index ); 27508 if ( allowed === false ) { 27509 return; 27510 } 27511 } 27512 break; 27513 } 27514 27515 step = this.options.step; 27516 if ( this._hasMultipleValues() ) { 27517 curVal = newVal = this.values( index ); 27518 } else { 27519 curVal = newVal = this.value(); 27520 } 27521 27522 switch ( event.keyCode ) { 27523 case $.ui.keyCode.HOME: 27524 newVal = this._valueMin(); 27525 break; 27526 case $.ui.keyCode.END: 27527 newVal = this._valueMax(); 27528 break; 27529 case $.ui.keyCode.PAGE_UP: 27530 newVal = this._trimAlignValue( 27531 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 27532 ); 27533 break; 27534 case $.ui.keyCode.PAGE_DOWN: 27535 newVal = this._trimAlignValue( 27536 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 27537 break; 27538 case $.ui.keyCode.UP: 27539 case $.ui.keyCode.RIGHT: 27540 if ( curVal === this._valueMax() ) { 27541 return; 27542 } 27543 newVal = this._trimAlignValue( curVal + step ); 27544 break; 27545 case $.ui.keyCode.DOWN: 27546 case $.ui.keyCode.LEFT: 27547 if ( curVal === this._valueMin() ) { 27548 return; 27549 } 27550 newVal = this._trimAlignValue( curVal - step ); 27551 break; 27552 } 27553 27554 this._slide( event, index, newVal ); 27555 }, 27556 keyup: function( event ) { 27557 var index = $( event.target ).data( "ui-slider-handle-index" ); 27558 27559 if ( this._keySliding ) { 27560 this._keySliding = false; 27561 this._stop( event, index ); 27562 this._change( event, index ); 27563 this._removeClass( $( event.target ), null, "ui-state-active" ); 27564 } 27565 } 27566 } 27567} ); 27568
vendor: 3,464 bytes, lines 27569-27739
27569} ); 27570 27571 27572 27573 27574 27575 27576 27577/*! 27578 * jQuery UI Sortable 1.13.0 27579 * http://jqueryui.com 27580 * 27581 * Copyright jQuery Foundation and other contributors 27582 * Released under the MIT license. 27583 * http://jquery.org/license 27584 */ 27585 27586//>>label: Sortable 27587//>>group: Interactions 27588//>>description: Enables items in a list to be sorted using the mouse. 27589//>>docs: http://api.jqueryui.com/sortable/ 27590//>>demos: http://jqueryui.com/sortable/ 27591//>>css.structure: ../../themes/base/sortable.css 27592 27593( function( factory ) { 27594 "use strict"; 27595 27596 if ( typeof define === "function" && define.amd ) { 27597 27598 // AMD. Register as an anonymous module. 27599 define( [ 27600 "jquery", 27601 "./mouse", 27602 "../data", 27603 "../ie", 27604 "../scroll-parent", 27605 "../version", 27606 "../widget" 27607 ], factory ); 27608 } else { 27609 27610 // Browser globals 27611 factory( jQuery ); 27612 } 27613} )( function( $ ) { 27614"use strict"; 27615 27616return $.widget( "ui.sortable", $.ui.mouse, { 27617 version: "1.13.0", 27618 widgetEventPrefix: "sort", 27619 ready: false, 27620 options: { 27621 appendTo: "parent", 27622 axis: false, 27623 connectWith: false, 27624 containment: false, 27625 cursor: "auto", 27626 cursorAt: false, 27627 dropOnEmpty: true, 27628 forcePlaceholderSize: false, 27629 forceHelperSize: false, 27630 grid: false, 27631 handle: false, 27632 helper: "original", 27633 items: "> *", 27634 opacity: false, 27635 placeholder: false, 27636 revert: false, 27637 scroll: true, 27638 scrollSensitivity: 20, 27639 scrollSpeed: 20, 27640 scope: "default", 27641 tolerance: "intersect", 27642 zIndex: 1000, 27643 27644 // Callbacks 27645 activate: null, 27646 beforeStop: null, 27647 change: null, 27648 deactivate: null, 27649 out: null, 27650 over: null, 27651 receive: null, 27652 remove: null, 27653 sort: null, 27654 start: null, 27655 stop: null, 27656 update: null 27657 }, 27658 27659 _isOverAxis: function( x, reference, size ) { 27660 return ( x >= reference ) && ( x < ( reference + size ) ); 27661 }, 27662 27663 _isFloating: function( item ) { 27664 return ( /left|right/ ).test( item.css( "float" ) ) || 27665 ( /inline|table-cell/ ).test( item.css( "display" ) ); 27666 }, 27667 27668 _create: function() { 27669 this.containerCache = {}; 27670 this._addClass( "ui-sortable" ); 27671 27672 //Get the items 27673 this.refresh(); 27674 27675 //Let's determine the parent's offset 27676 this.offset = this.element.offset(); 27677 27678 //Initialize mouse events for interaction 27679 this._mouseInit(); 27680 27681 this._setHandleClassName(); 27682 27683 //We're ready to go 27684 this.ready = true; 27685 27686 }, 27687 27688 _setOption: function( key, value ) { 27689 this._super( key, value ); 27690 27691 if ( key === "handle" ) { 27692 this._setHandleClassName(); 27693 } 27694 }, 27695 27696 _setHandleClassName: function() { 27697 var that = this; 27698 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 27699 $.each( this.items, function() { 27700 that._addClass( 27701 this.instance.options.handle ? 27702 this.item.find( this.instance.options.handle ) : 27703 this.item, 27704 "ui-sortable-handle" 27705 ); 27706 } ); 27707 }, 27708 27709 _destroy: function() { 27710 this._mouseDestroy(); 27711 27712 for ( var i = this.items.length - 1; i >= 0; i-- ) { 27713 this.items[ i ].item.removeData( this.widgetName + "-item" ); 27714 } 27715 27716 return this; 27717 }, 27718 27719 _mouseCapture: function( event, overrideHandle ) { 27720 var currentItem = null, 27721 validHandle = false, 27722 that = this; 27723 27724 if ( this.reverting ) { 27725 return false; 27726 } 27727 27728 if ( this.options.disabled || this.options.type === "static" ) { 27729 return false; 27730 } 27731 27732 //We have to refresh the items data once first 27733 this._refreshItems( event ); 27734 27735 //Find out if the clicked node (or one of its parents) is a actual item in this.items 27736 $( event.target ).parents().each( function() { 27737 if ( $.data( this, that.widgetName + "-item" ) === that ) { 27738 currentItem = $( this ); 27739 return false;
vendor: 5,334 bytes, lines 27740-27936
27740 } 27741 } ); 27742 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 27743 currentItem = $( event.target ); 27744 } 27745 27746 if ( !currentItem ) { 27747 return false; 27748 } 27749 if ( this.options.handle && !overrideHandle ) { 27750 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 27751 if ( this === event.target ) { 27752 validHandle = true; 27753 } 27754 } ); 27755 if ( !validHandle ) { 27756 return false; 27757 } 27758 } 27759 27760 this.currentItem = currentItem; 27761 this._removeCurrentsFromItems(); 27762 return true; 27763 27764 }, 27765 27766 _mouseStart: function( event, overrideHandle, noActivation ) { 27767 27768 var i, body, 27769 o = this.options; 27770 27771 this.currentContainer = this; 27772 27773 //We only need to call refreshPositions, because the refreshItems call has been moved to 27774 // mouseCapture 27775 this.refreshPositions(); 27776 27777 //Prepare the dragged items parent 27778 this.appendTo = $( o.appendTo !== "parent" ? 27779 o.appendTo : 27780 this.currentItem.parent() ); 27781 27782 //Create and append the visible helper 27783 this.helper = this._createHelper( event ); 27784 27785 //Cache the helper size 27786 this._cacheHelperProportions(); 27787 27788 /* 27789 * - Position generation - 27790 * This block generates everything position related - it's the core of draggables. 27791 */ 27792 27793 //Cache the margins of the original element 27794 this._cacheMargins(); 27795 27796 //The element's absolute position on the page minus margins 27797 this.offset = this.currentItem.offset(); 27798 this.offset = { 27799 top: this.offset.top - this.margins.top, 27800 left: this.offset.left - this.margins.left 27801 }; 27802 27803 $.extend( this.offset, { 27804 click: { //Where the click happened, relative to the element 27805 left: event.pageX - this.offset.left, 27806 top: event.pageY - this.offset.top 27807 }, 27808 27809 // This is a relative to absolute position minus the actual position calculation - 27810 // only used for relative positioned helper 27811 relative: this._getRelativeOffset() 27812 } ); 27813 27814 // After we get the helper offset, but before we get the parent offset we can 27815 // change the helper's position to absolute 27816 // TODO: Still need to figure out a way to make relative sorting possible 27817 this.helper.css( "position", "absolute" ); 27818 this.cssPosition = this.helper.css( "position" ); 27819 27820 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 27821 if ( o.cursorAt ) { 27822 this._adjustOffsetFromHelper( o.cursorAt ); 27823 } 27824 27825 //Cache the former DOM position 27826 this.domPosition = { 27827 prev: this.currentItem.prev()[ 0 ], 27828 parent: this.currentItem.parent()[ 0 ] 27829 }; 27830 27831 // If the helper is not the original, hide the original so it's not playing any role during 27832 // the drag, won't cause anything bad this way 27833 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 27834 this.currentItem.hide(); 27835 } 27836 27837 //Create the placeholder 27838 this._createPlaceholder(); 27839 27840 //Get the next scrolling parent 27841 this.scrollParent = this.placeholder.scrollParent(); 27842 27843 $.extend( this.offset, { 27844 parent: this._getParentOffset() 27845 } ); 27846 27847 //Set a containment if given in the options 27848 if ( o.containment ) { 27849 this._setContainment(); 27850 } 27851 27852 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 27853 body = this.document.find( "body" ); 27854 27855 // Support: IE 27856 this.storedCursor = body.css( "cursor" ); 27857 body.css( "cursor", o.cursor ); 27858 27859 this.storedStylesheet = 27860 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 27861 } 27862 27863 // We need to make sure to grab the zIndex before setting the 27864 // opacity, because setting the opacity to anything lower than 1 27865 // causes the zIndex to change from "auto" to 0. 27866 if ( o.zIndex ) { // zIndex option 27867 if ( this.helper.css( "zIndex" ) ) { 27868 this._storedZIndex = this.helper.css( "zIndex" ); 27869 } 27870 this.helper.css( "zIndex", o.zIndex ); 27871 } 27872 27873 if ( o.opacity ) { // opacity option 27874 if ( this.helper.css( "opacity" ) ) { 27875 this._storedOpacity = this.helper.css( "opacity" ); 27876 } 27877 this.helper.css( "opacity", o.opacity ); 27878 } 27879 27880 //Prepare scrolling 27881 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27882 this.scrollParent[ 0 ].tagName !== "HTML" ) { 27883 this.overflowOffset = this.scrollParent.offset(); 27884 } 27885 27886 //Call callbacks 27887 this._trigger( "start", event, this._uiHash() ); 27888 27889 //Recache the helper size 27890 if ( !this._preserveHelperProportions ) { 27891 this._cacheHelperProportions(); 27892 } 27893 27894 //Post "activate" events to possible containers 27895 if ( !noActivation ) { 27896 for ( i = this.containers.length - 1; i >= 0; i-- ) { 27897 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 27898 } 27899 } 27900 27901 //Prepare possible droppables 27902 if ( $.ui.ddmanager ) { 27903 $.ui.ddmanager.current = this; 27904 } 27905 27906 if ( $.ui.ddmanager && !o.dropBehaviour ) { 27907 $.ui.ddmanager.prepareOffsets( this, event ); 27908 } 27909 27910 this.dragging = true; 27911 27912 this._addClass( this.helper, "ui-sortable-helper" ); 27913 27914 //Move the helper, if needed 27915 if ( !this.helper.parent().is( this.appendTo ) ) { 27916 this.helper.detach().appendTo( this.appendTo ); 27917 27918 //Update position 27919 this.offset.parent = this._getParentOffset(); 27920 } 27921 27922 //Generate the original position 27923 this.position = this.originalPosition = this._generatePosition( event ); 27924 this.originalPageX = event.pageX; 27925 this.originalPageY = event.pageY; 27926 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); 27927 27928 this._mouseDrag( event ); 27929 27930 return true; 27931 27932 }, 27933 27934 _scroll: function( event ) { 27935 var o = this.options, 27936 scrolled = false;
vendor: 4,360 bytes, lines 27937-28071
27937 27938 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27939 this.scrollParent[ 0 ].tagName !== "HTML" ) { 27940 27941 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 27942 event.pageY < o.scrollSensitivity ) { 27943 this.scrollParent[ 0 ].scrollTop = 27944 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 27945 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 27946 this.scrollParent[ 0 ].scrollTop = 27947 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 27948 } 27949 27950 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 27951 event.pageX < o.scrollSensitivity ) { 27952 this.scrollParent[ 0 ].scrollLeft = scrolled = 27953 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 27954 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 27955 this.scrollParent[ 0 ].scrollLeft = scrolled = 27956 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 27957 } 27958 27959 } else { 27960 27961 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 27962 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 27963 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 27964 o.scrollSensitivity ) { 27965 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 27966 } 27967 27968 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 27969 scrolled = this.document.scrollLeft( 27970 this.document.scrollLeft() - o.scrollSpeed 27971 ); 27972 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 27973 o.scrollSensitivity ) { 27974 scrolled = this.document.scrollLeft( 27975 this.document.scrollLeft() + o.scrollSpeed 27976 ); 27977 } 27978 27979 } 27980 27981 return scrolled; 27982 }, 27983 27984 _mouseDrag: function( event ) { 27985 var i, item, itemElement, intersection, 27986 o = this.options; 27987 27988 //Compute the helpers position 27989 this.position = this._generatePosition( event ); 27990 this.positionAbs = this._convertPositionTo( "absolute" ); 27991 27992 //Set the helper position 27993 if ( !this.options.axis || this.options.axis !== "y" ) { 27994 this.helper[ 0 ].style.left = this.position.left + "px"; 27995 } 27996 if ( !this.options.axis || this.options.axis !== "x" ) { 27997 this.helper[ 0 ].style.top = this.position.top + "px"; 27998 } 27999 28000 //Post events to containers 28001 this._contactContainers( event ); 28002 28003 if ( this.innermostContainer !== null ) { 28004 28005 //Do scrolling 28006 if ( o.scroll ) { 28007 if ( this._scroll( event ) !== false ) { 28008 28009 //Update item positions used in position checks 28010 this._refreshItemPositions( true ); 28011 28012 if ( $.ui.ddmanager && !o.dropBehaviour ) { 28013 $.ui.ddmanager.prepareOffsets( this, event ); 28014 } 28015 } 28016 } 28017 28018 this.dragDirection = { 28019 vertical: this._getDragVerticalDirection(), 28020 horizontal: this._getDragHorizontalDirection() 28021 }; 28022 28023 //Rearrange 28024 for ( i = this.items.length - 1; i >= 0; i-- ) { 28025 28026 //Cache variables and intersection, continue if no intersection 28027 item = this.items[ i ]; 28028 itemElement = item.item[ 0 ]; 28029 intersection = this._intersectsWithPointer( item ); 28030 if ( !intersection ) { 28031 continue; 28032 } 28033 28034 // Only put the placeholder inside the current Container, skip all 28035 // items from other containers. This works because when moving 28036 // an item from one container to another the 28037 // currentContainer is switched before the placeholder is moved. 28038 // 28039 // Without this, moving items in "sub-sortables" can cause 28040 // the placeholder to jitter between the outer and inner container. 28041 if ( item.instance !== this.currentContainer ) { 28042 continue; 28043 } 28044 28045 // Cannot intersect with itself 28046 // no useless actions that have been done before 28047 // no action if the item moved is the parent of the item checked 28048 if ( itemElement !== this.currentItem[ 0 ] && 28049 this.placeholder[ intersection === 1 ? 28050 "next" : "prev" ]()[ 0 ] !== itemElement && 28051 !$.contains( this.placeholder[ 0 ], itemElement ) && 28052 ( this.options.type === "semi-dynamic" ? 28053 !$.contains( this.element[ 0 ], itemElement ) : 28054 true 28055 ) 28056 ) { 28057 28058 this.direction = intersection === 1 ? "down" : "up"; 28059 28060 if ( this.options.tolerance === "pointer" || 28061 this._intersectsWithSides( item ) ) { 28062 this._rearrange( event, item ); 28063 } else { 28064 break; 28065 } 28066 28067 this._trigger( "change", event, this._uiHash() ); 28068 break; 28069 } 28070 } 28071 }
vendor: 5,297 bytes, lines 28071-28272
28071 28072 28073 //Interconnect with droppables 28074 if ( $.ui.ddmanager ) { 28075 $.ui.ddmanager.drag( this, event ); 28076 } 28077 28078 //Call callbacks 28079 this._trigger( "sort", event, this._uiHash() ); 28080 28081 this.lastPositionAbs = this.positionAbs; 28082 return false; 28083 28084 }, 28085 28086 _mouseStop: function( event, noPropagation ) { 28087 28088 if ( !event ) { 28089 return; 28090 } 28091 28092 //If we are using droppables, inform the manager about the drop 28093 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 28094 $.ui.ddmanager.drop( this, event ); 28095 } 28096 28097 if ( this.options.revert ) { 28098 var that = this, 28099 cur = this.placeholder.offset(), 28100 axis = this.options.axis, 28101 animation = {}; 28102 28103 if ( !axis || axis === "x" ) { 28104 animation.left = cur.left - this.offset.parent.left - this.margins.left + 28105 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 28106 0 : 28107 this.offsetParent[ 0 ].scrollLeft 28108 ); 28109 } 28110 if ( !axis || axis === "y" ) { 28111 animation.top = cur.top - this.offset.parent.top - this.margins.top + 28112 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 28113 0 : 28114 this.offsetParent[ 0 ].scrollTop 28115 ); 28116 } 28117 this.reverting = true; 28118 $( this.helper ).animate( 28119 animation, 28120 parseInt( this.options.revert, 10 ) || 500, 28121 function() { 28122 that._clear( event ); 28123 } 28124 ); 28125 } else { 28126 this._clear( event, noPropagation ); 28127 } 28128 28129 return false; 28130 28131 }, 28132 28133 cancel: function() { 28134 28135 if ( this.dragging ) { 28136 28137 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 28138 28139 if ( this.options.helper === "original" ) { 28140 this.currentItem.css( this._storedCSS ); 28141 this._removeClass( this.currentItem, "ui-sortable-helper" ); 28142 } else { 28143 this.currentItem.show(); 28144 } 28145 28146 //Post deactivating events to containers 28147 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 28148 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 28149 if ( this.containers[ i ].containerCache.over ) { 28150 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 28151 this.containers[ i ].containerCache.over = 0; 28152 } 28153 } 28154 28155 } 28156 28157 if ( this.placeholder ) { 28158 28159 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 28160 // it unbinds ALL events from the original node! 28161 if ( this.placeholder[ 0 ].parentNode ) { 28162 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 28163 } 28164 if ( this.options.helper !== "original" && this.helper && 28165 this.helper[ 0 ].parentNode ) { 28166 this.helper.remove(); 28167 } 28168 28169 $.extend( this, { 28170 helper: null, 28171 dragging: false, 28172 reverting: false, 28173 _noFinalSort: null 28174 } ); 28175 28176 if ( this.domPosition.prev ) { 28177 $( this.domPosition.prev ).after( this.currentItem ); 28178 } else { 28179 $( this.domPosition.parent ).prepend( this.currentItem ); 28180 } 28181 } 28182 28183 return this; 28184 28185 }, 28186 28187 serialize: function( o ) { 28188 28189 var items = this._getItemsAsjQuery( o && o.connected ), 28190 str = []; 28191 o = o || {}; 28192 28193 $( items ).each( function() { 28194 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 28195 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 28196 if ( res ) { 28197 str.push( 28198 ( o.key || res[ 1 ] + "[]" ) + 28199 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 28200 } 28201 } ); 28202 28203 if ( !str.length && o.key ) { 28204 str.push( o.key + "=" ); 28205 } 28206 28207 return str.join( "&" ); 28208 28209 }, 28210 28211 toArray: function( o ) { 28212 28213 var items = this._getItemsAsjQuery( o && o.connected ), 28214 ret = []; 28215 28216 o = o || {}; 28217 28218 items.each( function() { 28219 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 28220 } ); 28221 return ret; 28222 28223 }, 28224 28225 /* Be careful with the following core functions */ 28226 _intersectsWith: function( item ) { 28227 28228 var x1 = this.positionAbs.left, 28229 x2 = x1 + this.helperProportions.width, 28230 y1 = this.positionAbs.top, 28231 y2 = y1 + this.helperProportions.height, 28232 l = item.left, 28233 r = l + item.width, 28234 t = item.top, 28235 b = t + item.height, 28236 dyClick = this.offset.click.top, 28237 dxClick = this.offset.click.left, 28238 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 28239 ( y1 + dyClick ) < b ), 28240 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 28241 ( x1 + dxClick ) < r ), 28242 isOverElement = isOverElementHeight && isOverElementWidth; 28243 28244 if ( this.options.tolerance === "pointer" || 28245 this.options.forcePointerForContainers || 28246 ( this.options.tolerance !== "pointer" && 28247 this.helperProportions[ this.floating ? "width" : "height" ] > 28248 item[ this.floating ? "width" : "height" ] ) 28249 ) { 28250 return isOverElement; 28251 } else { 28252 28253 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 28254 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 28255 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 28256 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 28257 28258 } 28259 }, 28260 28261 _intersectsWithPointer: function( item ) { 28262 var verticalDirection, horizontalDirection, 28263 isOverElementHeight = ( this.options.axis === "x" ) || 28264 this._isOverAxis( 28265 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 28266 isOverElementWidth = ( this.options.axis === "y" ) || 28267 this._isOverAxis( 28268 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 28269 isOverElement = isOverElementHeight && isOverElementWidth; 28270 28271 if ( !isOverElement ) { 28272 return false;
vendor: 5,624 bytes, lines 28273-28467
28273 } 28274 28275 verticalDirection = this.dragDirection.vertical; 28276 horizontalDirection = this.dragDirection.horizontal; 28277 28278 return this.floating ? 28279 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : 28280 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 28281 28282 }, 28283 28284 _intersectsWithSides: function( item ) { 28285 28286 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 28287 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 28288 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 28289 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 28290 verticalDirection = this.dragDirection.vertical, 28291 horizontalDirection = this.dragDirection.horizontal; 28292 28293 if ( this.floating && horizontalDirection ) { 28294 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 28295 ( horizontalDirection === "left" && !isOverRightHalf ) ); 28296 } else { 28297 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 28298 ( verticalDirection === "up" && !isOverBottomHalf ) ); 28299 } 28300 28301 }, 28302 28303 _getDragVerticalDirection: function() { 28304 var delta = this.positionAbs.top - this.lastPositionAbs.top; 28305 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 28306 }, 28307 28308 _getDragHorizontalDirection: function() { 28309 var delta = this.positionAbs.left - this.lastPositionAbs.left; 28310 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 28311 }, 28312 28313 refresh: function( event ) { 28314 this._refreshItems( event ); 28315 this._setHandleClassName(); 28316 this.refreshPositions(); 28317 return this; 28318 }, 28319 28320 _connectWith: function() { 28321 var options = this.options; 28322 return options.connectWith.constructor === String ? 28323 [ options.connectWith ] : 28324 options.connectWith; 28325 }, 28326 28327 _getItemsAsjQuery: function( connected ) { 28328 28329 var i, j, cur, inst, 28330 items = [], 28331 queries = [], 28332 connectWith = this._connectWith(); 28333 28334 if ( connectWith && connected ) { 28335 for ( i = connectWith.length - 1; i >= 0; i-- ) { 28336 cur = $( connectWith[ i ], this.document[ 0 ] ); 28337 for ( j = cur.length - 1; j >= 0; j-- ) { 28338 inst = $.data( cur[ j ], this.widgetFullName ); 28339 if ( inst && inst !== this && !inst.options.disabled ) { 28340 queries.push( [ typeof inst.options.items === "function" ? 28341 inst.options.items.call( inst.element ) : 28342 $( inst.options.items, inst.element ) 28343 .not( ".ui-sortable-helper" ) 28344 .not( ".ui-sortable-placeholder" ), inst ] ); 28345 } 28346 } 28347 } 28348 } 28349 28350 queries.push( [ typeof this.options.items === "function" ? 28351 this.options.items 28352 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 28353 $( this.options.items, this.element ) 28354 .not( ".ui-sortable-helper" ) 28355 .not( ".ui-sortable-placeholder" ), this ] ); 28356 28357 function addItems() { 28358 items.push( this ); 28359 } 28360 for ( i = queries.length - 1; i >= 0; i-- ) { 28361 queries[ i ][ 0 ].each( addItems ); 28362 } 28363 28364 return $( items ); 28365 28366 }, 28367 28368 _removeCurrentsFromItems: function() { 28369 28370 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 28371 28372 this.items = $.grep( this.items, function( item ) { 28373 for ( var j = 0; j < list.length; j++ ) { 28374 if ( list[ j ] === item.item[ 0 ] ) { 28375 return false; 28376 } 28377 } 28378 return true; 28379 } ); 28380 28381 }, 28382 28383 _refreshItems: function( event ) { 28384 28385 this.items = []; 28386 this.containers = [ this ]; 28387 28388 var i, j, cur, inst, targetData, _queries, item, queriesLength, 28389 items = this.items, 28390 queries = [ [ typeof this.options.items === "function" ? 28391 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 28392 $( this.options.items, this.element ), this ] ], 28393 connectWith = this._connectWith(); 28394 28395 //Shouldn't be run the first time through due to massive slow-down 28396 if ( connectWith && this.ready ) { 28397 for ( i = connectWith.length - 1; i >= 0; i-- ) { 28398 cur = $( connectWith[ i ], this.document[ 0 ] ); 28399 for ( j = cur.length - 1; j >= 0; j-- ) { 28400 inst = $.data( cur[ j ], this.widgetFullName ); 28401 if ( inst && inst !== this && !inst.options.disabled ) { 28402 queries.push( [ typeof inst.options.items === "function" ? 28403 inst.options.items 28404 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 28405 $( inst.options.items, inst.element ), inst ] ); 28406 this.containers.push( inst ); 28407 } 28408 } 28409 } 28410 } 28411 28412 for ( i = queries.length - 1; i >= 0; i-- ) { 28413 targetData = queries[ i ][ 1 ]; 28414 _queries = queries[ i ][ 0 ]; 28415 28416 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 28417 item = $( _queries[ j ] ); 28418 28419 // Data for target checking (mouse manager) 28420 item.data( this.widgetName + "-item", targetData ); 28421 28422 items.push( { 28423 item: item, 28424 instance: targetData, 28425 width: 0, height: 0, 28426 left: 0, top: 0 28427 } ); 28428 } 28429 } 28430 28431 }, 28432 28433 _refreshItemPositions: function( fast ) { 28434 var i, item, t, p; 28435 28436 for ( i = this.items.length - 1; i >= 0; i-- ) { 28437 item = this.items[ i ]; 28438 28439 //We ignore calculating positions of all connected containers when we're not over them 28440 if ( this.currentContainer && item.instance !== this.currentContainer && 28441 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 28442 continue; 28443 } 28444 28445 t = this.options.toleranceElement ? 28446 $( this.options.toleranceElement, item.item ) : 28447 item.item; 28448 28449 if ( !fast ) { 28450 item.width = t.outerWidth(); 28451 item.height = t.outerHeight(); 28452 } 28453 28454 p = t.offset(); 28455 item.left = p.left; 28456 item.top = p.top; 28457 } 28458 }, 28459 28460 refreshPositions: function( fast ) { 28461 28462 // Determine whether items are being displayed horizontally 28463 this.floating = this.items.length ? 28464 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 28465 false; 28466 28467
vendor: 4,943 bytes, lines 28467-28617
28467if ( this.innermostContainer !== null ) { 28468 this._refreshItemPositions( fast ); 28469 } 28470 28471 var i, p; 28472 28473 if ( this.options.custom && this.options.custom.refreshContainers ) { 28474 this.options.custom.refreshContainers.call( this ); 28475 } else { 28476 for ( i = this.containers.length - 1; i >= 0; i-- ) { 28477 p = this.containers[ i ].element.offset(); 28478 this.containers[ i ].containerCache.left = p.left; 28479 this.containers[ i ].containerCache.top = p.top; 28480 this.containers[ i ].containerCache.width = 28481 this.containers[ i ].element.outerWidth(); 28482 this.containers[ i ].containerCache.height = 28483 this.containers[ i ].element.outerHeight(); 28484 } 28485 } 28486 28487 return this; 28488 }, 28489 28490 _createPlaceholder: function( that ) { 28491 that = that || this; 28492 var className, nodeName, 28493 o = that.options; 28494 28495 if ( !o.placeholder || o.placeholder.constructor === String ) { 28496 className = o.placeholder; 28497 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); 28498 o.placeholder = { 28499 element: function() { 28500 28501 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); 28502 28503 that._addClass( element, "ui-sortable-placeholder", 28504 className || that.currentItem[ 0 ].className ) 28505 ._removeClass( element, "ui-sortable-helper" ); 28506 28507 if ( nodeName === "tbody" ) { 28508 that._createTrPlaceholder( 28509 that.currentItem.find( "tr" ).eq( 0 ), 28510 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 28511 ); 28512 } else if ( nodeName === "tr" ) { 28513 that._createTrPlaceholder( that.currentItem, element ); 28514 } else if ( nodeName === "img" ) { 28515 element.attr( "src", that.currentItem.attr( "src" ) ); 28516 } 28517 28518 if ( !className ) { 28519 element.css( "visibility", "hidden" ); 28520 } 28521 28522 return element; 28523 }, 28524 update: function( container, p ) { 28525 28526 // 1. If a className is set as 'placeholder option, we don't force sizes - 28527 // the class is responsible for that 28528 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 28529 // class name is specified 28530 if ( className && !o.forcePlaceholderSize ) { 28531 return; 28532 } 28533 28534 // If the element doesn't have a actual height or width by itself (without 28535 // styles coming from a stylesheet), it receives the inline height and width 28536 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height 28537 // anyway since we're populating them with <td>s above, but they're unlikely to 28538 // be the correct height on their own if the row heights are dynamic, so we'll 28539 // always assign the height of the dragged item given forcePlaceholderSize 28540 // is true. 28541 if ( !p.height() || ( o.forcePlaceholderSize && 28542 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { 28543 p.height( 28544 that.currentItem.innerHeight() - 28545 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 28546 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 28547 } 28548 if ( !p.width() ) { 28549 p.width( 28550 that.currentItem.innerWidth() - 28551 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 28552 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 28553 } 28554 } 28555 }; 28556 } 28557 28558 //Create the placeholder 28559 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 28560 28561 //Append it after the actual current item 28562 that.currentItem.after( that.placeholder ); 28563 28564 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 28565 o.placeholder.update( that, that.placeholder ); 28566 28567 }, 28568 28569 _createTrPlaceholder: function( sourceTr, targetTr ) { 28570 var that = this; 28571 28572 sourceTr.children().each( function() { 28573 $( "<td> </td>", that.document[ 0 ] ) 28574 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 28575 .appendTo( targetTr ); 28576 } ); 28577 }, 28578 28579 _contactContainers: function( event ) { 28580 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 28581 floating, axis, 28582 innermostContainer = null, 28583 innermostIndex = null; 28584 28585 // Get innermost container that intersects with item 28586 for ( i = this.containers.length - 1; i >= 0; i-- ) { 28587 28588 // Never consider a container that's located within the item itself 28589 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 28590 continue; 28591 } 28592 28593 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 28594 28595 // If we've already found a container and it's more "inner" than this, then continue 28596 if ( innermostContainer && 28597 $.contains( 28598 this.containers[ i ].element[ 0 ], 28599 innermostContainer.element[ 0 ] ) ) { 28600 continue; 28601 } 28602 28603 innermostContainer = this.containers[ i ]; 28604 innermostIndex = i; 28605 28606 } else { 28607 28608 // container doesn't intersect. trigger "out" event if necessary 28609 if ( this.containers[ i ].containerCache.over ) { 28610 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 28611 this.containers[ i ].containerCache.over = 0; 28612 } 28613 } 28614 28615 } 28616 28617 this.innermostContainer = innermostContainer;
vendor: 9,708 bytes, lines 28617-28905
28617 28618 28619 // If no intersecting containers found, return 28620 if ( !innermostContainer ) { 28621 return; 28622 } 28623 28624 // Move the item into the container if it's not there already 28625 if ( this.containers.length === 1 ) { 28626 if ( !this.containers[ innermostIndex ].containerCache.over ) { 28627 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 28628 this.containers[ innermostIndex ].containerCache.over = 1; 28629 } 28630 } else { 28631 28632 // When entering a new container, we will find the item with the least distance and 28633 // append our item near it 28634 dist = 10000; 28635 itemWithLeastDistance = null; 28636 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 28637 posProperty = floating ? "left" : "top"; 28638 sizeProperty = floating ? "width" : "height"; 28639 axis = floating ? "pageX" : "pageY"; 28640 28641 for ( j = this.items.length - 1; j >= 0; j-- ) { 28642 if ( !$.contains( 28643 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 28644 ) { 28645 continue; 28646 } 28647 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 28648 continue; 28649 } 28650 28651 cur = this.items[ j ].item.offset()[ posProperty ]; 28652 nearBottom = false; 28653 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 28654 nearBottom = true; 28655 } 28656 28657 if ( Math.abs( event[ axis ] - cur ) < dist ) { 28658 dist = Math.abs( event[ axis ] - cur ); 28659 itemWithLeastDistance = this.items[ j ]; 28660 this.direction = nearBottom ? "up" : "down"; 28661 } 28662 } 28663 28664 //Check if dropOnEmpty is enabled 28665 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 28666 return; 28667 } 28668 28669 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 28670 if ( !this.currentContainer.containerCache.over ) { 28671 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 28672 this.currentContainer.containerCache.over = 1; 28673 } 28674 return; 28675 } 28676 28677 if ( itemWithLeastDistance ) { 28678 this._rearrange( event, itemWithLeastDistance, null, true ); 28679 } else { 28680 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 28681 } 28682 this._trigger( "change", event, this._uiHash() ); 28683 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 28684 this.currentContainer = this.containers[ innermostIndex ]; 28685 28686 //Update the placeholder 28687 this.options.placeholder.update( this.currentContainer, this.placeholder ); 28688 28689 //Update scrollParent 28690 this.scrollParent = this.placeholder.scrollParent(); 28691 28692 //Update overflowOffset 28693 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 28694 this.scrollParent[ 0 ].tagName !== "HTML" ) { 28695 this.overflowOffset = this.scrollParent.offset(); 28696 } 28697 28698 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 28699 this.containers[ innermostIndex ].containerCache.over = 1; 28700 } 28701 28702 }, 28703 28704 _createHelper: function( event ) { 28705 28706 var o = this.options, 28707 helper = typeof o.helper === "function" ? 28708 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 28709 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 28710 28711 //Add the helper to the DOM if that didn't happen already 28712 if ( !helper.parents( "body" ).length ) { 28713 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); 28714 } 28715 28716 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 28717 this._storedCSS = { 28718 width: this.currentItem[ 0 ].style.width, 28719 height: this.currentItem[ 0 ].style.height, 28720 position: this.currentItem.css( "position" ), 28721 top: this.currentItem.css( "top" ), 28722 left: this.currentItem.css( "left" ) 28723 }; 28724 } 28725 28726 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 28727 helper.width( this.currentItem.width() ); 28728 } 28729 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 28730 helper.height( this.currentItem.height() ); 28731 } 28732 28733 return helper; 28734 28735 }, 28736 28737 _adjustOffsetFromHelper: function( obj ) { 28738 if ( typeof obj === "string" ) { 28739 obj = obj.split( " " ); 28740 } 28741 if ( Array.isArray( obj ) ) { 28742 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 28743 } 28744 if ( "left" in obj ) { 28745 this.offset.click.left = obj.left + this.margins.left; 28746 } 28747 if ( "right" in obj ) { 28748 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 28749 } 28750 if ( "top" in obj ) { 28751 this.offset.click.top = obj.top + this.margins.top; 28752 } 28753 if ( "bottom" in obj ) { 28754 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 28755 } 28756 }, 28757 28758 _getParentOffset: function() { 28759 28760 //Get the offsetParent and cache its position 28761 this.offsetParent = this.helper.offsetParent(); 28762 var po = this.offsetParent.offset(); 28763 28764 // This is a special case where we need to modify a offset calculated on start, since the 28765 // following happened: 28766 // 1. The position of the helper is absolute, so it's position is calculated based on the 28767 // next positioned parent 28768 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 28769 // the document, which means that the scroll is included in the initial calculation of the 28770 // offset of the parent, and never recalculated upon drag 28771 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 28772 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 28773 po.left += this.scrollParent.scrollLeft(); 28774 po.top += this.scrollParent.scrollTop(); 28775 } 28776 28777 // This needs to be actually done for all browsers, since pageX/pageY includes this 28778 // information with an ugly IE fix 28779 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || 28780 ( this.offsetParent[ 0 ].tagName && 28781 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { 28782 po = { top: 0, left: 0 }; 28783 } 28784 28785 return { 28786 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 28787 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 28788 }; 28789 28790 }, 28791 28792 _getRelativeOffset: function() { 28793 28794 if ( this.cssPosition === "relative" ) { 28795 var p = this.currentItem.position(); 28796 return { 28797 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 28798 this.scrollParent.scrollTop(), 28799 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 28800 this.scrollParent.scrollLeft() 28801 }; 28802 } else { 28803 return { top: 0, left: 0 }; 28804 } 28805 28806 }, 28807 28808 _cacheMargins: function() { 28809 this.margins = { 28810 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 28811 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 28812 }; 28813 }, 28814 28815 _cacheHelperProportions: function() { 28816 this.helperProportions = { 28817 width: this.helper.outerWidth(), 28818 height: this.helper.outerHeight() 28819 }; 28820 }, 28821 28822 _setContainment: function() { 28823 28824 var ce, co, over, 28825 o = this.options; 28826 if ( o.containment === "parent" ) { 28827 o.containment = this.helper[ 0 ].parentNode; 28828 } 28829 if ( o.containment === "document" || o.containment === "window" ) { 28830 this.containment = [ 28831 0 - this.offset.relative.left - this.offset.parent.left, 28832 0 - this.offset.relative.top - this.offset.parent.top, 28833 o.containment === "document" ? 28834 this.document.width() : 28835 this.window.width() - this.helperProportions.width - this.margins.left, 28836 ( o.containment === "document" ? 28837 ( this.document.height() || document.body.parentNode.scrollHeight ) : 28838 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 28839 ) - this.helperProportions.height - this.margins.top 28840 ]; 28841 } 28842 28843 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 28844 ce = $( o.containment )[ 0 ]; 28845 co = $( o.containment ).offset(); 28846 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 28847 28848 this.containment = [ 28849 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 28850 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 28851 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 28852 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 28853 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 28854 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 28855 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 28856 this.helperProportions.width - this.margins.left, 28857 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 28858 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 28859 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 28860 this.helperProportions.height - this.margins.top 28861 ]; 28862 } 28863 28864 }, 28865 28866 _convertPositionTo: function( d, pos ) { 28867 28868 if ( !pos ) { 28869 pos = this.position; 28870 } 28871 var mod = d === "absolute" ? 1 : -1, 28872 scroll = this.cssPosition === "absolute" && 28873 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 28874 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 28875 this.offsetParent : 28876 this.scrollParent, 28877 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 28878 28879 return { 28880 top: ( 28881 28882 // The absolute mouse position 28883 pos.top + 28884 28885 // Only for relative positioned nodes: Relative offset from element to offset parent 28886 this.offset.relative.top * mod + 28887 28888 // The offsetParent's offset without borders (offset + border) 28889 this.offset.parent.top * mod - 28890 ( ( this.cssPosition === "fixed" ? 28891 -this.scrollParent.scrollTop() : 28892 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 28893 ), 28894 left: ( 28895 28896 // The absolute mouse position 28897 pos.left + 28898 28899 // Only for relative positioned nodes: Relative offset from element to offset parent 28900 this.offset.relative.left * mod + 28901 28902 // The offsetParent's offset without borders (offset + border) 28903 this.offset.parent.left * mod - 28904 ( ( this.cssPosition === "fixed" ? 28905 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 4,632 bytes, lines 28906-29049
28906 scroll.scrollLeft() ) * mod ) 28907 ) 28908 }; 28909 28910 }, 28911 28912 _generatePosition: function( event ) { 28913 28914 var top, left, 28915 o = this.options, 28916 pageX = event.pageX, 28917 pageY = event.pageY, 28918 scroll = this.cssPosition === "absolute" && 28919 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 28920 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 28921 this.offsetParent : 28922 this.scrollParent, 28923 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 28924 28925 // This is another very weird special case that only happens for relative elements: 28926 // 1. If the css position is relative 28927 // 2. and the scroll parent is the document or similar to the offset parent 28928 // we have to refresh the relative offset during the scroll so there are no jumps 28929 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 28930 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 28931 this.offset.relative = this._getRelativeOffset(); 28932 } 28933 28934 /* 28935 * - Position constraining - 28936 * Constrain the position to a mix of grid, containment. 28937 */ 28938 28939 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 28940 28941 if ( this.containment ) { 28942 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 28943 pageX = this.containment[ 0 ] + this.offset.click.left; 28944 } 28945 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 28946 pageY = this.containment[ 1 ] + this.offset.click.top; 28947 } 28948 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 28949 pageX = this.containment[ 2 ] + this.offset.click.left; 28950 } 28951 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 28952 pageY = this.containment[ 3 ] + this.offset.click.top; 28953 } 28954 } 28955 28956 if ( o.grid ) { 28957 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 28958 o.grid[ 1 ] ) * o.grid[ 1 ]; 28959 pageY = this.containment ? 28960 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 28961 top - this.offset.click.top <= this.containment[ 3 ] ) ? 28962 top : 28963 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 28964 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 28965 top; 28966 28967 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 28968 o.grid[ 0 ] ) * o.grid[ 0 ]; 28969 pageX = this.containment ? 28970 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 28971 left - this.offset.click.left <= this.containment[ 2 ] ) ? 28972 left : 28973 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 28974 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 28975 left; 28976 } 28977 28978 } 28979 28980 return { 28981 top: ( 28982 28983 // The absolute mouse position 28984 pageY - 28985 28986 // Click offset (relative to the element) 28987 this.offset.click.top - 28988 28989 // Only for relative positioned nodes: Relative offset from element to offset parent 28990 this.offset.relative.top - 28991 28992 // The offsetParent's offset without borders (offset + border) 28993 this.offset.parent.top + 28994 ( ( this.cssPosition === "fixed" ? 28995 -this.scrollParent.scrollTop() : 28996 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 28997 ), 28998 left: ( 28999 29000 // The absolute mouse position 29001 pageX - 29002 29003 // Click offset (relative to the element) 29004 this.offset.click.left - 29005 29006 // Only for relative positioned nodes: Relative offset from element to offset parent 29007 this.offset.relative.left - 29008 29009 // The offsetParent's offset without borders (offset + border) 29010 this.offset.parent.left + 29011 ( ( this.cssPosition === "fixed" ? 29012 -this.scrollParent.scrollLeft() : 29013 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 29014 ) 29015 }; 29016 29017 }, 29018 29019 _rearrange: function( event, i, a, hardRefresh ) { 29020 29021 if ( a ) { 29022 a[ 0 ].appendChild( this.placeholder[ 0 ] ); 29023 } else { 29024 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 29025 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 29026 } 29027 29028 //Various things done here to improve the performance: 29029 // 1. we create a setTimeout, that calls refreshPositions 29030 // 2. on the instance, we have a counter variable, that get's higher after every append 29031 // 3. on the local scope, we copy the counter variable, and check in the timeout, 29032 // if it's still the same 29033 // 4. this lets only the last addition to the timeout stack through 29034 this.counter = this.counter ? ++this.counter : 1; 29035 var counter = this.counter; 29036 29037 this._delay( function() { 29038 if ( counter === this.counter ) { 29039 29040 //Precompute after each DOM insertion, NOT on mousemove 29041 this.refreshPositions( !hardRefresh ); 29042 } 29043 } ); 29044 29045 }, 29046 29047 _clear: function( event, noPropagation ) { 29048 29049 this.reverting = false;
vendor: 4,252 bytes, lines 29050-29191
29050 29051 // We delay all events that have to be triggered to after the point where the placeholder 29052 // has been removed and everything else normalized again 29053 var i, 29054 delayedTriggers = []; 29055 29056 // We first have to update the dom position of the actual currentItem 29057 // Note: don't do it if the current item is already removed (by a user), or it gets 29058 // reappended (see #4088) 29059 if ( !this._noFinalSort && this.currentItem.parent().length ) { 29060 this.placeholder.before( this.currentItem ); 29061 } 29062 this._noFinalSort = null; 29063 29064 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 29065 for ( i in this._storedCSS ) { 29066 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 29067 this._storedCSS[ i ] = ""; 29068 } 29069 } 29070 this.currentItem.css( this._storedCSS ); 29071 this._removeClass( this.currentItem, "ui-sortable-helper" ); 29072 } else { 29073 this.currentItem.show(); 29074 } 29075 29076 if ( this.fromOutside && !noPropagation ) { 29077 delayedTriggers.push( function( event ) { 29078 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 29079 } ); 29080 } 29081 if ( ( this.fromOutside || 29082 this.domPosition.prev !== 29083 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 29084 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 29085 29086 // Trigger update callback if the DOM position has changed 29087 delayedTriggers.push( function( event ) { 29088 this._trigger( "update", event, this._uiHash() ); 29089 } ); 29090 } 29091 29092 // Check if the items Container has Changed and trigger appropriate 29093 // events. 29094 if ( this !== this.currentContainer ) { 29095 if ( !noPropagation ) { 29096 delayedTriggers.push( function( event ) { 29097 this._trigger( "remove", event, this._uiHash() ); 29098 } ); 29099 delayedTriggers.push( ( function( c ) { 29100 return function( event ) { 29101 c._trigger( "receive", event, this._uiHash( this ) ); 29102 }; 29103 } ).call( this, this.currentContainer ) ); 29104 delayedTriggers.push( ( function( c ) { 29105 return function( event ) { 29106 c._trigger( "update", event, this._uiHash( this ) ); 29107 }; 29108 } ).call( this, this.currentContainer ) ); 29109 } 29110 } 29111 29112 //Post events to containers 29113 function delayEvent( type, instance, container ) { 29114 return function( event ) { 29115 container._trigger( type, event, instance._uiHash( instance ) ); 29116 }; 29117 } 29118 for ( i = this.containers.length - 1; i >= 0; i-- ) { 29119 if ( !noPropagation ) { 29120 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 29121 } 29122 if ( this.containers[ i ].containerCache.over ) { 29123 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 29124 this.containers[ i ].containerCache.over = 0; 29125 } 29126 } 29127 29128 //Do what was originally in plugins 29129 if ( this.storedCursor ) { 29130 this.document.find( "body" ).css( "cursor", this.storedCursor ); 29131 this.storedStylesheet.remove(); 29132 } 29133 if ( this._storedOpacity ) { 29134 this.helper.css( "opacity", this._storedOpacity ); 29135 } 29136 if ( this._storedZIndex ) { 29137 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 29138 } 29139 29140 this.dragging = false; 29141 29142 if ( !noPropagation ) { 29143 this._trigger( "beforeStop", event, this._uiHash() ); 29144 } 29145 29146 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 29147 // it unbinds ALL events from the original node! 29148 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 29149 29150 if ( !this.cancelHelperRemoval ) { 29151 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 29152 this.helper.remove(); 29153 } 29154 this.helper = null; 29155 } 29156 29157 if ( !noPropagation ) { 29158 for ( i = 0; i < delayedTriggers.length; i++ ) { 29159 29160 // Trigger all delayed events 29161 delayedTriggers[ i ].call( this, event ); 29162 } 29163 this._trigger( "stop", event, this._uiHash() ); 29164 } 29165 29166 this.fromOutside = false; 29167 return !this.cancelHelperRemoval; 29168 29169 }, 29170 29171 _trigger: function() { 29172 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 29173 this.cancel(); 29174 } 29175 }, 29176 29177 _uiHash: function( _inst ) { 29178 var inst = _inst || this; 29179 return { 29180 helper: inst.helper, 29181 placeholder: inst.placeholder || $( [] ), 29182 position: inst.position, 29183 originalPosition: inst.originalPosition, 29184 offset: inst.positionAbs, 29185 item: inst.currentItem, 29186 sender: _inst ? _inst.element : null 29187 }; 29188 } 29189 29190} ); 29191
29192} ); 29193 29194 29195 29196 29197 29198 29199/*! 29200 * jQuery UI Spinner 1.13.0 29201 * http://jqueryui.com 29202 * 29203 * Copyright jQuery Foundation and other contributors 29204 * Released under the MIT license. 29205 * http://jquery.org/license 29206 */ 29207 29208//>>label: Spinner 29209//>>group: Widgets 29210//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 29211//>>docs: http://api.jqueryui.com/spinner/ 29212//>>demos: http://jqueryui.com/spinner/ 29213//>>css.structure: ../../themes/base/core.css 29214//>>css.structure: ../../themes/base/spinner.css 29215//>>css.theme: ../../themes/base/theme.css 29216 29217( function( factory ) { 29218 "use strict"; 29219 29220 if ( typeof define === "function" && define.amd ) { 29221 29222 // AMD. Register as an anonymous module. 29223 define( [ 29224 "jquery", 29225 "./button", 29226 "../version", 29227 "../keycode", 29228 "../safe-active-element", 29229 "../widget" 29230 ], factory ); 29231 } else { 29232 29233 // Browser globals 29234 factory( jQuery ); 29235 } 29236} )( function( $ ) { 29237"use strict"; 29238 29239function spinnerModifier( fn ) { 29240 return function() { 29241 var previous = this.element.val(); 29242 fn.apply( this, arguments ); 29243 this._refresh(); 29244 if ( previous !== this.element.val() ) { 29245 this._trigger( "change" ); 29246 } 29247 }; 29248} 29249 29250$.widget( "ui.spinner", { 29251 version: "1.13.0
vendor: 13,246 bytes, lines 29251-29777
29251", 29252 defaultElement: "<input>", 29253 widgetEventPrefix: "spin", 29254 options: { 29255 classes: { 29256 "ui-spinner": "ui-corner-all", 29257 "ui-spinner-down": "ui-corner-br", 29258 "ui-spinner-up": "ui-corner-tr" 29259 }, 29260 culture: null, 29261 icons: { 29262 down: "ui-icon-triangle-1-s", 29263 up: "ui-icon-triangle-1-n" 29264 }, 29265 incremental: true, 29266 max: null, 29267 min: null, 29268 numberFormat: null, 29269 page: 10, 29270 step: 1, 29271 29272 change: null, 29273 spin: null, 29274 start: null, 29275 stop: null 29276 }, 29277 29278 _create: function() { 29279 29280 // handle string values that need to be parsed 29281 this._setOption( "max", this.options.max ); 29282 this._setOption( "min", this.options.min ); 29283 this._setOption( "step", this.options.step ); 29284 29285 // Only format if there is a value, prevents the field from being marked 29286 // as invalid in Firefox, see #9573. 29287 if ( this.value() !== "" ) { 29288 29289 // Format the value, but don't constrain. 29290 this._value( this.element.val(), true ); 29291 } 29292 29293 this._draw(); 29294 this._on( this._events ); 29295 this._refresh(); 29296 29297 // Turning off autocomplete prevents the browser from remembering the 29298 // value when navigating through history, so we re-enable autocomplete 29299 // if the page is unloaded before the widget is destroyed. #7790 29300 this._on( this.window, { 29301 beforeunload: function() { 29302 this.element.removeAttr( "autocomplete" ); 29303 } 29304 } ); 29305 }, 29306 29307 _getCreateOptions: function() { 29308 var options = this._super(); 29309 var element = this.element; 29310 29311 $.each( [ "min", "max", "step" ], function( i, option ) { 29312 var value = element.attr( option ); 29313 if ( value != null && value.length ) { 29314 options[ option ] = value; 29315 } 29316 } ); 29317 29318 return options; 29319 }, 29320 29321 _events: { 29322 keydown: function( event ) { 29323 if ( this._start( event ) && this._keydown( event ) ) { 29324 event.preventDefault(); 29325 } 29326 }, 29327 keyup: "_stop", 29328 focus: function() { 29329 this.previous = this.element.val(); 29330 }, 29331 blur: function( event ) { 29332 if ( this.cancelBlur ) { 29333 delete this.cancelBlur; 29334 return; 29335 } 29336 29337 this._stop(); 29338 this._refresh(); 29339 if ( this.previous !== this.element.val() ) { 29340 this._trigger( "change", event ); 29341 } 29342 }, 29343 mousewheel: function( event, delta ) { 29344 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); 29345 var isActive = this.element[ 0 ] === activeElement; 29346 29347 if ( !isActive || !delta ) { 29348 return; 29349 } 29350 29351 if ( !this.spinning && !this._start( event ) ) { 29352 return false; 29353 } 29354 29355 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 29356 clearTimeout( this.mousewheelTimer ); 29357 this.mousewheelTimer = this._delay( function() { 29358 if ( this.spinning ) { 29359 this._stop( event ); 29360 } 29361 }, 100 ); 29362 event.preventDefault(); 29363 }, 29364 "mousedown .ui-spinner-button": function( event ) { 29365 var previous; 29366 29367 // We never want the buttons to have focus; whenever the user is 29368 // interacting with the spinner, the focus should be on the input. 29369 // If the input is focused then this.previous is properly set from 29370 // when the input first received focus. If the input is not focused 29371 // then we need to set this.previous based on the value before spinning. 29372 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? 29373 this.previous : this.element.val(); 29374 function checkFocus() { 29375 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); 29376 if ( !isActive ) { 29377 this.element.trigger( "focus" ); 29378 this.previous = previous; 29379 29380 // support: IE 29381 // IE sets focus asynchronously, so we need to check if focus 29382 // moved off of the input because the user clicked on the button. 29383 this._delay( function() { 29384 this.previous = previous; 29385 } ); 29386 } 29387 } 29388 29389 // Ensure focus is on (or stays on) the text field 29390 event.preventDefault(); 29391 checkFocus.call( this ); 29392 29393 // Support: IE 29394 // IE doesn't prevent moving focus even with event.preventDefault() 29395 // so we set a flag to know when we should ignore the blur event 29396 // and check (again) if focus moved off of the input. 29397 this.cancelBlur = true; 29398 this._delay( function() { 29399 delete this.cancelBlur; 29400 checkFocus.call( this ); 29401 } ); 29402 29403 if ( this._start( event ) === false ) { 29404 return; 29405 } 29406 29407 this._repeat( null, $( event.currentTarget ) 29408 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 29409 }, 29410 "mouseup .ui-spinner-button": "_stop", 29411 "mouseenter .ui-spinner-button": function( event ) { 29412 29413 // button will add ui-state-active if mouse was down while mouseleave and kept down 29414 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 29415 return; 29416 } 29417 29418 if ( this._start( event ) === false ) { 29419 return false; 29420 } 29421 this._repeat( null, $( event.currentTarget ) 29422 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 29423 }, 29424 29425 // TODO: do we really want to consider this a stop? 29426 // shouldn't we just stop the repeater and wait until mouseup before 29427 // we trigger the stop event? 29428 "mouseleave .ui-spinner-button": "_stop" 29429 }, 29430 29431 // Support mobile enhanced option and make backcompat more sane 29432 _enhance: function() { 29433 this.uiSpinner = this.element 29434 .attr( "autocomplete", "off" ) 29435 .wrap( "<span>" ) 29436 .parent() 29437 29438 // Add buttons 29439 .append( 29440 "<a></a><a></a>" 29441 ); 29442 }, 29443 29444 _draw: function() { 29445 this._enhance(); 29446 29447 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 29448 this._addClass( "ui-spinner-input" ); 29449 29450 this.element.attr( "role", "spinbutton" ); 29451 29452 // Button bindings 29453 this.buttons = this.uiSpinner.children( "a" ) 29454 .attr( "tabIndex", -1 ) 29455 .attr( "aria-hidden", true ) 29456 .button( { 29457 classes: { 29458 "ui-button": "" 29459 } 29460 } ); 29461 29462 // TODO: Right now button does not support classes this is already updated in button PR 29463 this._removeClass( this.buttons, "ui-corner-all" ); 29464 29465 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 29466 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 29467 this.buttons.first().button( { 29468 "icon": this.options.icons.up, 29469 "showLabel": false 29470 } ); 29471 this.buttons.last().button( { 29472 "icon": this.options.icons.down, 29473 "showLabel": false 29474 } ); 29475 29476 // IE 6 doesn't understand height: 50% for the buttons 29477 // unless the wrapper has an explicit height 29478 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 29479 this.uiSpinner.height() > 0 ) { 29480 this.uiSpinner.height( this.uiSpinner.height() ); 29481 } 29482 }, 29483 29484 _keydown: function( event ) { 29485 var options = this.options, 29486 keyCode = $.ui.keyCode; 29487 29488 switch ( event.keyCode ) { 29489 case keyCode.UP: 29490 this._repeat( null, 1, event ); 29491 return true; 29492 case keyCode.DOWN: 29493 this._repeat( null, -1, event ); 29494 return true; 29495 case keyCode.PAGE_UP: 29496 this._repeat( null, options.page, event ); 29497 return true; 29498 case keyCode.PAGE_DOWN: 29499 this._repeat( null, -options.page, event ); 29500 return true; 29501 } 29502 29503 return false; 29504 }, 29505 29506 _start: function( event ) { 29507 if ( !this.spinning && this._trigger( "start", event ) === false ) { 29508 return false; 29509 } 29510 29511 if ( !this.counter ) { 29512 this.counter = 1; 29513 } 29514 this.spinning = true; 29515 return true; 29516 }, 29517 29518 _repeat: function( i, steps, event ) { 29519 i = i || 500; 29520 29521 clearTimeout( this.timer ); 29522 this.timer = this._delay( function() { 29523 this._repeat( 40, steps, event ); 29524 }, i ); 29525 29526 this._spin( steps * this.options.step, event ); 29527 }, 29528 29529 _spin: function( step, event ) { 29530 var value = this.value() || 0; 29531 29532 if ( !this.counter ) { 29533 this.counter = 1; 29534 } 29535 29536 value = this._adjustValue( value + step * this._increment( this.counter ) ); 29537 29538 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 29539 this._value( value ); 29540 this.counter++; 29541 } 29542 }, 29543 29544 _increment: function( i ) { 29545 var incremental = this.options.incremental; 29546 29547 if ( incremental ) { 29548 return typeof incremental === "function" ? 29549 incremental( i ) : 29550 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 29551 } 29552 29553 return 1; 29554 }, 29555 29556 _precision: function() { 29557 var precision = this._precisionOf( this.options.step ); 29558 if ( this.options.min !== null ) { 29559 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 29560 } 29561 return precision; 29562 }, 29563 29564 _precisionOf: function( num ) { 29565 var str = num.toString(), 29566 decimal = str.indexOf( "." ); 29567 return decimal === -1 ? 0 : str.length - decimal - 1; 29568 }, 29569 29570 _adjustValue: function( value ) { 29571 var base, aboveMin, 29572 options = this.options; 29573 29574 // Make sure we're at a valid step 29575 // - find out where we are relative to the base (min or 0) 29576 base = options.min !== null ? options.min : 0; 29577 aboveMin = value - base; 29578 29579 // - round to the nearest step 29580 aboveMin = Math.round( aboveMin / options.step ) * options.step; 29581 29582 // - rounding is based on 0, so adjust back to our base 29583 value = base + aboveMin; 29584 29585 // Fix precision from bad JS floating point math 29586 value = parseFloat( value.toFixed( this._precision() ) ); 29587 29588 // Clamp the value 29589 if ( options.max !== null && value > options.max ) { 29590 return options.max; 29591 } 29592 if ( options.min !== null && value < options.min ) { 29593 return options.min; 29594 } 29595 29596 return value; 29597 }, 29598 29599 _stop: function( event ) { 29600 if ( !this.spinning ) { 29601 return; 29602 } 29603 29604 clearTimeout( this.timer ); 29605 clearTimeout( this.mousewheelTimer ); 29606 this.counter = 0; 29607 this.spinning = false; 29608 this._trigger( "stop", event ); 29609 }, 29610 29611 _setOption: function( key, value ) { 29612 var prevValue, first, last; 29613 29614 if ( key === "culture" || key === "numberFormat" ) { 29615 prevValue = this._parse( this.element.val() ); 29616 this.options[ key ] = value; 29617 this.element.val( this._format( prevValue ) ); 29618 return; 29619 } 29620 29621 if ( key === "max" || key === "min" || key === "step" ) { 29622 if ( typeof value === "string" ) { 29623 value = this._parse( value ); 29624 } 29625 } 29626 if ( key === "icons" ) { 29627 first = this.buttons.first().find( ".ui-icon" ); 29628 this._removeClass( first, null, this.options.icons.up ); 29629 this._addClass( first, null, value.up ); 29630 last = this.buttons.last().find( ".ui-icon" ); 29631 this._removeClass( last, null, this.options.icons.down ); 29632 this._addClass( last, null, value.down ); 29633 } 29634 29635 this._super( key, value ); 29636 }, 29637 29638 _setOptionDisabled: function( value ) { 29639 this._super( value ); 29640 29641 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 29642 this.element.prop( "disabled", !!value ); 29643 this.buttons.button( value ? "disable" : "enable" ); 29644 }, 29645 29646 _setOptions: spinnerModifier( function( options ) { 29647 this._super( options ); 29648 } ), 29649 29650 _parse: function( val ) { 29651 if ( typeof val === "string" && val !== "" ) { 29652 val = window.Globalize && this.options.numberFormat ? 29653 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 29654 } 29655 return val === "" || isNaN( val ) ? null : val; 29656 }, 29657 29658 _format: function( value ) { 29659 if ( value === "" ) { 29660 return ""; 29661 } 29662 return window.Globalize && this.options.numberFormat ? 29663 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 29664 value; 29665 }, 29666 29667 _refresh: function() { 29668 this.element.attr( { 29669 "aria-valuemin": this.options.min, 29670 "aria-valuemax": this.options.max, 29671 29672 // TODO: what should we do with values that can't be parsed? 29673 "aria-valuenow": this._parse( this.element.val() ) 29674 } ); 29675 }, 29676 29677 isValid: function() { 29678 var value = this.value(); 29679 29680 // Null is invalid 29681 if ( value === null ) { 29682 return false; 29683 } 29684 29685 // If value gets adjusted, it's invalid 29686 return value === this._adjustValue( value ); 29687 }, 29688 29689 // Update the value without triggering change 29690 _value: function( value, allowAny ) { 29691 var parsed; 29692 if ( value !== "" ) { 29693 parsed = this._parse( value ); 29694 if ( parsed !== null ) { 29695 if ( !allowAny ) { 29696 parsed = this._adjustValue( parsed ); 29697 } 29698 value = this._format( parsed ); 29699 } 29700 } 29701 this.element.val( value ); 29702 this._refresh(); 29703 }, 29704 29705 _destroy: function() { 29706 this.element 29707 .prop( "disabled", false ) 29708 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 29709 29710 this.uiSpinner.replaceWith( this.element ); 29711 }, 29712 29713 stepUp: spinnerModifier( function( steps ) { 29714 this._stepUp( steps ); 29715 } ), 29716 _stepUp: function( steps ) { 29717 if ( this._start() ) { 29718 this._spin( ( steps || 1 ) * this.options.step ); 29719 this._stop(); 29720 } 29721 }, 29722 29723 stepDown: spinnerModifier( function( steps ) { 29724 this._stepDown( steps ); 29725 } ), 29726 _stepDown: function( steps ) { 29727 if ( this._start() ) { 29728 this._spin( ( steps || 1 ) * -this.options.step ); 29729 this._stop(); 29730 } 29731 }, 29732 29733 pageUp: spinnerModifier( function( pages ) { 29734 this._stepUp( ( pages || 1 ) * this.options.page ); 29735 } ), 29736 29737 pageDown: spinnerModifier( function( pages ) { 29738 this._stepDown( ( pages || 1 ) * this.options.page ); 29739 } ), 29740 29741 value: function( newVal ) { 29742 if ( !arguments.length ) { 29743 return this._parse( this.element.val() ); 29744 } 29745 spinnerModifier( this._value ).call( this, newVal ); 29746 }, 29747 29748 widget: function() { 29749 return this.uiSpinner; 29750 } 29751} ); 29752 29753// DEPRECATED 29754// TODO: switch return back to widget declaration at top of file when this is removed 29755if ( $.uiBackCompat !== false ) { 29756 29757 // Backcompat for spinner html extension points 29758 $.widget( "ui.spinner", $.ui.spinner, { 29759 _enhance: function() { 29760 this.uiSpinner = this.element 29761 .attr( "autocomplete", "off" ) 29762 .wrap( this._uiSpinnerHtml() ) 29763 .parent() 29764 29765 // Add buttons 29766 .append( this._buttonHtml() ); 29767 }, 29768 _uiSpinnerHtml: function() { 29769 return "<span>"; 29770 }, 29771 29772 _buttonHtml: function() { 29773 return "<a></a><a></a>"; 29774 } 29775 } ); 29776} 29777
29778return $.ui.spinner; 29779 29780} ); 29781 29782 29783 29784 29785 29786 29787/*! 29788 * jQuery UI Tabs 1.13.0 29789 * http://jqueryui.com 29790 * 29791 * Copyright jQuery Foundation and other contributors 29792 * Released under the MIT license. 29793 * http://jquery.org/license 29794 */ 29795 29796//>>label: Tabs 29797//>>group: Widgets 29798//>>description: Transforms a set of container elements into a tab structure. 29799//>>docs: http://api.jqueryui.com/tabs/ 29800//>>demos: http://jqueryui.com/tabs/ 29801//>>css.structure: ../../themes/base/core.css 29802//>>css.structure: ../../themes/base/tabs.css 29803//>>css.theme: ../../themes/base/theme.css 29804 29805( function( factory ) { 29806 "use strict"; 29807 29808 if ( typeof define === "function" && define.amd ) { 29809 29810 // AMD. Register as an anonymous module. 29811 define( [ 29812 "jquery", 29813 "../keycode", 29814 "../safe-active-element", 29815 "../unique-id", 29816 "../version", 29817 "../widget" 29818 ], factory ); 29819 } else { 29820 29821 // Browser globals 29822 factory( jQuery ); 29823 } 29824} )( function( $ ) { 29825"use strict"; 29826 29827$.widget( "ui.tabs", { 29828 version: "1.13.0
vendor: 21,408 bytes, lines 29828-30657
29828", 29829 delay: 300, 29830 options: { 29831 active: null, 29832 classes: { 29833 "ui-tabs": "ui-corner-all", 29834 "ui-tabs-nav": "ui-corner-all", 29835 "ui-tabs-panel": "ui-corner-bottom", 29836 "ui-tabs-tab": "ui-corner-top" 29837 }, 29838 collapsible: false, 29839 event: "click", 29840 heightStyle: "content", 29841 hide: null, 29842 show: null, 29843 29844 // Callbacks 29845 activate: null, 29846 beforeActivate: null, 29847 beforeLoad: null, 29848 load: null 29849 }, 29850 29851 _isLocal: ( function() { 29852 var rhash = /#.*$/; 29853 29854 return function( anchor ) { 29855 var anchorUrl, locationUrl; 29856 29857 anchorUrl = anchor.href.replace( rhash, "" ); 29858 locationUrl = location.href.replace( rhash, "" ); 29859 29860 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 29861 try { 29862 anchorUrl = decodeURIComponent( anchorUrl ); 29863 } catch ( error ) {} 29864 try { 29865 locationUrl = decodeURIComponent( locationUrl ); 29866 } catch ( error ) {} 29867 29868 return anchor.hash.length > 1 && anchorUrl === locationUrl; 29869 }; 29870 } )(), 29871 29872 _create: function() { 29873 var that = this, 29874 options = this.options; 29875 29876 this.running = false; 29877 29878 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 29879 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 29880 29881 this._processTabs(); 29882 options.active = this._initialActive(); 29883 29884 // Take disabling tabs via class attribute from HTML 29885 // into account and update option properly. 29886 if ( Array.isArray( options.disabled ) ) { 29887 options.disabled = $.uniqueSort( options.disabled.concat( 29888 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 29889 return that.tabs.index( li ); 29890 } ) 29891 ) ).sort(); 29892 } 29893 29894 // Check for length avoids error when initializing empty list 29895 if ( this.options.active !== false && this.anchors.length ) { 29896 this.active = this._findActive( options.active ); 29897 } else { 29898 this.active = $(); 29899 } 29900 29901 this._refresh(); 29902 29903 if ( this.active.length ) { 29904 this.load( options.active ); 29905 } 29906 }, 29907 29908 _initialActive: function() { 29909 var active = this.options.active, 29910 collapsible = this.options.collapsible, 29911 locationHash = location.hash.substring( 1 ); 29912 29913 if ( active === null ) { 29914 29915 // check the fragment identifier in the URL 29916 if ( locationHash ) { 29917 this.tabs.each( function( i, tab ) { 29918 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 29919 active = i; 29920 return false; 29921 } 29922 } ); 29923 } 29924 29925 // Check for a tab marked active via a class 29926 if ( active === null ) { 29927 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 29928 } 29929 29930 // No active tab, set to false 29931 if ( active === null || active === -1 ) { 29932 active = this.tabs.length ? 0 : false; 29933 } 29934 } 29935 29936 // Handle numbers: negative, out of range 29937 if ( active !== false ) { 29938 active = this.tabs.index( this.tabs.eq( active ) ); 29939 if ( active === -1 ) { 29940 active = collapsible ? false : 0; 29941 } 29942 } 29943 29944 // Don't allow collapsible: false and active: false 29945 if ( !collapsible && active === false && this.anchors.length ) { 29946 active = 0; 29947 } 29948 29949 return active; 29950 }, 29951 29952 _getCreateEventData: function() { 29953 return { 29954 tab: this.active, 29955 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 29956 }; 29957 }, 29958 29959 _tabKeydown: function( event ) { 29960 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), 29961 selectedIndex = this.tabs.index( focusedTab ), 29962 goingForward = true; 29963 29964 if ( this._handlePageNav( event ) ) { 29965 return; 29966 } 29967 29968 switch ( event.keyCode ) { 29969 case $.ui.keyCode.RIGHT: 29970 case $.ui.keyCode.DOWN: 29971 selectedIndex++; 29972 break; 29973 case $.ui.keyCode.UP: 29974 case $.ui.keyCode.LEFT: 29975 goingForward = false; 29976 selectedIndex--; 29977 break; 29978 case $.ui.keyCode.END: 29979 selectedIndex = this.anchors.length - 1; 29980 break; 29981 case $.ui.keyCode.HOME: 29982 selectedIndex = 0; 29983 break; 29984 case $.ui.keyCode.SPACE: 29985 29986 // Activate only, no collapsing 29987 event.preventDefault(); 29988 clearTimeout( this.activating ); 29989 this._activate( selectedIndex ); 29990 return; 29991 case $.ui.keyCode.ENTER: 29992 29993 // Toggle (cancel delayed activation, allow collapsing) 29994 event.preventDefault(); 29995 clearTimeout( this.activating ); 29996 29997 // Determine if we should collapse or activate 29998 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 29999 return; 30000 default: 30001 return; 30002 } 30003 30004 // Focus the appropriate tab, based on which key was pressed 30005 event.preventDefault(); 30006 clearTimeout( this.activating ); 30007 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 30008 30009 // Navigating with control/command key will prevent automatic activation 30010 if ( !event.ctrlKey && !event.metaKey ) { 30011 30012 // Update aria-selected immediately so that AT think the tab is already selected. 30013 // Otherwise AT may confuse the user by stating that they need to activate the tab, 30014 // but the tab will already be activated by the time the announcement finishes. 30015 focusedTab.attr( "aria-selected", "false" ); 30016 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 30017 30018 this.activating = this._delay( function() { 30019 this.option( "active", selectedIndex ); 30020 }, this.delay ); 30021 } 30022 }, 30023 30024 _panelKeydown: function( event ) { 30025 if ( this._handlePageNav( event ) ) { 30026 return; 30027 } 30028 30029 // Ctrl+up moves focus to the current tab 30030 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 30031 event.preventDefault(); 30032 this.active.trigger( "focus" ); 30033 } 30034 }, 30035 30036 // Alt+page up/down moves focus to the previous/next tab (and activates) 30037 _handlePageNav: function( event ) { 30038 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 30039 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 30040 return true; 30041 } 30042 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 30043 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 30044 return true; 30045 } 30046 }, 30047 30048 _findNextTab: function( index, goingForward ) { 30049 var lastTabIndex = this.tabs.length - 1; 30050 30051 function constrain() { 30052 if ( index > lastTabIndex ) { 30053 index = 0; 30054 } 30055 if ( index < 0 ) { 30056 index = lastTabIndex; 30057 } 30058 return index; 30059 } 30060 30061 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 30062 index = goingForward ? index + 1 : index - 1; 30063 } 30064 30065 return index; 30066 }, 30067 30068 _focusNextTab: function( index, goingForward ) { 30069 index = this._findNextTab( index, goingForward ); 30070 this.tabs.eq( index ).trigger( "focus" ); 30071 return index; 30072 }, 30073 30074 _setOption: function( key, value ) { 30075 if ( key === "active" ) { 30076 30077 // _activate() will handle invalid values and update this.options 30078 this._activate( value ); 30079 return; 30080 } 30081 30082 this._super( key, value ); 30083 30084 if ( key === "collapsible" ) { 30085 this._toggleClass( "ui-tabs-collapsible", null, value ); 30086 30087 // Setting collapsible: false while collapsed; open first panel 30088 if ( !value && this.options.active === false ) { 30089 this._activate( 0 ); 30090 } 30091 } 30092 30093 if ( key === "event" ) { 30094 this._setupEvents( value ); 30095 } 30096 30097 if ( key === "heightStyle" ) { 30098 this._setupHeightStyle( value ); 30099 } 30100 }, 30101 30102 _sanitizeSelector: function( hash ) { 30103 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 30104 }, 30105 30106 refresh: function() { 30107 var options = this.options, 30108 lis = this.tablist.children( ":has(a[href])" ); 30109 30110 // Get disabled tabs from class attribute from HTML 30111 // this will get converted to a boolean if needed in _refresh() 30112 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 30113 return lis.index( tab ); 30114 } ); 30115 30116 this._processTabs(); 30117 30118 // Was collapsed or no tabs 30119 if ( options.active === false || !this.anchors.length ) { 30120 options.active = false; 30121 this.active = $(); 30122 30123 // was active, but active tab is gone 30124 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 30125 30126 // all remaining tabs are disabled 30127 if ( this.tabs.length === options.disabled.length ) { 30128 options.active = false; 30129 this.active = $(); 30130 30131 // activate previous tab 30132 } else { 30133 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 30134 } 30135 30136 // was active, active tab still exists 30137 } else { 30138 30139 // make sure active index is correct 30140 options.active = this.tabs.index( this.active ); 30141 } 30142 30143 this._refresh(); 30144 }, 30145 30146 _refresh: function() { 30147 this._setOptionDisabled( this.options.disabled ); 30148 this._setupEvents( this.options.event ); 30149 this._setupHeightStyle( this.options.heightStyle ); 30150 30151 this.tabs.not( this.active ).attr( { 30152 "aria-selected": "false", 30153 "aria-expanded": "false", 30154 tabIndex: -1 30155 } ); 30156 this.panels.not( this._getPanelForTab( this.active ) ) 30157 .hide() 30158 .attr( { 30159 "aria-hidden": "true" 30160 } ); 30161 30162 // Make sure one tab is in the tab order 30163 if ( !this.active.length ) { 30164 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 30165 } else { 30166 this.active 30167 .attr( { 30168 "aria-selected": "true", 30169 "aria-expanded": "true", 30170 tabIndex: 0 30171 } ); 30172 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 30173 this._getPanelForTab( this.active ) 30174 .show() 30175 .attr( { 30176 "aria-hidden": "false" 30177 } ); 30178 } 30179 }, 30180 30181 _processTabs: function() { 30182 var that = this, 30183 prevTabs = this.tabs, 30184 prevAnchors = this.anchors, 30185 prevPanels = this.panels; 30186 30187 this.tablist = this._getList().attr( "role", "tablist" ); 30188 this._addClass( this.tablist, "ui-tabs-nav", 30189 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 30190 30191 // Prevent users from focusing disabled tabs via click 30192 this.tablist 30193 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 30194 if ( $( this ).is( ".ui-state-disabled" ) ) { 30195 event.preventDefault(); 30196 } 30197 } ) 30198 30199 // Support: IE <9 30200 // Preventing the default action in mousedown doesn't prevent IE 30201 // from focusing the element, so if the anchor gets focused, blur. 30202 // We don't have to worry about focusing the previously focused 30203 // element since clicking on a non-focusable element should focus 30204 // the body anyway. 30205 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { 30206 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 30207 this.blur(); 30208 } 30209 } ); 30210 30211 this.tabs = this.tablist.find( "> li:has(a[href])" ) 30212 .attr( { 30213 role: "tab", 30214 tabIndex: -1 30215 } ); 30216 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 30217 30218 this.anchors = this.tabs.map( function() { 30219 return $( "a", this )[ 0 ]; 30220 } ) 30221 .attr( { 30222 tabIndex: -1 30223 } ); 30224 this._addClass( this.anchors, "ui-tabs-anchor" ); 30225 30226 this.panels = $(); 30227 30228 this.anchors.each( function( i, anchor ) { 30229 var selector, panel, panelId, 30230 anchorId = $( anchor ).uniqueId().attr( "id" ), 30231 tab = $( anchor ).closest( "li" ), 30232 originalAriaControls = tab.attr( "aria-controls" ); 30233 30234 // Inline tab 30235 if ( that._isLocal( anchor ) ) { 30236 selector = anchor.hash; 30237 panelId = selector.substring( 1 ); 30238 panel = that.element.find( that._sanitizeSelector( selector ) ); 30239 30240 // remote tab 30241 } else { 30242 30243 // If the tab doesn't already have aria-controls, 30244 // generate an id by using a throw-away element 30245 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 30246 selector = "#" + panelId; 30247 panel = that.element.find( selector ); 30248 if ( !panel.length ) { 30249 panel = that._createPanel( panelId ); 30250 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 30251 } 30252 panel.attr( "aria-live", "polite" ); 30253 } 30254 30255 if ( panel.length ) { 30256 that.panels = that.panels.add( panel ); 30257 } 30258 if ( originalAriaControls ) { 30259 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 30260 } 30261 tab.attr( { 30262 "aria-controls": panelId, 30263 "aria-labelledby": anchorId 30264 } ); 30265 panel.attr( "aria-labelledby", anchorId ); 30266 } ); 30267 30268 this.panels.attr( "role", "tabpanel" ); 30269 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 30270 30271 // Avoid memory leaks (#10056) 30272 if ( prevTabs ) { 30273 this._off( prevTabs.not( this.tabs ) ); 30274 this._off( prevAnchors.not( this.anchors ) ); 30275 this._off( prevPanels.not( this.panels ) ); 30276 } 30277 }, 30278 30279 // Allow overriding how to find the list for rare usage scenarios (#7715) 30280 _getList: function() { 30281 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 30282 }, 30283 30284 _createPanel: function( id ) { 30285 return $( "<div>" ) 30286 .attr( "id", id ) 30287 .data( "ui-tabs-destroy", true ); 30288 }, 30289 30290 _setOptionDisabled: function( disabled ) { 30291 var currentItem, li, i; 30292 30293 if ( Array.isArray( disabled ) ) { 30294 if ( !disabled.length ) { 30295 disabled = false; 30296 } else if ( disabled.length === this.anchors.length ) { 30297 disabled = true; 30298 } 30299 } 30300 30301 // Disable tabs 30302 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 30303 currentItem = $( li ); 30304 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 30305 currentItem.attr( "aria-disabled", "true" ); 30306 this._addClass( currentItem, null, "ui-state-disabled" ); 30307 } else { 30308 currentItem.removeAttr( "aria-disabled" ); 30309 this._removeClass( currentItem, null, "ui-state-disabled" ); 30310 } 30311 } 30312 30313 this.options.disabled = disabled; 30314 30315 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 30316 disabled === true ); 30317 }, 30318 30319 _setupEvents: function( event ) { 30320 var events = {}; 30321 if ( event ) { 30322 $.each( event.split( " " ), function( index, eventName ) { 30323 events[ eventName ] = "_eventHandler"; 30324 } ); 30325 } 30326 30327 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 30328 30329 // Always prevent the default action, even when disabled 30330 this._on( true, this.anchors, { 30331 click: function( event ) { 30332 event.preventDefault(); 30333 } 30334 } ); 30335 this._on( this.anchors, events ); 30336 this._on( this.tabs, { keydown: "_tabKeydown" } ); 30337 this._on( this.panels, { keydown: "_panelKeydown" } ); 30338 30339 this._focusable( this.tabs ); 30340 this._hoverable( this.tabs ); 30341 }, 30342 30343 _setupHeightStyle: function( heightStyle ) { 30344 var maxHeight, 30345 parent = this.element.parent(); 30346 30347 if ( heightStyle === "fill" ) { 30348 maxHeight = parent.height(); 30349 maxHeight -= this.element.outerHeight() - this.element.height(); 30350 30351 this.element.siblings( ":visible" ).each( function() { 30352 var elem = $( this ), 30353 position = elem.css( "position" ); 30354 30355 if ( position === "absolute" || position === "fixed" ) { 30356 return; 30357 } 30358 maxHeight -= elem.outerHeight( true ); 30359 } ); 30360 30361 this.element.children().not( this.panels ).each( function() { 30362 maxHeight -= $( this ).outerHeight( true ); 30363 } ); 30364 30365 this.panels.each( function() { 30366 $( this ).height( Math.max( 0, maxHeight - 30367 $( this ).innerHeight() + $( this ).height() ) ); 30368 } ) 30369 .css( "overflow", "auto" ); 30370 } else if ( heightStyle === "auto" ) { 30371 maxHeight = 0; 30372 this.panels.each( function() { 30373 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 30374 } ).height( maxHeight ); 30375 } 30376 }, 30377 30378 _eventHandler: function( event ) { 30379 var options = this.options, 30380 active = this.active, 30381 anchor = $( event.currentTarget ), 30382 tab = anchor.closest( "li" ), 30383 clickedIsActive = tab[ 0 ] === active[ 0 ], 30384 collapsing = clickedIsActive && options.collapsible, 30385 toShow = collapsing ? $() : this._getPanelForTab( tab ), 30386 toHide = !active.length ? $() : this._getPanelForTab( active ), 30387 eventData = { 30388 oldTab: active, 30389 oldPanel: toHide, 30390 newTab: collapsing ? $() : tab, 30391 newPanel: toShow 30392 }; 30393 30394 event.preventDefault(); 30395 30396 if ( tab.hasClass( "ui-state-disabled" ) || 30397 30398 // tab is already loading 30399 tab.hasClass( "ui-tabs-loading" ) || 30400 30401 // can't switch durning an animation 30402 this.running || 30403 30404 // click on active header, but not collapsible 30405 ( clickedIsActive && !options.collapsible ) || 30406 30407 // allow canceling activation 30408 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 30409 return; 30410 } 30411 30412 options.active = collapsing ? false : this.tabs.index( tab ); 30413 30414 this.active = clickedIsActive ? $() : tab; 30415 if ( this.xhr ) { 30416 this.xhr.abort(); 30417 } 30418 30419 if ( !toHide.length && !toShow.length ) { 30420 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 30421 } 30422 30423 if ( toShow.length ) { 30424 this.load( this.tabs.index( tab ), event ); 30425 } 30426 this._toggle( event, eventData ); 30427 }, 30428 30429 // Handles show/hide for selecting tabs 30430 _toggle: function( event, eventData ) { 30431 var that = this, 30432 toShow = eventData.newPanel, 30433 toHide = eventData.oldPanel; 30434 30435 this.running = true; 30436 30437 function complete() { 30438 that.running = false; 30439 that._trigger( "activate", event, eventData ); 30440 } 30441 30442 function show() { 30443 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 30444 30445 if ( toShow.length && that.options.show ) { 30446 that._show( toShow, that.options.show, complete ); 30447 } else { 30448 toShow.show(); 30449 complete(); 30450 } 30451 } 30452 30453 // Start out by hiding, then showing, then completing 30454 if ( toHide.length && this.options.hide ) { 30455 this._hide( toHide, this.options.hide, function() { 30456 that._removeClass( eventData.oldTab.closest( "li" ), 30457 "ui-tabs-active", "ui-state-active" ); 30458 show(); 30459 } ); 30460 } else { 30461 this._removeClass( eventData.oldTab.closest( "li" ), 30462 "ui-tabs-active", "ui-state-active" ); 30463 toHide.hide(); 30464 show(); 30465 } 30466 30467 toHide.attr( "aria-hidden", "true" ); 30468 eventData.oldTab.attr( { 30469 "aria-selected": "false", 30470 "aria-expanded": "false" 30471 } ); 30472 30473 // If we're switching tabs, remove the old tab from the tab order. 30474 // If we're opening from collapsed state, remove the previous tab from the tab order. 30475 // If we're collapsing, then keep the collapsing tab in the tab order. 30476 if ( toShow.length && toHide.length ) { 30477 eventData.oldTab.attr( "tabIndex", -1 ); 30478 } else if ( toShow.length ) { 30479 this.tabs.filter( function() { 30480 return $( this ).attr( "tabIndex" ) === 0; 30481 } ) 30482 .attr( "tabIndex", -1 ); 30483 } 30484 30485 toShow.attr( "aria-hidden", "false" ); 30486 eventData.newTab.attr( { 30487 "aria-selected": "true", 30488 "aria-expanded": "true", 30489 tabIndex: 0 30490 } ); 30491 }, 30492 30493 _activate: function( index ) { 30494 var anchor, 30495 active = this._findActive( index ); 30496 30497 // Trying to activate the already active panel 30498 if ( active[ 0 ] === this.active[ 0 ] ) { 30499 return; 30500 } 30501 30502 // Trying to collapse, simulate a click on the current active header 30503 if ( !active.length ) { 30504 active = this.active; 30505 } 30506 30507 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 30508 this._eventHandler( { 30509 target: anchor, 30510 currentTarget: anchor, 30511 preventDefault: $.noop 30512 } ); 30513 }, 30514 30515 _findActive: function( index ) { 30516 return index === false ? $() : this.tabs.eq( index ); 30517 }, 30518 30519 _getIndex: function( index ) { 30520 30521 // meta-function to give users option to provide a href string instead of a numerical index. 30522 if ( typeof index === "string" ) { 30523 index = this.anchors.index( this.anchors.filter( "[href$='" + 30524 $.escapeSelector( index ) + "']" ) ); 30525 } 30526 30527 return index; 30528 }, 30529 30530 _destroy: function() { 30531 if ( this.xhr ) { 30532 this.xhr.abort(); 30533 } 30534 30535 this.tablist 30536 .removeAttr( "role" ) 30537 .off( this.eventNamespace ); 30538 30539 this.anchors 30540 .removeAttr( "role tabIndex" ) 30541 .removeUniqueId(); 30542 30543 this.tabs.add( this.panels ).each( function() { 30544 if ( $.data( this, "ui-tabs-destroy" ) ) { 30545 $( this ).remove(); 30546 } else { 30547 $( this ).removeAttr( "role tabIndex " + 30548 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 30549 } 30550 } ); 30551 30552 this.tabs.each( function() { 30553 var li = $( this ), 30554 prev = li.data( "ui-tabs-aria-controls" ); 30555 if ( prev ) { 30556 li 30557 .attr( "aria-controls", prev ) 30558 .removeData( "ui-tabs-aria-controls" ); 30559 } else { 30560 li.removeAttr( "aria-controls" ); 30561 } 30562 } ); 30563 30564 this.panels.show(); 30565 30566 if ( this.options.heightStyle !== "content" ) { 30567 this.panels.css( "height", "" ); 30568 } 30569 }, 30570 30571 enable: function( index ) { 30572 var disabled = this.options.disabled; 30573 if ( disabled === false ) { 30574 return; 30575 } 30576 30577 if ( index === undefined ) { 30578 disabled = false; 30579 } else { 30580 index = this._getIndex( index ); 30581 if ( Array.isArray( disabled ) ) { 30582 disabled = $.map( disabled, function( num ) { 30583 return num !== index ? num : null; 30584 } ); 30585 } else { 30586 disabled = $.map( this.tabs, function( li, num ) { 30587 return num !== index ? num : null; 30588 } ); 30589 } 30590 } 30591 this._setOptionDisabled( disabled ); 30592 }, 30593 30594 disable: function( index ) { 30595 var disabled = this.options.disabled; 30596 if ( disabled === true ) { 30597 return; 30598 } 30599 30600 if ( index === undefined ) { 30601 disabled = true; 30602 } else { 30603 index = this._getIndex( index ); 30604 if ( $.inArray( index, disabled ) !== -1 ) { 30605 return; 30606 } 30607 if ( Array.isArray( disabled ) ) { 30608 disabled = $.merge( [ index ], disabled ).sort(); 30609 } else { 30610 disabled = [ index ]; 30611 } 30612 } 30613 this._setOptionDisabled( disabled ); 30614 }, 30615 30616 load: function( index, event ) { 30617 index = this._getIndex( index ); 30618 var that = this, 30619 tab = this.tabs.eq( index ), 30620 anchor = tab.find( ".ui-tabs-anchor" ), 30621 panel = this._getPanelForTab( tab ), 30622 eventData = { 30623 tab: tab, 30624 panel: panel 30625 }, 30626 complete = function( jqXHR, status ) { 30627 if ( status === "abort" ) { 30628 that.panels.stop( false, true ); 30629 } 30630 30631 that._removeClass( tab, "ui-tabs-loading" ); 30632 panel.removeAttr( "aria-busy" ); 30633 30634 if ( jqXHR === that.xhr ) { 30635 delete that.xhr; 30636 } 30637 }; 30638 30639 // Not remote 30640 if ( this._isLocal( anchor[ 0 ] ) ) { 30641 return; 30642 } 30643 30644 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 30645 30646 // Support: jQuery <1.8 30647 // jQuery <1.8 returns false if the request is canceled in beforeSend, 30648 // but as of 1.8, $.ajax() always returns a jqXHR object. 30649 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 30650 this._addClass( tab, "ui-tabs-loading" ); 30651 panel.attr( "aria-busy", "true" ); 30652 30653 this.xhr 30654 .done( function( response, status, jqXHR ) { 30655 30656 // support: jQuery <1.8 30657 // http
30657://bugs.jquery.com/ticket/11778 30658 setTimeout( function() { 30659 panel.html( response ); 30660 that._trigger( "load", event, eventData ); 30661 30662 complete( jqXHR, status ); 30663 }, 1 ); 30664 } ) 30665 .fail( function( jqXHR, status ) { 30666 30667 // support: jQuery <1.8 30668 // http://bugs.jquery.com/ticket/11778 30669 setTimeout( function() { 30670 complete( jqXHR, status ); 30671 }, 1 ); 30672 } ); 30673 } 30674 }, 30675 30676 _ajaxSettings: function( anchor, event, eventData ) { 30677 var that = this; 30678 return { 30679
vendor: 18,280 bytes, lines 30680-31366
30680 // Support: IE <11 only 30681 // Strip any hash that exists to prevent errors with the Ajax request 30682 url: anchor.attr( "href" ).replace( /#.*$/, "" ), 30683 beforeSend: function( jqXHR, settings ) { 30684 return that._trigger( "beforeLoad", event, 30685 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 30686 } 30687 }; 30688 }, 30689 30690 _getPanelForTab: function( tab ) { 30691 var id = $( tab ).attr( "aria-controls" ); 30692 return this.element.find( this._sanitizeSelector( "#" + id ) ); 30693 } 30694} ); 30695 30696// DEPRECATED 30697// TODO: Switch return back to widget declaration at top of file when this is removed 30698if ( $.uiBackCompat !== false ) { 30699 30700 // Backcompat for ui-tab class (now ui-tabs-tab) 30701 $.widget( "ui.tabs", $.ui.tabs, { 30702 _processTabs: function() { 30703 this._superApply( arguments ); 30704 this._addClass( this.tabs, "ui-tab" ); 30705 } 30706 } ); 30707} 30708 30709return $.ui.tabs; 30710 30711} ); 30712 30713 30714 30715 30716 30717 30718/*! 30719 * jQuery UI Tooltip 1.13.0 30720 * http://jqueryui.com 30721 * 30722 * Copyright jQuery Foundation and other contributors 30723 * Released under the MIT license. 30724 * http://jquery.org/license 30725 */ 30726 30727//>>label: Tooltip 30728//>>group: Widgets 30729//>>description: Shows additional information for any element on hover or focus. 30730//>>docs: http://api.jqueryui.com/tooltip/ 30731//>>demos: http://jqueryui.com/tooltip/ 30732//>>css.structure: ../../themes/base/core.css 30733//>>css.structure: ../../themes/base/tooltip.css 30734//>>css.theme: ../../themes/base/theme.css 30735 30736( function( factory ) { 30737 "use strict"; 30738 30739 if ( typeof define === "function" && define.amd ) { 30740 30741 // AMD. Register as an anonymous module. 30742 define( [ 30743 "jquery", 30744 "../keycode", 30745 "../position", 30746 "../unique-id", 30747 "../version", 30748 "../widget" 30749 ], factory ); 30750 } else { 30751 30752 // Browser globals 30753 factory( jQuery ); 30754 } 30755} )( function( $ ) { 30756"use strict"; 30757 30758$.widget( "ui.tooltip", { 30759 version: "1.13.0", 30760 options: { 30761 classes: { 30762 "ui-tooltip": "ui-corner-all ui-widget-shadow" 30763 }, 30764 content: function() { 30765 var title = $( this ).attr( "title" ); 30766 30767 // Escape title, since we're going from an attribute to raw HTML 30768 return $( "<a>" ).text( title ).html(); 30769 }, 30770 hide: true, 30771 30772 // Disabled elements have inconsistent behavior across browsers (#8661) 30773 items: "[title]:not([disabled])", 30774 position: { 30775 my: "left top+15", 30776 at: "left bottom", 30777 collision: "flipfit flip" 30778 }, 30779 show: true, 30780 track: false, 30781 30782 // Callbacks 30783 close: null, 30784 open: null 30785 }, 30786 30787 _addDescribedBy: function( elem, id ) { 30788 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 30789 describedby.push( id ); 30790 elem 30791 .data( "ui-tooltip-id", id ) 30792 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 30793 }, 30794 30795 _removeDescribedBy: function( elem ) { 30796 var id = elem.data( "ui-tooltip-id" ), 30797 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 30798 index = $.inArray( id, describedby ); 30799 30800 if ( index !== -1 ) { 30801 describedby.splice( index, 1 ); 30802 } 30803 30804 elem.removeData( "ui-tooltip-id" ); 30805 describedby = String.prototype.trim.call( describedby.join( " " ) ); 30806 if ( describedby ) { 30807 elem.attr( "aria-describedby", describedby ); 30808 } else { 30809 elem.removeAttr( "aria-describedby" ); 30810 } 30811 }, 30812 30813 _create: function() { 30814 this._on( { 30815 mouseover: "open", 30816 focusin: "open" 30817 } ); 30818 30819 // IDs of generated tooltips, needed for destroy 30820 this.tooltips = {}; 30821 30822 // IDs of parent tooltips where we removed the title attribute 30823 this.parents = {}; 30824 30825 // Append the aria-live region so tooltips announce correctly 30826 this.liveRegion = $( "<div>" ) 30827 .attr( { 30828 role: "log", 30829 "aria-live": "assertive", 30830 "aria-relevant": "additions" 30831 } ) 30832 .appendTo( this.document[ 0 ].body ); 30833 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 30834 30835 this.disabledTitles = $( [] ); 30836 }, 30837 30838 _setOption: function( key, value ) { 30839 var that = this; 30840 30841 this._super( key, value ); 30842 30843 if ( key === "content" ) { 30844 $.each( this.tooltips, function( id, tooltipData ) { 30845 that._updateContent( tooltipData.element ); 30846 } ); 30847 } 30848 }, 30849 30850 _setOptionDisabled: function( value ) { 30851 this[ value ? "_disable" : "_enable" ](); 30852 }, 30853 30854 _disable: function() { 30855 var that = this; 30856 30857 // Close open tooltips 30858 $.each( this.tooltips, function( id, tooltipData ) { 30859 var event = $.Event( "blur" ); 30860 event.target = event.currentTarget = tooltipData.element[ 0 ]; 30861 that.close( event, true ); 30862 } ); 30863 30864 // Remove title attributes to prevent native tooltips 30865 this.disabledTitles = this.disabledTitles.add( 30866 this.element.find( this.options.items ).addBack() 30867 .filter( function() { 30868 var element = $( this ); 30869 if ( element.is( "[title]" ) ) { 30870 return element 30871 .data( "ui-tooltip-title", element.attr( "title" ) ) 30872 .removeAttr( "title" ); 30873 } 30874 } ) 30875 ); 30876 }, 30877 30878 _enable: function() { 30879 30880 // restore title attributes 30881 this.disabledTitles.each( function() { 30882 var element = $( this ); 30883 if ( element.data( "ui-tooltip-title" ) ) { 30884 element.attr( "title", element.data( "ui-tooltip-title" ) ); 30885 } 30886 } ); 30887 this.disabledTitles = $( [] ); 30888 }, 30889 30890 open: function( event ) { 30891 var that = this, 30892 target = $( event ? event.target : this.element ) 30893 30894 // we need closest here due to mouseover bubbling, 30895 // but always pointing at the same event target 30896 .closest( this.options.items ); 30897 30898 // No element to show a tooltip for or the tooltip is already open 30899 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 30900 return; 30901 } 30902 30903 if ( target.attr( "title" ) ) { 30904 target.data( "ui-tooltip-title", target.attr( "title" ) ); 30905 } 30906 30907 target.data( "ui-tooltip-open", true ); 30908 30909 // Kill parent tooltips, custom or native, for hover 30910 if ( event && event.type === "mouseover" ) { 30911 target.parents().each( function() { 30912 var parent = $( this ), 30913 blurEvent; 30914 if ( parent.data( "ui-tooltip-open" ) ) { 30915 blurEvent = $.Event( "blur" ); 30916 blurEvent.target = blurEvent.currentTarget = this; 30917 that.close( blurEvent, true ); 30918 } 30919 if ( parent.attr( "title" ) ) { 30920 parent.uniqueId(); 30921 that.parents[ this.id ] = { 30922 element: this, 30923 title: parent.attr( "title" ) 30924 }; 30925 parent.attr( "title", "" ); 30926 } 30927 } ); 30928 } 30929 30930 this._registerCloseHandlers( event, target ); 30931 this._updateContent( target, event ); 30932 }, 30933 30934 _updateContent: function( target, event ) { 30935 var content, 30936 contentOption = this.options.content, 30937 that = this, 30938 eventType = event ? event.type : null; 30939 30940 if ( typeof contentOption === "string" || contentOption.nodeType || 30941 contentOption.jquery ) { 30942 return this._open( event, target, contentOption ); 30943 } 30944 30945 content = contentOption.call( target[ 0 ], function( response ) { 30946 30947 // IE may instantly serve a cached response for ajax requests 30948 // delay this call to _open so the other call to _open runs first 30949 that._delay( function() { 30950 30951 // Ignore async response if tooltip was closed already 30952 if ( !target.data( "ui-tooltip-open" ) ) { 30953 return; 30954 } 30955 30956 // JQuery creates a special event for focusin when it doesn't 30957 // exist natively. To improve performance, the native event 30958 // object is reused and the type is changed. Therefore, we can't 30959 // rely on the type being correct after the event finished 30960 // bubbling, so we set it back to the previous value. (#8740) 30961 if ( event ) { 30962 event.type = eventType; 30963 } 30964 this._open( event, target, response ); 30965 } ); 30966 } ); 30967 if ( content ) { 30968 this._open( event, target, content ); 30969 } 30970 }, 30971 30972 _open: function( event, target, content ) { 30973 var tooltipData, tooltip, delayedShow, a11yContent, 30974 positionOption = $.extend( {}, this.options.position ); 30975 30976 if ( !content ) { 30977 return; 30978 } 30979 30980 // Content can be updated multiple times. If the tooltip already 30981 // exists, then just update the content and bail. 30982 tooltipData = this._find( target ); 30983 if ( tooltipData ) { 30984 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 30985 return; 30986 } 30987 30988 // If we have a title, clear it to prevent the native tooltip 30989 // we have to check first to avoid defining a title if none exists 30990 // (we don't want to cause an element to start matching [title]) 30991 // 30992 // We use removeAttr only for key events, to allow IE to export the correct 30993 // accessible attributes. For mouse events, set to empty string to avoid 30994 // native tooltip showing up (happens only when removing inside mouseover). 30995 if ( target.is( "[title]" ) ) { 30996 if ( event && event.type === "mouseover" ) { 30997 target.attr( "title", "" ); 30998 } else { 30999 target.removeAttr( "title" ); 31000 } 31001 } 31002 31003 tooltipData = this._tooltip( target ); 31004 tooltip = tooltipData.tooltip; 31005 this._addDescribedBy( target, tooltip.attr( "id" ) ); 31006 tooltip.find( ".ui-tooltip-content" ).html( content ); 31007 31008 // Support: Voiceover on OS X, JAWS on IE <= 9 31009 // JAWS announces deletions even when aria-relevant="additions" 31010 // Voiceover will sometimes re-read the entire log region's contents from the beginning 31011 this.liveRegion.children().hide(); 31012 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 31013 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 31014 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 31015 a11yContent.appendTo( this.liveRegion ); 31016 31017 function position( event ) { 31018 positionOption.of = event; 31019 if ( tooltip.is( ":hidden" ) ) { 31020 return; 31021 } 31022 tooltip.position( positionOption ); 31023 } 31024 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 31025 this._on( this.document, { 31026 mousemove: position 31027 } ); 31028 31029 // trigger once to override element-relative positioning 31030 position( event ); 31031 } else { 31032 tooltip.position( $.extend( { 31033 of: target 31034 }, this.options.position ) ); 31035 } 31036 31037 tooltip.hide(); 31038 31039 this._show( tooltip, this.options.show ); 31040 31041 // Handle tracking tooltips that are shown with a delay (#8644). As soon 31042 // as the tooltip is visible, position the tooltip using the most recent 31043 // event. 31044 // Adds the check to add the timers only when both delay and track options are set (#14682) 31045 if ( this.options.track && this.options.show && this.options.show.delay ) { 31046 delayedShow = this.delayedShow = setInterval( function() { 31047 if ( tooltip.is( ":visible" ) ) { 31048 position( positionOption.of ); 31049 clearInterval( delayedShow ); 31050 } 31051 }, 13 ); 31052 } 31053 31054 this._trigger( "open", event, { tooltip: tooltip } ); 31055 }, 31056 31057 _registerCloseHandlers: function( event, target ) { 31058 var events = { 31059 keyup: function( event ) { 31060 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 31061 var fakeEvent = $.Event( event ); 31062 fakeEvent.currentTarget = target[ 0 ]; 31063 this.close( fakeEvent, true ); 31064 } 31065 } 31066 }; 31067 31068 // Only bind remove handler for delegated targets. Non-delegated 31069 // tooltips will handle this in destroy. 31070 if ( target[ 0 ] !== this.element[ 0 ] ) { 31071 events.remove = function() { 31072 this._removeTooltip( this._find( target ).tooltip ); 31073 }; 31074 } 31075 31076 if ( !event || event.type === "mouseover" ) { 31077 events.mouseleave = "close"; 31078 } 31079 if ( !event || event.type === "focusin" ) { 31080 events.focusout = "close"; 31081 } 31082 this._on( true, target, events ); 31083 }, 31084 31085 close: function( event ) { 31086 var tooltip, 31087 that = this, 31088 target = $( event ? event.currentTarget : this.element ), 31089 tooltipData = this._find( target ); 31090 31091 // The tooltip may already be closed 31092 if ( !tooltipData ) { 31093 31094 // We set ui-tooltip-open immediately upon open (in open()), but only set the 31095 // additional data once there's actually content to show (in _open()). So even if the 31096 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 31097 // the period between open() and _open(). 31098 target.removeData( "ui-tooltip-open" ); 31099 return; 31100 } 31101 31102 tooltip = tooltipData.tooltip; 31103 31104 // Disabling closes the tooltip, so we need to track when we're closing 31105 // to avoid an infinite loop in case the tooltip becomes disabled on close 31106 if ( tooltipData.closing ) { 31107 return; 31108 } 31109 31110 // Clear the interval for delayed tracking tooltips 31111 clearInterval( this.delayedShow ); 31112 31113 // Only set title if we had one before (see comment in _open()) 31114 // If the title attribute has changed since open(), don't restore 31115 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 31116 target.attr( "title", target.data( "ui-tooltip-title" ) ); 31117 } 31118 31119 this._removeDescribedBy( target ); 31120 31121 tooltipData.hiding = true; 31122 tooltip.stop( true ); 31123 this._hide( tooltip, this.options.hide, function() { 31124 that._removeTooltip( $( this ) ); 31125 } ); 31126 31127 target.removeData( "ui-tooltip-open" ); 31128 this._off( target, "mouseleave focusout keyup" ); 31129 31130 // Remove 'remove' binding only on delegated targets 31131 if ( target[ 0 ] !== this.element[ 0 ] ) { 31132 this._off( target, "remove" ); 31133 } 31134 this._off( this.document, "mousemove" ); 31135 31136 if ( event && event.type === "mouseleave" ) { 31137 $.each( this.parents, function( id, parent ) { 31138 $( parent.element ).attr( "title", parent.title ); 31139 delete that.parents[ id ]; 31140 } ); 31141 } 31142 31143 tooltipData.closing = true; 31144 this._trigger( "close", event, { tooltip: tooltip } ); 31145 if ( !tooltipData.hiding ) { 31146 tooltipData.closing = false; 31147 } 31148 }, 31149 31150 _tooltip: function( element ) { 31151 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 31152 content = $( "<div>" ).appendTo( tooltip ), 31153 id = tooltip.uniqueId().attr( "id" ); 31154 31155 this._addClass( content, "ui-tooltip-content" ); 31156 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 31157 31158 tooltip.appendTo( this._appendTo( element ) ); 31159 31160 return this.tooltips[ id ] = { 31161 element: element, 31162 tooltip: tooltip 31163 }; 31164 }, 31165 31166 _find: function( target ) { 31167 var id = target.data( "ui-tooltip-id" ); 31168 return id ? this.tooltips[ id ] : null; 31169 }, 31170 31171 _removeTooltip: function( tooltip ) { 31172 31173 // Clear the interval for delayed tracking tooltips 31174 clearInterval( this.delayedShow ); 31175 31176 tooltip.remove(); 31177 delete this.tooltips[ tooltip.attr( "id" ) ]; 31178 }, 31179 31180 _appendTo: function( target ) { 31181 var element = target.closest( ".ui-front, dialog" ); 31182 31183 if ( !element.length ) { 31184 element = this.document[ 0 ].body; 31185 } 31186 31187 return element; 31188 }, 31189 31190 _destroy: function() { 31191 var that = this; 31192 31193 // Close open tooltips 31194 $.each( this.tooltips, function( id, tooltipData ) { 31195 31196 // Delegate to close method to handle common cleanup 31197 var event = $.Event( "blur" ), 31198 element = tooltipData.element; 31199 event.target = event.currentTarget = element[ 0 ]; 31200 that.close( event, true ); 31201 31202 // Remove immediately; destroying an open tooltip doesn't use the 31203 // hide animation 31204 $( "#" + id ).remove(); 31205 31206 // Restore the title 31207 if ( element.data( "ui-tooltip-title" ) ) { 31208 31209 // If the title attribute has changed since open(), don't restore 31210 if ( !element.attr( "title" ) ) { 31211 element.attr( "title", element.data( "ui-tooltip-title" ) ); 31212 } 31213 element.removeData( "ui-tooltip-title" ); 31214 } 31215 } ); 31216 this.liveRegion.remove(); 31217 } 31218} ); 31219 31220// DEPRECATED 31221// TODO: Switch return back to widget declaration at top of file when this is removed 31222if ( $.uiBackCompat !== false ) { 31223 31224 // Backcompat for tooltipClass option 31225 $.widget( "ui.tooltip", $.ui.tooltip, { 31226 options: { 31227 tooltipClass: null 31228 }, 31229 _tooltip: function() { 31230 var tooltipData = this._superApply( arguments ); 31231 if ( this.options.tooltipClass ) { 31232 tooltipData.tooltip.addClass( this.options.tooltipClass ); 31233 } 31234 return tooltipData; 31235 } 31236 } ); 31237} 31238 31239return $.ui.tooltip; 31240 31241} ); 31242 31243 31244 31245 31246 31247 31248 31249 31250 31251 31252 31253 31254 31255 31256 31257 31258 31259 31260 31261 31262 31263 31264 31265 31266 31267 31268 31269 31270 31271 31272 31273 31274 31275 31276 31277 31278 31279 31280 31281 31282 31283 31284 31285 31286 31287 31288 31289 31290 31291 31292 31293 31294 31295 31296 31297 31298 31299/* jshint node: true */ 31300 31301/** 31302 * Unobtrusive scripting adapter for jQuery 31303 * https://github.com/rails/jquery-ujs 31304 * 31305 * Requires jQuery 1.8.0 or later. 31306 * 31307 * Released under the MIT license 31308 * 31309 */ 31310 31311 31312(function() { 31313 'use strict'; 31314 31315 var jqueryUjsInit = function($, undefined) { 31316 31317 // Cut down on the number of issues from people inadvertently including jquery_ujs twice 31318 // by detecting and raising an error when it happens. 31319 if ( $.rails !== undefined ) { 31320 $.error('jquery-ujs has already been loaded!'); 31321 } 31322 31323 // Shorthand to make it a little easier to call public rails functions from within rails.js 31324 var rails; 31325 var $document = $(document); 31326 31327 $.rails = rails = { 31328 // Link elements bound by jquery-ujs 31329 linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]', 31330 31331 // Button elements bound by jquery-ujs 31332 buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)', 31333 31334 // Select elements bound by jquery-ujs 31335 inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', 31336 31337 // Form elements bound by jquery-ujs 31338 formSubmitSelector: 'form:not([data-turbo=true])', 31339 31340 // Form input elements bound by jquery-ujs 31341 formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])', 31342 31343 // Form input elements disabled during form submission 31344 disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled', 31345 31346 // Form input elements re-enabled after form submission 31347 enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', 31348 31349 // Form required input elements 31350 requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])', 31351 31352 // Form file input elements 31353 fileInputSelector: 'input[name][type=file]:not([disabled])', 31354 31355 // Link onClick disable selector with possible reenable after remote submission 31356 linkDisableSelector: 'a[data-disable-with], a[data-disable]', 31357 31358 // Button onClick disable selector with possible reenable after remote submission 31359 buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]', 31360 31361 // Up-to-date Cross-Site Request Forgery token 31362 csrfToken: function() { 31363 return $('meta[name=csrf-token]').attr('content'); 31364 }, 31365 31366 // URL param that must contain the CSRF token
31367 csrfParam: function() { 31368 return $('meta[name=csrf-param]').attr('content'); 31369 }, 31370 31371 // Make sure that every Ajax request sends the CSRF token 31372 CSRFProtection: function(xhr) { 31373 var token = rails.csrfToken(); 31374 if (token) xhr.setRequestHeader('X-CSRF-Token', token); 31375 }, 31376 31377 // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones) 31378 refreshCSRFTokens: function(){ 31379 $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken()); 31380 }, 31381 31382 // Triggers an event on an element and returns false if the event result is false 31383 fire: function(obj, name, data) { 31384 var event = $.Event(name); 31385 obj.trigger(event, data); 31386 return event.result !== false; 31387 }, 31388 31389 // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm 31390 confirm: function(message) { 31391 return confirm(message); 31392 }, 31393 31394 // Default ajax function, may be overridden with custom function in $.rails.ajax 31395 ajax: function(options) { 31396 return $.ajax(options); 31397 }, 31398 31399 // Default way to get an element's href. May be overridden at $.rails.href. 31400 href: function(element) { 31401 return element[0].href; 31402 }, 31403 31404 // Checks "data-remote" if true to handle the request through a XHR request. 31405 isRemote: function(element) { 31406 return element.data('remote') !== undefined && element.data('remote') !== false; 31407 }, 31408 31409 // Submits "remote" forms and links with ajax 31410 handleRemote: function(element) { 31411 var method, url, data, withCredentials, dataType, options; 31412 31413 if (rails.fire(element, 'ajax:before')) { 31414 withCredentials = element.data('with-credentials') || null; 31415 dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); 31416 31417 if (element.is('form')) { 31418 method = element.data('ujs:submit-button-formmethod') || element.attr('method'); 31419 url = element.data('ujs:submit-button-formaction') || element.attr('action'); 31420 data = $(element[0]).serializeArray(); 31421 // memoized value from clicked submit button 31422 var button = element.data('ujs:submit-button'); 31423 if (button) { 31424 data.push(button); 31425 element.data('ujs:submit-button', null); 31426 } 31427 element.data('ujs:submit-button-formmethod', null); 31428 element.data('ujs:submit-button-formaction', null); 31429 } else if (element.is(rails.inputChangeSelector)) { 31430 method = element.data('method'); 31431 url = element.data('url'); 31432 data = element.serialize(); 31433 if (element.data('params')) data = data + '&' + element.data('params'); 31434 } else if (element.is(rails.buttonClickSelector)) { 31435 method = element.data('method') || 'get'; 31436 url = element.data('url'); 31437 data = element.serialize(); 31438 if (element.data('params')) data = data + '&' + element.data('params'); 31439 } else { 31440 method = element.data('method'); 31441 url = rails.href(element); 31442 data = element.data('params') || null; 31443 } 31444 31445 options = { 31446 type: method || 'GET', data: data, dataType: dataType, 31447 // stopping the "ajax:beforeSend" event will cancel the ajax request 31448 beforeSend: function(xhr, settings) { 31449 if (settings.dataType === undefined) { 31450 xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); 31451 } 31452 if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) { 31453 element.trigger('ajax:send', xhr); 31454 } else { 31455 return false; 31456 } 31457 }, 31458 success: function(data, status, xhr) { 31459 element.trigger('ajax:success', [data, status, xhr]); 31460 }, 31461 complete: function(xhr, status) { 31462 element.trigger('ajax:complete', [xhr, status]); 31463 }, 31464 error: function(xhr, status, error) { 31465 element.trigger('ajax:error', [xhr, status, error]); 31466 }, 31467 crossDomain: rails.isCrossDomain(url) 31468 }; 31469 31470 // There is no withCredentials for IE6-8 when 31471 // "Enable native XMLHTTP support" is disabled 31472 if (withCredentials) { 31473 options.xhrFields = { 31474 withCredentials: withCredentials 31475 }; 31476 } 31477 31478 // Only pass url to `ajax` options if not blank 31479 if (url) { options.url = url; } 31480 31481 return rails.ajax(options); 31482 } else { 31483 return false;
31484 } 31485 }, 31486 31487 // Determines if the request is a cross domain request. 31488 isCrossDomain: function(url) { 31489 var originAnchor = document.createElement('a'); 31490 originAnchor.href = location.href; 31491 var urlAnchor = document.createElement('a'); 31492 31493 try { 31494 urlAnchor.href = url; 31495 // This is a workaround to a IE bug. 31496 urlAnchor.href = urlAnchor.href; 31497 31498 // If URL protocol is false or is a string containing a single colon 31499 // *and* host are false, assume it is not a cross-domain request 31500 // (should only be the case for IE7 and IE compatibility mode). 31501 // Otherwise, evaluate protocol and host of the URL against the origin 31502 // protocol and host. 31503 return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || 31504 (originAnchor.protocol + '//' + originAnchor.host === 31505 urlAnchor.protocol + '//' + urlAnchor.host)); 31506 } catch (e) { 31507 // If there is an error parsing the URL, assume it is crossDomain. 31508 return true; 31509 } 31510 }, 31511 31512 // Handles "data-method" on links such as: 31513 // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> 31514 handleMethod: function(link) { 31515 var href = rails.href(link), 31516 method = link.data('method'), 31517 target = link.attr('target'), 31518 csrfToken = rails.csrfToken(), 31519 csrfParam = rails.csrfParam(), 31520 form = $('<form method="post" action="' + href + '"></form>'), 31521 metadataInput = '<input name="_method" value="' + method + '" type="hidden" />'; 31522 31523 if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) { 31524 metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />'; 31525 } 31526 31527 if (target) { form.attr('target', target); } 31528 31529 form.hide().append(metadataInput).appendTo('body'); 31530 form.submit(); 31531 }, 31532 31533 // Helper function that returns form elements that match the specified CSS selector 31534 // If form is actually a "form" element this will return associated elements outside the from that have 31535 // the html form attribute set 31536 formElements: function(form, selector) { 31537 return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector); 31538 }, 31539 31540 /* Disables form elements: 31541 - Caches element value in 'ujs:enable-with' data store 31542 - Replaces element text with value of 'data-disable-with' attribute 31543 - Sets disabled property to true 31544 */ 31545 disableFormElements: function(form) { 31546 rails.formElements(form, rails.disableSelector).each(function() { 31547 rails.disableFormElement($(this)); 31548 }); 31549 }, 31550 31551 disableFormElement: function(element) { 31552 var method, replacement; 31553 31554 method = element.is('button') ? 'html' : 'val'; 31555 replacement = element.data('disable-with'); 31556 31557 if (replacement !== undefined) { 31558 element.data('ujs:enable-with', element[method]()); 31559 element[method](replacement); 31560 } 31561 31562 element.prop('disabled', true); 31563 element.data('ujs:disabled', true); 31564 }, 31565 31566 /* Re-enables disabled form elements: 31567 - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) 31568 - Sets disabled property to false 31569 */ 31570 enableFormElements: function(form) { 31571 rails.formElements(form, rails.enableSelector).each(function() { 31572 rails.enableFormElement($(this)); 31573 }); 31574 }, 31575 31576 enableFormElement: function(element) { 31577 var method = element.is('button') ? 'html' : 'val'; 31578 if (element.data('ujs:enable-with') !== undefined) { 31579 element[method](element.data('ujs:enable-with')); 31580 element.removeData('ujs:enable-with'); // clean up cache 31581 } 31582 element.prop('disabled', false); 31583 element.removeData('ujs:disabled'); 31584 }, 31585 31586 /* For 'data-confirm' attribute: 31587 - Fires `confirm` event 31588 - Shows the confirmation dialog 31589 - Fires the `confirm:complete` event 31590 31591 Returns `true` if no function stops the chain and user chose yes; `false` otherwise. 31592 Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. 31593 Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
31594 return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. 31595 */ 31596 allowAction: function(element) { 31597 var message = element.data('confirm'), 31598 answer = false, callback; 31599 if (!message) { return true; } 31600 31601 if (rails.fire(element, 'confirm')) { 31602 try { 31603 answer = rails.confirm(message); 31604 } catch (e) { 31605 (console.error || console.log).call(console, e.stack || e); 31606 } 31607 callback = rails.fire(element, 'confirm:complete', [answer]); 31608 } 31609 return answer && callback; 31610 }, 31611 31612 // Helper function which checks for blank inputs in a form that match the specified CSS selector 31613 blankInputs: function(form, specifiedSelector, nonBlank) { 31614 var foundInputs = $(), 31615 input, 31616 valueToCheck, 31617 radiosForNameWithNoneSelected, 31618 radioName, 31619 selector = specifiedSelector || 'input,textarea', 31620 requiredInputs = form.find(selector), 31621 checkedRadioButtonNames = {}; 31622 31623 requiredInputs.each(function() { 31624 input = $(this); 31625 if (input.is('input[type=radio]')) { 31626 31627 // Don't count unchecked required radio as blank if other radio with same name is checked, 31628 // regardless of whether same-name radio input has required attribute or not. The spec 31629 // states https://www.w3.org/TR/html5/forms.html#the-required-attribute 31630 radioName = input.attr('name'); 31631 31632 // Skip if we've already seen the radio with this name. 31633 if (!checkedRadioButtonNames[radioName]) { 31634 31635 // If none checked 31636 if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) { 31637 radiosForNameWithNoneSelected = form.find( 31638 'input[type=radio][name="' + radioName + '"]'); 31639 foundInputs = foundInputs.add(radiosForNameWithNoneSelected); 31640 } 31641 31642 // We only need to check each name once. 31643 checkedRadioButtonNames[radioName] = radioName; 31644 } 31645 } else { 31646 valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val(); 31647 if (valueToCheck === nonBlank) { 31648 foundInputs = foundInputs.add(input); 31649 } 31650 } 31651 }); 31652 return foundInputs.length ? foundInputs : false; 31653 }, 31654 31655 // Helper function which checks for non-blank inputs in a form that match the specified CSS selector 31656 nonBlankInputs: function(form, specifiedSelector) { 31657 return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank 31658 }, 31659 31660 // Helper function, needed to provide consistent behavior in IE 31661 stopEverything: function(e) { 31662 $(e.target).trigger('ujs:everythingStopped'); 31663 e.stopImmediatePropagation(); 31664 return false; 31665 }, 31666 31667 // Replace element's html with the 'data-disable-with' after storing original html 31668 // and prevent clicking on it 31669 disableElement: function(element) { 31670 var replacement = element.data('disable-with'); 31671 31672 if (replacement !== undefined) { 31673 element.data('ujs:enable-with', element.html()); // store enabled state 31674 element.html(replacement); 31675 } 31676 31677 element.on('click.railsDisable', function(e) { // prevent further clicking 31678 return rails.stopEverything(e); 31679 }); 31680 element.data('ujs:disabled', true); 31681 }, 31682 31683 // Restore element to its original state which was disabled by 'disableElement' above 31684 enableElement: function(element) { 31685 if (element.data('ujs:enable-with') !== undefined) { 31686 element.html(element.data('ujs:enable-with')); // set to old enabled state 31687 element.removeData('ujs:enable-with'); // clean up cache 31688 } 31689 element.off('click.railsDisable'); // enable element 31690 element.removeData('ujs:disabled'); 31691 } 31692 }; 31693 31694 if (rails.fire($document, 'rails:attachBindings')) { 31695 31696 $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); 31697 31698 // This event works the same as the load event, except that it fires every 31699 // time the page is loaded. 31700 // 31701 // See https://github.com/rails/jquery-ujs/issues/357 31702 // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching 31703 $(window).on('pageshow.rails', function () { 31704 $($.rails.enableSelector).each(function () { 31705 var element = $(this); 31706 31707 if (element.data('ujs:disabled')) { 31708 $.rails.enableFormElement(element); 31709 } 31710 }); 31711 31712 $($.rails.linkDisableSelector).each(function () { 31713 var element = $(this); 31714 31715 if (element.data('ujs:disabled')) { 31716 $.rails.enableElement(element); 31717 } 31718 }); 31719 }); 31720 31721 $document.on('ajax:complete', rails.linkDisableSelector, function() { 31722 rails.enableElement($(this)); 31723 }); 31724 31725 $document.on('ajax:complete', rails.buttonDisableSelector, function() { 31726 rails.enableFormElement($(this)); 31727 }); 31728 31729 $document.on('click.rails', rails.linkClickSelector, function(e) { 31730 var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey; 31731 if (!rails.allowAction(link)) return rails.stopEverything(e); 31732 31733 if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link); 31734 31735 if (rails.isRemote(link)) { 31736 if (metaClick && (!method || method === 'GET') && !data) { return true; } 31737 31738 var handleRemote = rails.handleRemote(link); 31739 // Response from rails.handleRemote() will either be false or a deferred object promise. 31740 if (handleRemote === false) { 31741 rails.enableElement(link); 31742 } else { 31743 handleRemote.fail( function() { rails.enableElement(link); } ); 31744 } 31745 return false;
31746 31747 } else if (method) { 31748 rails.handleMethod(link); 31749 return false; 31750 } 31751 }); 31752 31753 $document.on('click.rails', rails.buttonClickSelector, function(e) { 31754 var button = $(this); 31755 31756 if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e); 31757 31758 if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button); 31759 31760 var handleRemote = rails.handleRemote(button); 31761 // Response from rails.handleRemote() will either be false or a deferred object promise. 31762 if (handleRemote === false) { 31763 rails.enableFormElement(button); 31764 } else { 31765 handleRemote.fail( function() { rails.enableFormElement(button); } ); 31766 } 31767 return false; 31768 }); 31769 31770 $document.on('change.rails', rails.inputChangeSelector, function(e) { 31771 var link = $(this); 31772 if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e); 31773 31774 rails.handleRemote(link); 31775 return false; 31776 }); 31777 31778 $document.on('submit.rails', rails.formSubmitSelector, function(e) { 31779 var form = $(this), 31780 remote = rails.isRemote(form), 31781 blankRequiredInputs, 31782 nonBlankFileInputs; 31783 31784 if (!rails.allowAction(form)) return rails.stopEverything(e); 31785 31786 // Skip other logic when required values are missing or file upload is present 31787 if (form.attr('novalidate') === undefined) { 31788 if (form.data('ujs:formnovalidate-button') === undefined) { 31789 blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); 31790 if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { 31791 return rails.stopEverything(e); 31792 } 31793 } else { 31794 // Clear the formnovalidate in case the next button click is not on a formnovalidate button 31795 // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain 31796 form.data('ujs:formnovalidate-button', undefined); 31797 } 31798 } 31799 31800 if (remote) { 31801 nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); 31802 if (nonBlankFileInputs) { 31803 // Slight timeout so that the submit button gets properly serialized 31804 // (make it easy for event handler to serialize form without disabled values) 31805 setTimeout(function(){ rails.disableFormElements(form); }, 13); 31806 var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); 31807 31808 // Re-enable form elements if event bindings return false (canceling normal form submission) 31809 if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } 31810 31811 return aborted; 31812 } 31813 31814 rails.handleRemote(form); 31815 return false; 31816 31817 } else { 31818 // Slight timeout so that the submit button gets properly serialized 31819 setTimeout(function(){ rails.disableFormElements(form); }, 13); 31820 } 31821 }); 31822 31823 $document.on('click.rails', rails.formInputClickSelector, function(event) { 31824 var button = $(this); 31825 31826 if (!rails.allowAction(button)) return rails.stopEverything(event); 31827 31828 // Register the pressed submit button 31829 var name = button.attr('name'), 31830 data = name ? {name:name, value:button.val()} : null; 31831 31832 var form = button.closest('form'); 31833 if (form.length === 0) { 31834 form = $('#' + button.attr('form')); 31835 } 31836 form.data('ujs:submit-button', data); 31837 31838 // Save attributes from button 31839 form.data('ujs:formnovalidate-button', button.attr('formnovalidate')); 31840 form.data('ujs:submit-button-formaction', button.attr('formaction')); 31841 form.data('ujs:submit-button-formmethod', button.attr('formmethod')); 31842 }); 31843 31844 $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) { 31845 if (this === event.target) rails.disableFormElements($(this)); 31846 }); 31847 31848 $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) { 31849 if (this === event.target) rails.enableFormElements($(this)); 31850 }); 31851 31852 $(function(){ 31853 rails.refreshCSRFTokens(); 31854 }); 31855 } 31856 31857 }; 31858 31859 if (window.jQuery) { 31860 jqueryUjsInit(jQuery); 31861 } else if (typeof exports === 'object' && typeof module === 'object') { 31862 module.exports = jqueryUjsInit; 31863 } 31864})(); 31865/*! 31866 * jQuery Validation Plugin v1.19.0 31867 * 31868 * https://jqueryvalidation.org/ 31869 * 31870 * Copyright (c) 2018 Jörn Zaefferer 31871 * Released under the MIT license 31872 */ 31873 31874(function( factory ) { 31875 if ( typeof define === "function" && define.amd ) { 31876 define( ["jquery"], factory ); 31877 } else if (typeof module === "object" && module.exports) { 31878 module.exports = factory( require( "jquery" ) ); 31879 } else { 31880 factory( jQuery ); 31881 } 31882}(function( $ ) { 31883 31884$.extend( $.fn, { 31885 31886 // https://jqueryvalidation.org/validate/ 31887 validate: function( options ) { 31888 31889 // If nothing is selected, return nothing; can't chain anyway 31890 if ( !this.length ) { 31891 if ( options && options.debug && window.console ) { 31892 console.warn( "Nothing selected, can't validate, returning nothing." ); 31893 } 31894 return; 31895 } 31896 31897 // Check if a validator for this form was already created
vendor: 26,206 bytes, lines 31898-32777
31898 var validator = $.data( this[ 0 ], "validator" ); 31899 if ( validator ) { 31900 return validator; 31901 } 31902 31903 // Add novalidate tag if HTML5. 31904 this.attr( "novalidate", "novalidate" ); 31905 31906 validator = new $.validator( options, this[ 0 ] ); 31907 $.data( this[ 0 ], "validator", validator ); 31908 31909 if ( validator.settings.onsubmit ) { 31910 31911 this.on( "click.validate", ":submit", function( event ) { 31912 31913 // Track the used submit button to properly handle scripted 31914 // submits later. 31915 validator.submitButton = event.currentTarget; 31916 31917 // Allow suppressing validation by adding a cancel class to the submit button 31918 if ( $( this ).hasClass( "cancel" ) ) { 31919 validator.cancelSubmit = true; 31920 } 31921 31922 // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 31923 if ( $( this ).attr( "formnovalidate" ) !== undefined ) { 31924 validator.cancelSubmit = true; 31925 } 31926 } ); 31927 31928 // Validate the form on submit 31929 this.on( "submit.validate", function( event ) { 31930 if ( validator.settings.debug ) { 31931 31932 // Prevent form submit to be able to see console output 31933 event.preventDefault(); 31934 } 31935 31936 function handle() { 31937 var hidden, result; 31938 31939 // Insert a hidden input as a replacement for the missing submit button 31940 // The hidden input is inserted in two cases: 31941 // - A user defined a `submitHandler` 31942 // - There was a pending request due to `remote` method and `stopRequest()` 31943 // was called to submit the form in case it's valid 31944 if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) { 31945 hidden = $( "<input type='hidden'/>" ) 31946 .attr( "name", validator.submitButton.name ) 31947 .val( $( validator.submitButton ).val() ) 31948 .appendTo( validator.currentForm ); 31949 } 31950 31951 if ( validator.settings.submitHandler && !validator.settings.debug ) { 31952 result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); 31953 if ( hidden ) { 31954 31955 // And clean up afterwards; thanks to no-block-scope, hidden can be referenced 31956 hidden.remove(); 31957 } 31958 if ( result !== undefined ) { 31959 return result; 31960 } 31961 return false; 31962 } 31963 return true; 31964 } 31965 31966 // Prevent submit for invalid forms or custom submit handlers 31967 if ( validator.cancelSubmit ) { 31968 validator.cancelSubmit = false; 31969 return handle(); 31970 } 31971 if ( validator.form() ) { 31972 if ( validator.pendingRequest ) { 31973 validator.formSubmitted = true; 31974 return false; 31975 } 31976 return handle(); 31977 } else { 31978 validator.focusInvalid(); 31979 return false; 31980 } 31981 } ); 31982 } 31983 31984 return validator; 31985 }, 31986 31987 // https://jqueryvalidation.org/valid/ 31988 valid: function() { 31989 var valid, validator, errorList; 31990 31991 if ( $( this[ 0 ] ).is( "form" ) ) { 31992 valid = this.validate().form(); 31993 } else { 31994 errorList = []; 31995 valid = true; 31996 validator = $( this[ 0 ].form ).validate(); 31997 this.each( function() { 31998 valid = validator.element( this ) && valid; 31999 if ( !valid ) { 32000 errorList = errorList.concat( validator.errorList ); 32001 } 32002 } ); 32003 validator.errorList = errorList; 32004 } 32005 return valid; 32006 }, 32007 32008 // https://jqueryvalidation.org/rules/ 32009 rules: function( command, argument ) { 32010 var element = this[ 0 ], 32011 isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false", 32012 settings, staticRules, existingRules, data, param, filtered; 32013 32014 // If nothing is selected, return empty object; can't chain anyway 32015 if ( element == null ) { 32016 return; 32017 } 32018 32019 if ( !element.form && isContentEditable ) { 32020 element.form = this.closest( "form" )[ 0 ]; 32021 element.name = this.attr( "name" ); 32022 } 32023 32024 if ( element.form == null ) { 32025 return; 32026 } 32027 32028 if ( command ) { 32029 settings = $.data( element.form, "validator" ).settings; 32030 staticRules = settings.rules; 32031 existingRules = $.validator.staticRules( element ); 32032 switch ( command ) { 32033 case "add": 32034 $.extend( existingRules, $.validator.normalizeRule( argument ) ); 32035 32036 // Remove messages from rules, but allow them to be set separately 32037 delete existingRules.messages; 32038 staticRules[ element.name ] = existingRules; 32039 if ( argument.messages ) { 32040 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); 32041 } 32042 break; 32043 case "remove": 32044 if ( !argument ) { 32045 delete staticRules[ element.name ]; 32046 return existingRules; 32047 } 32048 filtered = {}; 32049 $.each( argument.split( /\s/ ), function( index, method ) { 32050 filtered[ method ] = existingRules[ method ]; 32051 delete existingRules[ method ]; 32052 } ); 32053 return filtered; 32054 } 32055 } 32056 32057 data = $.validator.normalizeRules( 32058 $.extend( 32059 {}, 32060 $.validator.classRules( element ), 32061 $.validator.attributeRules( element ), 32062 $.validator.dataRules( element ), 32063 $.validator.staticRules( element ) 32064 ), element ); 32065 32066 // Make sure required is at front 32067 if ( data.required ) { 32068 param = data.required; 32069 delete data.required; 32070 data = $.extend( { required: param }, data ); 32071 } 32072 32073 // Make sure remote is at back 32074 if ( data.remote ) { 32075 param = data.remote; 32076 delete data.remote; 32077 data = $.extend( data, { remote: param } ); 32078 } 32079 32080 return data; 32081 } 32082} ); 32083 32084// Custom selectors 32085$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support 32086 32087 // https://jqueryvalidation.org/blank-selector/ 32088 blank: function( a ) { 32089 return !$.trim( "" + $( a ).val() ); 32090 }, 32091 32092 // https://jqueryvalidation.org/filled-selector/ 32093 filled: function( a ) { 32094 var val = $( a ).val(); 32095 return val !== null && !!$.trim( "" + val ); 32096 }, 32097 32098 // https://jqueryvalidation.org/unchecked-selector/ 32099 unchecked: function( a ) { 32100 return !$( a ).prop( "checked" ); 32101 } 32102} ); 32103 32104// Constructor for validator 32105$.validator = function( options, form ) { 32106 this.settings = $.extend( true, {}, $.validator.defaults, options ); 32107 this.currentForm = form; 32108 this.init(); 32109}; 32110 32111// https://jqueryvalidation.org/jQuery.validator.format/ 32112$.validator.format = function( source, params ) { 32113 if ( arguments.length === 1 ) { 32114 return function() { 32115 var args = $.makeArray( arguments ); 32116 args.unshift( source ); 32117 return $.validator.format.apply( this, args ); 32118 }; 32119 } 32120 if ( params === undefined ) { 32121 return source; 32122 } 32123 if ( arguments.length > 2 && params.constructor !== Array ) { 32124 params = $.makeArray( arguments ).slice( 1 ); 32125 } 32126 if ( params.constructor !== Array ) { 32127 params = [ params ]; 32128 } 32129 $.each( params, function( i, n ) { 32130 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { 32131 return n; 32132 } ); 32133 } ); 32134 return source; 32135}; 32136 32137$.extend( $.validator, { 32138 32139 defaults: { 32140 messages: {}, 32141 groups: {}, 32142 rules: {}, 32143 errorClass: "error", 32144 pendingClass: "pending", 32145 validClass: "valid", 32146 errorElement: "label", 32147 focusCleanup: false, 32148 focusInvalid: true, 32149 errorContainer: $( [] ), 32150 errorLabelContainer: $( [] ), 32151 onsubmit: true, 32152 ignore: ":hidden", 32153 ignoreTitle: false, 32154 onfocusin: function( element ) { 32155 this.lastActive = element; 32156 32157 // Hide error label and remove error class on focus if enabled 32158 if ( this.settings.focusCleanup ) { 32159 if ( this.settings.unhighlight ) { 32160 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 32161 } 32162 this.hideThese( this.errorsFor( element ) ); 32163 } 32164 }, 32165 onfocusout: function( element ) { 32166 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { 32167 this.element( element ); 32168 } 32169 }, 32170 onkeyup: function( element, event ) { 32171 32172 // Avoid revalidate the field when pressing one of the following keys 32173 // Shift => 16 32174 // Ctrl => 17 32175 // Alt => 18 32176 // Caps lock => 20 32177 // End => 35 32178 // Home => 36 32179 // Left arrow => 37 32180 // Up arrow => 38 32181 // Right arrow => 39 32182 // Down arrow => 40 32183 // Insert => 45 32184 // Num lock => 144 32185 // AltGr key => 225 32186 var excludedKeys = [ 32187 16, 17, 18, 20, 35, 36, 37, 32188 38, 39, 40, 45, 144, 225 32189 ]; 32190 32191 if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { 32192 return; 32193 } else if ( element.name in this.submitted || element.name in this.invalid ) { 32194 this.element( element ); 32195 } 32196 }, 32197 onclick: function( element ) { 32198 32199 // Click on selects, radiobuttons and checkboxes 32200 if ( element.name in this.submitted ) { 32201 this.element( element ); 32202 32203 // Or option elements, check parent select in that case 32204 } else if ( element.parentNode.name in this.submitted ) { 32205 this.element( element.parentNode ); 32206 } 32207 }, 32208 highlight: function( element, errorClass, validClass ) { 32209 if ( element.type === "radio" ) { 32210 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); 32211 } else { 32212 $( element ).addClass( errorClass ).removeClass( validClass ); 32213 } 32214 }, 32215 unhighlight: function( element, errorClass, validClass ) { 32216 if ( element.type === "radio" ) { 32217 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); 32218 } else { 32219 $( element ).removeClass( errorClass ).addClass( validClass ); 32220 } 32221 } 32222 }, 32223 32224 // https://jqueryvalidation.org/jQuery.validator.setDefaults/ 32225 setDefaults: function( settings ) { 32226 $.extend( $.validator.defaults, settings ); 32227 }, 32228 32229 messages: { 32230 required: "This field is required.", 32231 remote: "Please fix this field.", 32232 email: "Please enter a valid email address.", 32233 url: "Please enter a valid URL.", 32234 date: "Please enter a valid date.", 32235 dateISO: "Please enter a valid date (ISO).", 32236 number: "Please enter a valid number.", 32237 digits: "Please enter only digits.", 32238 equalTo: "Please enter the same value again.", 32239 maxlength: $.validator.format( "Please enter no more than {0} characters." ), 32240 minlength: $.validator.format( "Please enter at least {0} characters." ), 32241 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), 32242 range: $.validator.format( "Please enter a value between {0} and {1}." ), 32243 max: $.validator.format( "Please enter a value less than or equal to {0}." ), 32244 min: $.validator.format( "Please enter a value greater than or equal to {0}." ), 32245 step: $.validator.format( "Please enter a multiple of {0}." ) 32246 }, 32247 32248 autoCreateRanges: false, 32249 32250 prototype: { 32251 32252 init: function() { 32253 this.labelContainer = $( this.settings.errorLabelContainer ); 32254 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); 32255 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); 32256 this.submitted = {}; 32257 this.valueCache = {}; 32258 this.pendingRequest = 0; 32259 this.pending = {}; 32260 this.invalid = {}; 32261 this.reset(); 32262 32263 var currentForm = this.currentForm, 32264 groups = ( this.groups = {} ), 32265 rules; 32266 $.each( this.settings.groups, function( key, value ) { 32267 if ( typeof value === "string" ) { 32268 value = value.split( /\s/ ); 32269 } 32270 $.each( value, function( index, name ) { 32271 groups[ name ] = key; 32272 } ); 32273 } ); 32274 rules = this.settings.rules; 32275 $.each( rules, function( key, value ) { 32276 rules[ key ] = $.validator.normalizeRule( value ); 32277 } ); 32278 32279 function delegate( event ) { 32280 var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; 32281 32282 // Set form expando on contenteditable 32283 if ( !this.form && isContentEditable ) { 32284 this.form = $( this ).closest( "form" )[ 0 ]; 32285 this.name = $( this ).attr( "name" ); 32286 } 32287 32288 // Ignore the element if it belongs to another form. This will happen mainly 32289 // when setting the `form` attribute of an input to the id of another form. 32290 if ( currentForm !== this.form ) { 32291 return; 32292 } 32293 32294 var validator = $.data( this.form, "validator" ), 32295 eventType = "on" + event.type.replace( /^validate/, "" ), 32296 settings = validator.settings; 32297 if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) { 32298 settings[ eventType ].call( validator, this, event ); 32299 } 32300 } 32301 32302 $( this.currentForm ) 32303 .on( "focusin.validate focusout.validate keyup.validate", 32304 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + 32305 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + 32306 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + 32307 "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate ) 32308 32309 // Support: Chrome, oldIE 32310 // "select" is provided as event.target when clicking a option 32311 .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate ); 32312 32313 if ( this.settings.invalidHandler ) { 32314 $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler ); 32315 } 32316 }, 32317 32318 // https://jqueryvalidation.org/Validator.form/ 32319 form: function() { 32320 this.checkForm(); 32321 $.extend( this.submitted, this.errorMap ); 32322 this.invalid = $.extend( {}, this.errorMap ); 32323 if ( !this.valid() ) { 32324 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); 32325 } 32326 this.showErrors(); 32327 return this.valid(); 32328 }, 32329 32330 checkForm: function() { 32331 this.prepareForm(); 32332 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { 32333 this.check( elements[ i ] ); 32334 } 32335 return this.valid(); 32336 }, 32337 32338 // https://jqueryvalidation.org/Validator.element/ 32339 element: function( element ) { 32340 var cleanElement = this.clean( element ), 32341 checkElement = this.validationTargetFor( cleanElement ), 32342 v = this, 32343 result = true, 32344 rs, group; 32345 32346 if ( checkElement === undefined ) { 32347 delete this.invalid[ cleanElement.name ]; 32348 } else { 32349 this.prepareElement( checkElement ); 32350 this.currentElements = $( checkElement ); 32351 32352 // If this element is grouped, then validate all group elements already 32353 // containing a value 32354 group = this.groups[ checkElement.name ]; 32355 if ( group ) { 32356 $.each( this.groups, function( name, testgroup ) { 32357 if ( testgroup === group && name !== checkElement.name ) { 32358 cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) ); 32359 if ( cleanElement && cleanElement.name in v.invalid ) { 32360 v.currentElements.push( cleanElement ); 32361 result = v.check( cleanElement ) && result; 32362 } 32363 } 32364 } ); 32365 } 32366 32367 rs = this.check( checkElement ) !== false; 32368 result = result && rs; 32369 if ( rs ) { 32370 this.invalid[ checkElement.name ] = false; 32371 } else { 32372 this.invalid[ checkElement.name ] = true; 32373 } 32374 32375 if ( !this.numberOfInvalids() ) { 32376 32377 // Hide error containers on last error 32378 this.toHide = this.toHide.add( this.containers ); 32379 } 32380 this.showErrors(); 32381 32382 // Add aria-invalid status for screen readers 32383 $( element ).attr( "aria-invalid", !rs ); 32384 } 32385 32386 return result; 32387 }, 32388 32389 // https://jqueryvalidation.org/Validator.showErrors/ 32390 showErrors: function( errors ) { 32391 if ( errors ) { 32392 var validator = this; 32393 32394 // Add items to error list and map 32395 $.extend( this.errorMap, errors ); 32396 this.errorList = $.map( this.errorMap, function( message, name ) { 32397 return { 32398 message: message, 32399 element: validator.findByName( name )[ 0 ] 32400 }; 32401 } ); 32402 32403 // Remove items from success list 32404 this.successList = $.grep( this.successList, function( element ) { 32405 return !( element.name in errors ); 32406 } ); 32407 } 32408 if ( this.settings.showErrors ) { 32409 this.settings.showErrors.call( this, this.errorMap, this.errorList ); 32410 } else { 32411 this.defaultShowErrors(); 32412 } 32413 }, 32414 32415 // https://jqueryvalidation.org/Validator.resetForm/ 32416 resetForm: function() { 32417 if ( $.fn.resetForm ) { 32418 $( this.currentForm ).resetForm(); 32419 } 32420 this.invalid = {}; 32421 this.submitted = {}; 32422 this.prepareForm(); 32423 this.hideErrors(); 32424 var elements = this.elements() 32425 .removeData( "previousValue" ) 32426 .removeAttr( "aria-invalid" ); 32427 32428 this.resetElements( elements ); 32429 }, 32430 32431 resetElements: function( elements ) { 32432 var i; 32433 32434 if ( this.settings.unhighlight ) { 32435 for ( i = 0; elements[ i ]; i++ ) { 32436 this.settings.unhighlight.call( this, elements[ i ], 32437 this.settings.errorClass, "" ); 32438 this.findByName( elements[ i ].name ).removeClass( this.settings.validClass ); 32439 } 32440 } else { 32441 elements 32442 .removeClass( this.settings.errorClass ) 32443 .removeClass( this.settings.validClass ); 32444 } 32445 }, 32446 32447 numberOfInvalids: function() { 32448 return this.objectLength( this.invalid ); 32449 }, 32450 32451 objectLength: function( obj ) { 32452 /* jshint unused: false */ 32453 var count = 0, 32454 i; 32455 for ( i in obj ) { 32456 32457 // This check allows counting elements with empty error 32458 // message as invalid elements 32459 if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) { 32460 count++; 32461 } 32462 } 32463 return count; 32464 }, 32465 32466 hideErrors: function() { 32467 this.hideThese( this.toHide ); 32468 }, 32469 32470 hideThese: function( errors ) { 32471 errors.not( this.containers ).text( "" ); 32472 this.addWrapper( errors ).hide(); 32473 }, 32474 32475 valid: function() { 32476 return this.size() === 0; 32477 }, 32478 32479 size: function() { 32480 return this.errorList.length; 32481 }, 32482 32483 focusInvalid: function() { 32484 if ( this.settings.focusInvalid ) { 32485 try { 32486 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] ) 32487 .filter( ":visible" ) 32488 .focus() 32489 32490 // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 32491 .trigger( "focusin" ); 32492 } catch ( e ) { 32493 32494 // Ignore IE throwing errors when focusing hidden elements 32495 } 32496 } 32497 }, 32498 32499 findLastActive: function() { 32500 var lastActive = this.lastActive; 32501 return lastActive && $.grep( this.errorList, function( n ) { 32502 return n.element.name === lastActive.name; 32503 } ).length === 1 && lastActive; 32504 }, 32505 32506 elements: function() { 32507 var validator = this, 32508 rulesCache = {}; 32509 32510 // Select all valid inputs inside the form (no submit or reset buttons) 32511 return $( this.currentForm ) 32512 .find( "input, select, textarea, [contenteditable]" ) 32513 .not( ":submit, :reset, :image, :disabled" ) 32514 .not( this.settings.ignore ) 32515 .filter( function() { 32516 var name = this.name || $( this ).attr( "name" ); // For contenteditable 32517 var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; 32518 32519 if ( !name && validator.settings.debug && window.console ) { 32520 console.error( "%o has no name assigned", this ); 32521 } 32522 32523 // Set form expando on contenteditable 32524 if ( isContentEditable ) { 32525 this.form = $( this ).closest( "form" )[ 0 ]; 32526 this.name = name; 32527 } 32528 32529 // Ignore elements that belong to other/nested forms 32530 if ( this.form !== validator.currentForm ) { 32531 return false; 32532 } 32533 32534 // Select only the first element for each name, and only those with rules specified 32535 if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { 32536 return false; 32537 } 32538 32539 rulesCache[ name ] = true; 32540 return true; 32541 } ); 32542 }, 32543 32544 clean: function( selector ) { 32545 return $( selector )[ 0 ]; 32546 }, 32547 32548 errors: function() { 32549 var errorClass = this.settings.errorClass.split( " " ).join( "." ); 32550 return $( this.settings.errorElement + "." + errorClass, this.errorContext ); 32551 }, 32552 32553 resetInternals: function() { 32554 this.successList = []; 32555 this.errorList = []; 32556 this.errorMap = {}; 32557 this.toShow = $( [] ); 32558 this.toHide = $( [] ); 32559 }, 32560 32561 reset: function() { 32562 this.resetInternals(); 32563 this.currentElements = $( [] ); 32564 }, 32565 32566 prepareForm: function() { 32567 this.reset(); 32568 this.toHide = this.errors().add( this.containers ); 32569 }, 32570 32571 prepareElement: function( element ) { 32572 this.reset(); 32573 this.toHide = this.errorsFor( element ); 32574 }, 32575 32576 elementValue: function( element ) { 32577 var $element = $( element ), 32578 type = element.type, 32579 isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false", 32580 val, idx; 32581 32582 if ( type === "radio" || type === "checkbox" ) { 32583 return this.findByName( element.name ).filter( ":checked" ).val(); 32584 } else if ( type === "number" && typeof element.validity !== "undefined" ) { 32585 return element.validity.badInput ? "NaN" : $element.val(); 32586 } 32587 32588 if ( isContentEditable ) { 32589 val = $element.text(); 32590 } else { 32591 val = $element.val(); 32592 } 32593 32594 if ( type === "file" ) { 32595 32596 // Modern browser (chrome & safari) 32597 if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) { 32598 return val.substr( 12 ); 32599 } 32600 32601 // Legacy browsers 32602 // Unix-based path 32603 idx = val.lastIndexOf( "/" ); 32604 if ( idx >= 0 ) { 32605 return val.substr( idx + 1 ); 32606 } 32607 32608 // Windows-based path 32609 idx = val.lastIndexOf( "\\" ); 32610 if ( idx >= 0 ) { 32611 return val.substr( idx + 1 ); 32612 } 32613 32614 // Just the file name 32615 return val; 32616 } 32617 32618 if ( typeof val === "string" ) { 32619 return val.replace( /\r/g, "" ); 32620 } 32621 return val; 32622 }, 32623 32624 check: function( element ) { 32625 element = this.validationTargetFor( this.clean( element ) ); 32626 32627 var rules = $( element ).rules(), 32628 rulesCount = $.map( rules, function( n, i ) { 32629 return i; 32630 } ).length, 32631 dependencyMismatch = false, 32632 val = this.elementValue( element ), 32633 result, method, rule, normalizer; 32634 32635 // Prioritize the local normalizer defined for this element over the global one 32636 // if the former exists, otherwise user the global one in case it exists. 32637 if ( typeof rules.normalizer === "function" ) { 32638 normalizer = rules.normalizer; 32639 } else if ( typeof this.settings.normalizer === "function" ) { 32640 normalizer = this.settings.normalizer; 32641 } 32642 32643 // If normalizer is defined, then call it to retreive the changed value instead 32644 // of using the real one. 32645 // Note that `this` in the normalizer is `element`. 32646 if ( normalizer ) { 32647 val = normalizer.call( element, val ); 32648 32649 // Delete the normalizer from rules to avoid treating it as a pre-defined method. 32650 delete rules.normalizer; 32651 } 32652 32653 for ( method in rules ) { 32654 rule = { method: method, parameters: rules[ method ] }; 32655 try { 32656 result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); 32657 32658 // If a method indicates that the field is optional and therefore valid, 32659 // don't mark it as valid when there are no other rules 32660 if ( result === "dependency-mismatch" && rulesCount === 1 ) { 32661 dependencyMismatch = true; 32662 continue; 32663 } 32664 dependencyMismatch = false; 32665 32666 if ( result === "pending" ) { 32667 this.toHide = this.toHide.not( this.errorsFor( element ) ); 32668 return; 32669 } 32670 32671 if ( !result ) { 32672 this.formatAndAdd( element, rule ); 32673 return false; 32674 } 32675 } catch ( e ) { 32676 if ( this.settings.debug && window.console ) { 32677 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 32678 } 32679 if ( e instanceof TypeError ) { 32680 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; 32681 } 32682 32683 throw e; 32684 } 32685 } 32686 if ( dependencyMismatch ) { 32687 return; 32688 } 32689 if ( this.objectLength( rules ) ) { 32690 this.successList.push( element ); 32691 } 32692 return true; 32693 }, 32694 32695 // Return the custom message for the given element and validation method 32696 // specified in the element's HTML5 data attribute 32697 // return the generic message if present and no method specific message is present 32698 customDataMessage: function( element, method ) { 32699 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + 32700 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); 32701 }, 32702 32703 // Return the custom message for the given element name and validation method 32704 customMessage: function( name, method ) { 32705 var m = this.settings.messages[ name ]; 32706 return m && ( m.constructor === String ? m : m[ method ] ); 32707 }, 32708 32709 // Return the first defined argument, allowing empty strings 32710 findDefined: function() { 32711 for ( var i = 0; i < arguments.length; i++ ) { 32712 if ( arguments[ i ] !== undefined ) { 32713 return arguments[ i ]; 32714 } 32715 } 32716 return undefined; 32717 }, 32718 32719 // The second parameter 'rule' used to be a string, and extended to an object literal 32720 // of the following form: 32721 // rule = { 32722 // method: "method name", 32723 // parameters: "the given method parameters" 32724 // } 32725 // 32726 // The old behavior still supported, kept to maintain backward compatibility with 32727 // old code, and will be removed in the next major release. 32728 defaultMessage: function( element, rule ) { 32729 if ( typeof rule === "string" ) { 32730 rule = { method: rule }; 32731 } 32732 32733 var message = this.findDefined( 32734 this.customMessage( element.name, rule.method ), 32735 this.customDataMessage( element, rule.method ), 32736 32737 // 'title' is never undefined, so handle empty string as undefined 32738 !this.settings.ignoreTitle && element.title || undefined, 32739 $.validator.messages[ rule.method ], 32740 "<strong>Warning: No message defined for " + element.name + "</strong>" 32741 ), 32742 theregex = /\$?\{(\d+)\}/g; 32743 if ( typeof message === "function" ) { 32744 message = message.call( this, rule.parameters, element ); 32745 } else if ( theregex.test( message ) ) { 32746 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); 32747 } 32748 32749 return message; 32750 }, 32751 32752 formatAndAdd: function( element, rule ) { 32753 var message = this.defaultMessage( element, rule ); 32754 32755 this.errorList.push( { 32756 message: message, 32757 element: element, 32758 method: rule.method 32759 } ); 32760 32761 this.errorMap[ element.name ] = message; 32762 this.submitted[ element.name ] = message; 32763 }, 32764 32765 addWrapper: function( toToggle ) { 32766 if ( this.settings.wrapper ) { 32767 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 32768 } 32769 return toToggle; 32770 }, 32771 32772 defaultShowErrors: function() { 32773 var i, elements, error; 32774 for ( i = 0; this.errorList[ i ]; i++ ) { 32775 error = this.errorList[ i ]; 32776 if ( this.settings.highlight ) { 32777 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
32777idClass ); 32778 } 32779 this.showLabel( error.element, error.message ); 32780 } 32781 if ( this.errorList.length ) { 32782 this.toShow = this.toShow.add( this.containers ); 32783 } 32784 if ( this.settings.success ) { 32785 for ( i = 0; this.successList[ i ]; i++ ) { 32786 this.showLabel( this.successList[ i ] ); 32787 } 32788 } 32789 if ( this.settings.unhighlight ) { 32790 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { 32791 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); 32792 } 32793 } 32794 this.toHide = this.toHide.not( this.toShow ); 32795 this.hideErrors(); 32796 this.addWrapper( this.toShow ).show(); 32797 }, 32798 32799 validElements: function() { 32800 return this.currentElements.not( this.invalidElements() ); 32801 }, 32802 32803 invalidElements: function() { 32804 return $( this.errorList ).map( function() { 32805 return this.element; 32806 } ); 32807 }, 32808 32809 showLabel: function( element, message ) { 32810 var place, group, errorID, v, 32811 error = this.errorsFor( element ), 32812 elementID = this.idOrName( element ), 32813 describedBy = $( element ).attr( "aria-describedby" ); 32814 32815 if ( error.length ) { 32816 32817 // Refresh error/success class 32818 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 32819 32820 // Replace message on existing label 32821 error.html( message ); 32822 } else { 32823 32824 // Create error element 32825 error = $( "<" + this.settings.errorElement + ">" ) 32826 .attr( "id", elementID + "-error" ) 32827 .addClass( this.settings.errorClass ) 32828 .html( message || "" ); 32829 32830 // Maintain reference to the element to be placed into the DOM 32831 place = error; 32832 if ( this.settings.wrapper ) { 32833 32834 // Make sure the element is visible, even in IE 32835 // actually showing the wrapped element is handled elsewhere 32836 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); 32837 } 32838 if ( this.labelContainer.length ) { 32839 this.labelContainer.append( place ); 32840 } else if ( this.settings.errorPlacement ) { 32841 this.settings.errorPlacement.call( this, place, $( element ) ); 32842 } else { 32843 place.insertAfter( element ); 32844 } 32845 32846 // Link error back to the element 32847 if ( error.is( "label" ) ) { 32848 32849 // If the error is a label, then associate using 'for' 32850 error.attr( "for", elementID ); 32851 32852 // If the element is not a child of an associated label, then it's necessary 32853 // to explicitly apply aria-describedby 32854 } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) { 32855 errorID = error.attr( "id" ); 32856 32857 // Respect existing non-error aria-describedby 32858 if ( !describedBy ) { 32859 describedBy = errorID; 32860 } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) { 32861 32862 // Add to end of list if not already present 32863 describedBy += " " + errorID; 32864 } 32865 $( element ).attr( "aria-describedby", describedBy ); 32866 32867 // If this element is grouped, then assign to all elements in the same group 32868 group = this.groups[ element.name ]; 32869 if ( group ) { 32870 v = this; 32871 $.each( v.groups, function( name, testgroup ) { 32872 if ( testgroup === group ) { 32873 $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm ) 32874 .attr( "aria-describedby", error.attr( "id" ) ); 32875 } 32876 } ); 32877 } 32878 } 32879 } 32880 if ( !message && this.settings.success ) { 32881 error.text( "" ); 32882 if ( typeof this.settings.success === "string" ) { 32883 error.addClass( this.settings.success ); 32884 } else { 32885 this.settings.success( error, element ); 32886 } 32887 } 32888 this.toShow = this.toShow.add( error ); 32889 }, 32890 32891 errorsFor: function( element ) { 32892 var name = this.escapeCssMeta( this.idOrName( element ) ), 32893 describer = $( element ).attr( "aria-describedby" ), 32894 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 32895 32896 // 'aria-describedby' should directly reference the error element 32897 if ( describer ) { 32898 selector = selector + ", #" + this.escapeCssMeta( describer ) 32899 .replace( /\s+/g, ", #" ); 32900 } 32901 32902 return this 32903 .errors() 32904 .filter( selector ); 32905 }, 32906 32907 // See https://api.jquery.com/category/selectors/, for CSS 32908 // meta-characters that should be escaped in order to be used with JQuery 32909 // as a literal part of a name/id or any selector. 32910 escapeCssMeta: function( string ) { 32911 return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" ); 32912 }, 32913 32914 idOrName: function( element ) { 32915 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.i
vendor: 15,429 bytes, lines 32915-33396
32915d || element.name ); 32916 }, 32917 32918 validationTargetFor: function( element ) { 32919 32920 // If radio/checkbox, validate first element in group instead 32921 if ( this.checkable( element ) ) { 32922 element = this.findByName( element.name ); 32923 } 32924 32925 // Always apply ignore filter 32926 return $( element ).not( this.settings.ignore )[ 0 ]; 32927 }, 32928 32929 checkable: function( element ) { 32930 return ( /radio|checkbox/i ).test( element.type ); 32931 }, 32932 32933 findByName: function( name ) { 32934 return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" ); 32935 }, 32936 32937 getLength: function( value, element ) { 32938 switch ( element.nodeName.toLowerCase() ) { 32939 case "select": 32940 return $( "option:selected", element ).length; 32941 case "input": 32942 if ( this.checkable( element ) ) { 32943 return this.findByName( element.name ).filter( ":checked" ).length; 32944 } 32945 } 32946 return value.length; 32947 }, 32948 32949 depend: function( param, element ) { 32950 return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true; 32951 }, 32952 32953 dependTypes: { 32954 "boolean": function( param ) { 32955 return param; 32956 }, 32957 "string": function( param, element ) { 32958 return !!$( param, element.form ).length; 32959 }, 32960 "function": function( param, element ) { 32961 return param( element ); 32962 } 32963 }, 32964 32965 optional: function( element ) { 32966 var val = this.elementValue( element ); 32967 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; 32968 }, 32969 32970 startRequest: function( element ) { 32971 if ( !this.pending[ element.name ] ) { 32972 this.pendingRequest++; 32973 $( element ).addClass( this.settings.pendingClass ); 32974 this.pending[ element.name ] = true; 32975 } 32976 }, 32977 32978 stopRequest: function( element, valid ) { 32979 this.pendingRequest--; 32980 32981 // Sometimes synchronization fails, make sure pendingRequest is never < 0 32982 if ( this.pendingRequest < 0 ) { 32983 this.pendingRequest = 0; 32984 } 32985 delete this.pending[ element.name ]; 32986 $( element ).removeClass( this.settings.pendingClass ); 32987 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 32988 $( this.currentForm ).submit(); 32989 32990 // Remove the hidden input that was used as a replacement for the 32991 // missing submit button. The hidden input is added by `handle()` 32992 // to ensure that the value of the used submit button is passed on 32993 // for scripted submits triggered by this method 32994 if ( this.submitButton ) { 32995 $( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove(); 32996 } 32997 32998 this.formSubmitted = false; 32999 } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) { 33000 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); 33001 this.formSubmitted = false; 33002 } 33003 }, 33004 33005 previousValue: function( element, method ) { 33006 method = typeof method === "string" && method || "remote"; 33007 33008 return $.data( element, "previousValue" ) || $.data( element, "previousValue", { 33009 old: null, 33010 valid: true, 33011 message: this.defaultMessage( element, { method: method } ) 33012 } ); 33013 }, 33014 33015 // Cleans up all forms and elements, removes validator-specific events 33016 destroy: function() { 33017 this.resetForm(); 33018 33019 $( this.currentForm ) 33020 .off( ".validate" ) 33021 .removeData( "validator" ) 33022 .find( ".validate-equalTo-blur" ) 33023 .off( ".validate-equalTo" ) 33024 .removeClass( "validate-equalTo-blur" ) 33025 .find( ".validate-lessThan-blur" ) 33026 .off( ".validate-lessThan" ) 33027 .removeClass( "validate-lessThan-blur" ) 33028 .find( ".validate-lessThanEqual-blur" ) 33029 .off( ".validate-lessThanEqual" ) 33030 .removeClass( "validate-lessThanEqual-blur" ) 33031 .find( ".validate-greaterThanEqual-blur" ) 33032 .off( ".validate-greaterThanEqual" ) 33033 .removeClass( "validate-greaterThanEqual-blur" ) 33034 .find( ".validate-greaterThan-blur" ) 33035 .off( ".validate-greaterThan" ) 33036 .removeClass( "validate-greaterThan-blur" ); 33037 } 33038 33039 }, 33040 33041 classRuleSettings: { 33042 required: { required: true }, 33043 email: { email: true }, 33044 url: { url: true }, 33045 date: { date: true }, 33046 dateISO: { dateISO: true }, 33047 number: { number: true }, 33048 digits: { digits: true }, 33049 creditcard: { creditcard: true } 33050 }, 33051 33052 addClassRules: function( className, rules ) { 33053 if ( className.constructor === String ) { 33054 this.classRuleSettings[ className ] = rules; 33055 } else { 33056 $.extend( this.classRuleSettings, className ); 33057 } 33058 }, 33059 33060 classRules: function( element ) { 33061 var rules = {}, 33062 classes = $( element ).attr( "class" ); 33063 33064 if ( classes ) { 33065 $.each( classes.split( " " ), function() { 33066 if ( this in $.validator.classRuleSettings ) { 33067 $.extend( rules, $.validator.classRuleSettings[ this ] ); 33068 } 33069 } ); 33070 } 33071 return rules; 33072 }, 33073 33074 normalizeAttributeRule: function( rules, type, method, value ) { 33075 33076 // Convert the value to a number for number inputs, and for text for backwards compability 33077 // allows type="date" and others to be compared as strings 33078 if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 33079 value = Number( value ); 33080 33081 // Support Opera Mini, which returns NaN for undefined minlength 33082 if ( isNaN( value ) ) { 33083 value = undefined; 33084 } 33085 } 33086 33087 if ( value || value === 0 ) { 33088 rules[ method ] = value; 33089 } else if ( type === method && type !== "range" ) { 33090 33091 // Exception: the jquery validate 'range' method 33092 // does not test for the html5 'range' type 33093 rules[ method ] = true; 33094 } 33095 }, 33096 33097 attributeRules: function( element ) { 33098 var rules = {}, 33099 $element = $( element ), 33100 type = element.getAttribute( "type" ), 33101 method, value; 33102 33103 for ( method in $.validator.methods ) { 33104 33105 // Support for <input required> in both html5 and older browsers 33106 if ( method === "required" ) { 33107 value = element.getAttribute( method ); 33108 33109 // Some browsers return an empty string for the required attribute 33110 // and non-HTML5 browsers might have required="" markup 33111 if ( value === "" ) { 33112 value = true; 33113 } 33114 33115 // Force non-HTML5 browsers to return bool 33116 value = !!value; 33117 } else { 33118 value = $element.attr( method ); 33119 } 33120 33121 this.normalizeAttributeRule( rules, type, method, value ); 33122 } 33123 33124 // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 33125 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { 33126 delete rules.maxlength; 33127 } 33128 33129 return rules; 33130 }, 33131 33132 dataRules: function( element ) { 33133 var rules = {}, 33134 $element = $( element ), 33135 type = element.getAttribute( "type" ), 33136 method, value; 33137 33138 for ( method in $.validator.methods ) { 33139 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); 33140 33141 // Cast empty attributes like `data-rule-required` to `true` 33142 if ( value === "" ) { 33143 value = true; 33144 } 33145 33146 this.normalizeAttributeRule( rules, type, method, value ); 33147 } 33148 return rules; 33149 }, 33150 33151 staticRules: function( element ) { 33152 var rules = {}, 33153 validator = $.data( element.form, "validator" ); 33154 33155 if ( validator.settings.rules ) { 33156 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; 33157 } 33158 return rules; 33159 }, 33160 33161 normalizeRules: function( rules, element ) { 33162 33163 // Handle dependency check 33164 $.each( rules, function( prop, val ) { 33165 33166 // Ignore rule when param is explicitly false, eg. required:false 33167 if ( val === false ) { 33168 delete rules[ prop ]; 33169 return; 33170 } 33171 if ( val.param || val.depends ) { 33172 var keepRule = true; 33173 switch ( typeof val.depends ) { 33174 case "string": 33175 keepRule = !!$( val.depends, element.form ).length; 33176 break; 33177 case "function": 33178 keepRule = val.depends.call( element, element ); 33179 break; 33180 } 33181 if ( keepRule ) { 33182 rules[ prop ] = val.param !== undefined ? val.param : true; 33183 } else { 33184 $.data( element.form, "validator" ).resetElements( $( element ) ); 33185 delete rules[ prop ]; 33186 } 33187 } 33188 } ); 33189 33190 // Evaluate parameters 33191 $.each( rules, function( rule, parameter ) { 33192 rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter; 33193 } ); 33194 33195 // Clean number parameters 33196 $.each( [ "minlength", "maxlength" ], function() { 33197 if ( rules[ this ] ) { 33198 rules[ this ] = Number( rules[ this ] ); 33199 } 33200 } ); 33201 $.each( [ "rangelength", "range" ], function() { 33202 var parts; 33203 if ( rules[ this ] ) { 33204 if ( $.isArray( rules[ this ] ) ) { 33205 rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ]; 33206 } else if ( typeof rules[ this ] === "string" ) { 33207 parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ ); 33208 rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ]; 33209 } 33210 } 33211 } ); 33212 33213 if ( $.validator.autoCreateRanges ) { 33214 33215 // Auto-create ranges 33216 if ( rules.min != null && rules.max != null ) { 33217 rules.range = [ rules.min, rules.max ]; 33218 delete rules.min; 33219 delete rules.max; 33220 } 33221 if ( rules.minlength != null && rules.maxlength != null ) { 33222 rules.rangelength = [ rules.minlength, rules.maxlength ]; 33223 delete rules.minlength; 33224 delete rules.maxlength; 33225 } 33226 } 33227 33228 return rules; 33229 }, 33230 33231 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 33232 normalizeRule: function( data ) { 33233 if ( typeof data === "string" ) { 33234 var transformed = {}; 33235 $.each( data.split( /\s/ ), function() { 33236 transformed[ this ] = true; 33237 } ); 33238 data = transformed; 33239 } 33240 return data; 33241 }, 33242 33243 // https://jqueryvalidation.org/jQuery.validator.addMethod/ 33244 addMethod: function( name, method, message ) { 33245 $.validator.methods[ name ] = method; 33246 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; 33247 if ( method.length < 3 ) { 33248 $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); 33249 } 33250 }, 33251 33252 // https://jqueryvalidation.org/jQuery.validator.methods/ 33253 methods: { 33254 33255 // https://jqueryvalidation.org/required-method/ 33256 required: function( value, element, param ) { 33257 33258 // Check if dependency is met 33259 if ( !this.depend( param, element ) ) { 33260 return "dependency-mismatch"; 33261 } 33262 if ( element.nodeName.toLowerCase() === "select" ) { 33263 33264 // Could be an array for select-multiple or a string, both are fine this way 33265 var val = $( element ).val(); 33266 return val && val.length > 0; 33267 } 33268 if ( this.checkable( element ) ) { 33269 return this.getLength( value, element ) > 0; 33270 } 33271 return value !== undefined && value !== null && value.length > 0; 33272 }, 33273 33274 // https://jqueryvalidation.org/email-method/ 33275 email: function( value, element ) { 33276 33277 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address 33278 // Retrieved 2014-01-14 33279 // If you have a problem with this implementation, report a bug against the above spec 33280 // Or use custom methods to implement your own email validation 33281 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); 33282 }, 33283 33284 // https://jqueryvalidation.org/url-method/ 33285 url: function( value, element ) { 33286 33287 // Copyright (c) 2010-2013 Diego Perini, MIT licensed 33288 // https://gist.github.com/dperini/729294 33289 // see also https://mathiasbynens.be/demo/url-regex 33290 // modified to allow protocol-relative URLs 33291 return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); 33292 }, 33293 33294 // https://jqueryvalidation.org/date-method/ 33295 date: ( function() { 33296 var called = false; 33297 33298 return function( value, element ) { 33299 if ( !called ) { 33300 called = true; 33301 if ( this.settings.debug && window.console ) { 33302 console.warn( 33303 "The `date` method is deprecated and will be removed in version '2.0.0'.\n" + 33304 "Please don't use it, since it relies on the Date constructor, which\n" + 33305 "behaves very differently across browsers and locales. Use `dateISO`\n" + 33306 "instead or one of the locale specific methods in `localizations/`\n" + 33307 "and `additional-methods.js`." 33308 ); 33309 } 33310 } 33311 33312 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); 33313 }; 33314 }() ), 33315 33316 // https://jqueryvalidation.org/dateISO-method/ 33317 dateISO: function( value, element ) { 33318 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); 33319 }, 33320 33321 // https://jqueryvalidation.org/number-method/ 33322 number: function( value, element ) { 33323 return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); 33324 }, 33325 33326 // https://jqueryvalidation.org/digits-method/ 33327 digits: function( value, element ) { 33328 return this.optional( element ) || /^\d+$/.test( value ); 33329 }, 33330 33331 // https://jqueryvalidation.org/minlength-method/ 33332 minlength: function( value, element, param ) { 33333 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 33334 return this.optional( element ) || length >= param; 33335 }, 33336 33337 // https://jqueryvalidation.org/maxlength-method/ 33338 maxlength: function( value, element, param ) { 33339 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 33340 return this.optional( element ) || length <= param; 33341 }, 33342 33343 // https://jqueryvalidation.org/rangelength-method/ 33344 rangelength: function( value, element, param ) { 33345 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 33346 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); 33347 }, 33348 33349 // https://jqueryvalidation.org/min-method/ 33350 min: function( value, element, param ) { 33351 return this.optional( element ) || value >= param; 33352 }, 33353 33354 // https://jqueryvalidation.org/max-method/ 33355 max: function( value, element, param ) { 33356 return this.optional( element ) || value <= param; 33357 }, 33358 33359 // https://jqueryvalidation.org/range-method/ 33360 range: function( value, element, param ) { 33361 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); 33362 }, 33363 33364 // https://jqueryvalidation.org/step-method/ 33365 step: function( value, element, param ) { 33366 var type = $( element ).attr( "type" ), 33367 errorMessage = "Step attribute on input type " + type + " is not supported.", 33368 supportedTypes = [ "text", "number", "range" ], 33369 re = new RegExp( "\\b" + type + "\\b" ), 33370 notSupported = type && !re.test( supportedTypes.join() ), 33371 decimalPlaces = function( num ) { 33372 var match = ( "" + num ).match( /(?:\.(\d+))?$/ ); 33373 if ( !match ) { 33374 return 0; 33375 } 33376 33377 // Number of digits right of decimal point. 33378 return match[ 1 ] ? match[ 1 ].length : 0; 33379 }, 33380 toInt = function( num ) { 33381 return Math.round( num * Math.pow( 10, decimals ) ); 33382 }, 33383 valid = true, 33384 decimals; 33385 33386 // Works only for text, number and range input types 33387 // TODO find a way to support input types date, datetime, datetime-local, month, time and week 33388 if ( notSupported ) { 33389 throw new Error( errorMessage ); 33390 } 33391 33392 decimals = decimalPlaces( param ); 33393 33394 // Value can't have too many decimals 33395 if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) { 33396 valid = false;
33397 } 33398 33399 return this.optional( element ) || valid; 33400 }, 33401 33402 // https://jqueryvalidation.org/equalTo-method/ 33403 equalTo: function( value, element, param ) { 33404 33405 // Bind to the blur event of the target in order to revalidate whenever the target field is updated 33406 var target = $( param ); 33407 if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) { 33408 target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() { 33409 $( element ).valid(); 33410 } ); 33411 } 33412 return value === target.val(); 33413 }, 33414 33415 // https://jqueryvalidation.org/remote-method/ 33416 remote: function( value, element, param, method ) { 33417 if ( this.optional( element ) ) { 33418 return "dependency-mismatch"; 33419 } 33420 33421 method = typeof method === "string" && method || "remote"; 33422 33423 var previous = this.previousValue( element, method ), 33424 validator, data, optionDataString; 33425 33426 if ( !this.settings.messages[ element.name ] ) { 33427 this.settings.messages[ element.name ] = {}; 33428 } 33429 previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ]; 33430 this.settings.messages[ element.name ][ method ] = previous.message; 33431 33432 param = typeof param === "string" && { url: param } || param; 33433 optionDataString = $.param( $.extend( { data: value }, param.data ) ); 33434 if ( previous.old === optionDataString ) { 33435 return previous.valid; 33436 } 33437 33438 previous.old = optionDataString; 33439 validator = this; 33440 this.startRequest( element ); 33441 data = {}; 33442 data[ element.name ] = value; 33443 $.ajax( $.extend( true, { 33444 mode: "abort", 33445 port: "validate" + element.name, 33446 dataType: "json", 33447 data: data, 33448 context: validator.currentForm, 33449 success: function( response ) { 33450 var valid = response === true || response === "true", 33451 errors, message, submitted; 33452 33453 validator.settings.messages[ element.name ][ method ] = previous.originalMessage; 33454 if ( valid ) { 33455 submitted = validator.formSubmitted; 33456 validator.resetInternals(); 33457 validator.toHide = validator.errorsFor( element ); 33458 validator.formSubmitted = submitted; 33459 validator.successList.push( element ); 33460 validator.invalid[ element.name ] = false; 33461 validator.showErrors(); 33462 } else { 33463 errors = {}; 33464 message = response || validator.defaultMessage( element, { method: method, parameters: value } ); 33465 errors[ element.name ] = previous.message = message; 33466 validator.invalid[ element.name ] = true; 33467 validator.showErrors( errors ); 33468 } 33469 previous.valid = valid; 33470 validator.stopRequest( element, valid ); 33471 } 33472 }, param ) ); 33473 return "pending"; 33474 } 33475 } 33476 33477} ); 33478 33479// Ajax mode: abort 33480// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 33481// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 33482 33483var pendingRequests = {}, 33484 ajax; 33485 33486// Use a prefilter if available (1.5+) 33487if ( $.ajaxPrefilter ) { 33488 $.ajaxPrefilter( function( settings, _, xhr ) { 33489 var port = settings.port; 33490 if ( settings.mode === "abort" ) { 33491 if ( pendingRequests[ port ] ) { 33492 pendingRequests[ port ].abort(); 33493 } 33494 pendingRequests[ port ] = xhr; 33495 } 33496 } ); 33497} else { 33498 33499 // Proxy ajax 33500 ajax = $.ajax; 33501 $.ajax = function( settings ) { 33502 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 33503 port = ( "port" in settings ? settings : $.ajaxSettings ).port; 33504 if ( mode === "abort" ) { 33505 if ( pendingRequests[ port ] ) { 33506 pendingRequests[ port ].abort(); 33507 } 33508 pendingRequests[ port ] = ajax.apply( this, arguments ); 33509 return pendingRequests[ port ]; 33510 } 33511 return ajax.apply( this, arguments ); 33512 }; 33513} 33514return $; 33515})); 33516/*! 33517 * jQuery Validation Plugin v1.19.0 33518 * 33519 * https://jqueryvalidation.org/ 33520 * 33521 * Copyright (c) 2018 Jörn Zaefferer 33522 * Released under the MIT license 33523 */ 33524 33525(function( factory ) { 33526 if ( typeof define === "function" && define.amd ) { 33527 define( ["jquery", "./jquery.validate"], factory ); 33528 } else if (typeof module === "object" && module.exports) { 33529 module.exports = factory( require( "jquery" ) ); 33530 } else { 33531 factory( jQuery ); 33532 } 33533}(function( $ ) { 33534 33535( function() { 33536 33537 function stripHtml( value ) { 33538 33539 // Remove html tags and space chars 33540 return value.replace( /<.[^<>]*?>/g, " " ).replace( / | /gi, " " ) 33541 33542 // Remove punctuation 33543 .replace( /[.(),;:!?%#$'\"_+=\/\-âââ]*/g, "" ); 33544 } 33545 33546 $.validator.addMethod( "maxWords", function( value, element, params ) {
vendor: 4,581 bytes, lines 33547-33679
33547 return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params; 33548 }, $.validator.format( "Please enter {0} words or less." ) ); 33549 33550 $.validator.addMethod( "minWords", function( value, element, params ) { 33551 return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params; 33552 }, $.validator.format( "Please enter at least {0} words." ) ); 33553 33554 $.validator.addMethod( "rangeWords", function( value, element, params ) { 33555 var valueStripped = stripHtml( value ), 33556 regex = /\b\w+\b/g; 33557 return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ]; 33558 }, $.validator.format( "Please enter between {0} and {1} words." ) ); 33559 33560}() ); 33561 33562/** 33563 * This is used in the United States to process payments, deposits, 33564 * or transfers using the Automated Clearing House (ACH) or Fedwire 33565 * systems. A very common use case would be to validate a form for 33566 * an ACH bill payment. 33567 */ 33568$.validator.addMethod( "abaRoutingNumber", function( value ) { 33569 var checksum = 0; 33570 var tokens = value.split( "" ); 33571 var length = tokens.length; 33572 33573 // Length Check 33574 if ( length !== 9 ) { 33575 return false; 33576 } 33577 33578 // Calc the checksum 33579 // https://en.wikipedia.org/wiki/ABA_routing_transit_number 33580 for ( var i = 0; i < length; i += 3 ) { 33581 checksum += parseInt( tokens[ i ], 10 ) * 3 + 33582 parseInt( tokens[ i + 1 ], 10 ) * 7 + 33583 parseInt( tokens[ i + 2 ], 10 ); 33584 } 33585 33586 // If not zero and divisible by 10 then valid 33587 if ( checksum !== 0 && checksum % 10 === 0 ) { 33588 return true; 33589 } 33590 33591 return false; 33592}, "Please enter a valid routing number." ); 33593 33594// Accept a value from a file input based on a required mimetype 33595$.validator.addMethod( "accept", function( value, element, param ) { 33596 33597 // Split mime on commas in case we have multiple types we can accept 33598 var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*", 33599 optionalValue = this.optional( element ), 33600 i, file, regex; 33601 33602 // Element is optional 33603 if ( optionalValue ) { 33604 return optionalValue; 33605 } 33606 33607 if ( $( element ).attr( "type" ) === "file" ) { 33608 33609 // Escape string to be used in the regex 33610 // see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex 33611 // Escape also "/*" as "/.*" as a wildcard 33612 typeParam = typeParam 33613 .replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" ) 33614 .replace( /,/g, "|" ) 33615 .replace( /\/\*/g, "/.*" ); 33616 33617 // Check if the element has a FileList before checking each file 33618 if ( element.files && element.files.length ) { 33619 regex = new RegExp( ".?(" + typeParam + ")$", "i" ); 33620 for ( i = 0; i < element.files.length; i++ ) { 33621 file = element.files[ i ]; 33622 33623 // Grab the mimetype from the loaded file, verify it matches 33624 if ( !file.type.match( regex ) ) { 33625 return false; 33626 } 33627 } 33628 } 33629 } 33630 33631 // Either return true because we've validated each file, or because the 33632 // browser does not support element.files and the FileList feature 33633 return true; 33634}, $.validator.format( "Please enter a value with a valid mimetype." ) ); 33635 33636$.validator.addMethod( "alphanumeric", function( value, element ) { 33637 return this.optional( element ) || /^\w+$/i.test( value ); 33638}, "Letters, numbers, and underscores only please" ); 33639 33640/* 33641 * Dutch bank account numbers (not 'giro' numbers) have 9 digits 33642 * and pass the '11 check'. 33643 * We accept the notation with spaces, as that is common. 33644 * acceptable: 123456789 or 12 34 56 789 33645 */ 33646$.validator.addMethod( "bankaccountNL", function( value, element ) { 33647 if ( this.optional( element ) ) { 33648 return true; 33649 } 33650 if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) { 33651 return false; 33652 } 33653 33654 // Now '11 check' 33655 var account = value.replace( / /g, "" ), // Remove spaces 33656 sum = 0, 33657 len = account.length, 33658 pos, factor, digit; 33659 for ( pos = 0; pos < len; pos++ ) { 33660 factor = len - pos; 33661 digit = account.substring( pos, pos + 1 ); 33662 sum = sum + factor * digit; 33663 } 33664 return sum % 11 === 0; 33665}, "Please specify a valid bank account number" ); 33666 33667$.validator.addMethod( "bankorgiroaccountNL", function( value, element ) { 33668 return this.optional( element ) || 33669 ( $.validator.methods.bankaccountNL.call( this, value, element ) ) || 33670 ( $.validator.methods.giroaccountNL.call( this, value, element ) ); 33671}, "Please specify a valid bank or giro account number" ); 33672 33673/** 33674 * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity. 33675 * 33676 * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional) 33677 * 33678 * Validation is case-insensitive. Please make sure to normalize input yourself. 33679 *
33680 * BIC definition in detail: 33681 * - First 4 characters - bank code (only letters) 33682 * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters) 33683 * - Next 2 characters - location code (letters and digits) 33684 * a. shall not start with '0' or '1' 33685 * b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing) 33686 * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits) 33687 */ 33688$.validator.addMethod( "bic", function( value, element ) { 33689 return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() ); 33690}, "Please specify a valid BIC code" ); 33691 33692/* 33693 * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities 33694 * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal 33695 * 33696 * Spanish CIF structure: 33697 * 33698 * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ] 33699 * 33700 * Where: 33701 * 33702 * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW] 33703 * P: 2 characters. Province. 33704 * N: 5 characters. Secuencial Number within the province. 33705 * C: 1 character. Control Digit: [0-9A-J]. 33706 * 33707 * [ T ]: Kind of Organizations. Possible values: 33708 * 33709 * A. Corporations 33710 * B. LLCs 33711 * C. General partnerships 33712 * D. Companies limited partnerships 33713 * E. Communities of goods 33714 * F. Cooperative Societies 33715 * G. Associations 33716 * H. Communities of homeowners in horizontal property regime 33717 * J. Civil Societies 33718 * K. Old format 33719 * L. Old format 33720 * M. Old format 33721 * N. Nonresident entities 33722 * P. Local authorities 33723 * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions 33724 * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008) 33725 * S. Organs of State Administration and regions 33726 * V. Agrarian Transformation 33727 * W. Permanent establishments of non-resident in Spain 33728 * 33729 * [ C ]: Control Digit. It can be a number or a letter depending on T value: 33730 * [ T ] --> [ C ] 33731 * ------ ---------- 33732 * A Number 33733 * B Number 33734 * E Number 33735 * H Number 33736 * K Letter 33737 * P Letter 33738 * Q Letter 33739 * S Letter 33740 * 33741 */ 33742$.validator.addMethod( "cifES", function( value, element ) { 33743 "use strict"; 33744 33745 if ( this.optional( element ) ) { 33746 return true; 33747 } 33748 33749 var cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi ); 33750 var letter = value.substring( 0, 1 ), // [ T ] 33751 number = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ] 33752 control = value.substring( 8, 9 ), // [ C ] 33753 all_sum = 0, 33754 even_sum = 0, 33755 odd_sum = 0, 33756 i, n, 33757 control_digit, 33758 control_letter; 33759 33760 function isOdd( n ) { 33761 return n % 2 === 0; 33762 } 33763 33764 // Quick format test 33765 if ( value.length !== 9 || !cifRegEx.test( value ) ) { 33766 return false; 33767 } 33768 33769 for ( i = 0; i < number.length; i++ ) { 33770 n = parseInt( number[ i ], 10 ); 33771 33772 // Odd positions 33773 if ( isOdd( i ) ) { 33774 33775 // Odd positions are multiplied first. 33776 n *= 2; 33777 33778 // If the multiplication is bigger than 10 we need to adjust 33779 odd_sum += n < 10 ? n : n - 9; 33780 33781 // Even positions 33782 // Just sum them 33783 } else { 33784 even_sum += n; 33785 } 33786 } 33787 33788 all_sum = even_sum + odd_sum; 33789 control_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString(); 33790 control_digit = parseInt( control_digit, 10 ) > 9 ? "0" : control_digit; 33791 control_letter = "JABCDEFGHI".substr( control_digit, 1 ).toString(); 33792 33793 // Control must be a digit 33794 if ( letter.match( /[ABEH]/ ) ) { 33795 return control === control_digit; 33796 33797 // Control must be a letter 33798 } else if ( letter.match( /[KPQS]/ ) ) { 33799 return control === control_letter; 33800 } 33801 33802 // Can be either 33803 return control === control_digit || control === control_letter; 33804 33805}, "Please specify a valid CIF number." ); 33806 33807/* 33808 * Brazillian CNH number (Carteira Nacional de Habilitacao) is the License Driver number. 33809 * CNH numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation. 33810 */ 33811$.validator.addMethod( "cnhBR", function( value ) { 33812 33813 // Removing special characters from value 33814 value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); 33815 33816 // Checking value to have 11 digits only 33817 if ( value.length !== 11 ) { 33818 return false;
vendor: 28,001 bytes, lines 33819-34710
33819 } 33820 33821 var sum = 0, dsc = 0, firstChar, 33822 firstCN, secondCN, i, j, v; 33823 33824 firstChar = value.charAt( 0 ); 33825 33826 if ( new Array( 12 ).join( firstChar ) === value ) { 33827 return false; 33828 } 33829 33830 // Step 1 - using first Check Number: 33831 for ( i = 0, j = 9, v = 0; i < 9; ++i, --j ) { 33832 sum += +( value.charAt( i ) * j ); 33833 } 33834 33835 firstCN = sum % 11; 33836 if ( firstCN >= 10 ) { 33837 firstCN = 0; 33838 dsc = 2; 33839 } 33840 33841 sum = 0; 33842 for ( i = 0, j = 1, v = 0; i < 9; ++i, ++j ) { 33843 sum += +( value.charAt( i ) * j ); 33844 } 33845 33846 secondCN = sum % 11; 33847 if ( secondCN >= 10 ) { 33848 secondCN = 0; 33849 } else { 33850 secondCN = secondCN - dsc; 33851 } 33852 33853 return ( String( firstCN ).concat( secondCN ) === value.substr( -2 ) ); 33854 33855}, "Please specify a valid CNH number" ); 33856 33857/* 33858 * Brazillian value number (Cadastrado de Pessoas Juridica). 33859 * value numbers have 14 digits in total: 12 numbers followed by 2 check numbers that are being used for validation. 33860 */ 33861$.validator.addMethod( "cnpjBR", function( value, element ) { 33862 "use strict"; 33863 33864 if ( this.optional( element ) ) { 33865 return true; 33866 } 33867 33868 // Removing no number 33869 value = value.replace( /[^\d]+/g, "" ); 33870 33871 // Checking value to have 14 digits only 33872 if ( value.length !== 14 ) { 33873 return false; 33874 } 33875 33876 // Elimina values invalidos conhecidos 33877 if ( value === "00000000000000" || 33878 value === "11111111111111" || 33879 value === "22222222222222" || 33880 value === "33333333333333" || 33881 value === "44444444444444" || 33882 value === "55555555555555" || 33883 value === "66666666666666" || 33884 value === "77777777777777" || 33885 value === "88888888888888" || 33886 value === "99999999999999" ) { 33887 return false; 33888 } 33889 33890 // Valida DVs 33891 var tamanho = ( value.length - 2 ); 33892 var numeros = value.substring( 0, tamanho ); 33893 var digitos = value.substring( tamanho ); 33894 var soma = 0; 33895 var pos = tamanho - 7; 33896 33897 for ( var i = tamanho; i >= 1; i-- ) { 33898 soma += numeros.charAt( tamanho - i ) * pos--; 33899 if ( pos < 2 ) { 33900 pos = 9; 33901 } 33902 } 33903 33904 var resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; 33905 33906 if ( resultado !== parseInt( digitos.charAt( 0 ), 10 ) ) { 33907 return false; 33908 } 33909 33910 tamanho = tamanho + 1; 33911 numeros = value.substring( 0, tamanho ); 33912 soma = 0; 33913 pos = tamanho - 7; 33914 33915 for ( var il = tamanho; il >= 1; il-- ) { 33916 soma += numeros.charAt( tamanho - il ) * pos--; 33917 if ( pos < 2 ) { 33918 pos = 9; 33919 } 33920 } 33921 33922 resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; 33923 33924 if ( resultado !== parseInt( digitos.charAt( 1 ), 10 ) ) { 33925 return false; 33926 } 33927 33928 return true; 33929 33930}, "Please specify a CNPJ value number" ); 33931 33932/* 33933 * Brazillian CPF number (Cadastrado de Pessoas FÃsicas) is the equivalent of a Brazilian tax registration number. 33934 * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation. 33935 */ 33936$.validator.addMethod( "cpfBR", function( value, element ) { 33937 "use strict"; 33938 33939 if ( this.optional( element ) ) { 33940 return true; 33941 } 33942 33943 // Removing special characters from value 33944 value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); 33945 33946 // Checking value to have 11 digits only 33947 if ( value.length !== 11 ) { 33948 return false; 33949 } 33950 33951 var sum = 0, 33952 firstCN, secondCN, checkResult, i; 33953 33954 firstCN = parseInt( value.substring( 9, 10 ), 10 ); 33955 secondCN = parseInt( value.substring( 10, 11 ), 10 ); 33956 33957 checkResult = function( sum, cn ) { 33958 var result = ( sum * 10 ) % 11; 33959 if ( ( result === 10 ) || ( result === 11 ) ) { 33960 result = 0; 33961 } 33962 return ( result === cn ); 33963 }; 33964 33965 // Checking for dump data 33966 if ( value === "" || 33967 value === "00000000000" || 33968 value === "11111111111" || 33969 value === "22222222222" || 33970 value === "33333333333" || 33971 value === "44444444444" || 33972 value === "55555555555" || 33973 value === "66666666666" || 33974 value === "77777777777" || 33975 value === "88888888888" || 33976 value === "99999999999" 33977 ) { 33978 return false; 33979 } 33980 33981 // Step 1 - using first Check Number: 33982 for ( i = 1; i <= 9; i++ ) { 33983 sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i ); 33984 } 33985 33986 // If first Check Number (CN) is valid, move to Step 2 - using second Check Number: 33987 if ( checkResult( sum, firstCN ) ) { 33988 sum = 0; 33989 for ( i = 1; i <= 10; i++ ) { 33990 sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i ); 33991 } 33992 return checkResult( sum, secondCN ); 33993 } 33994 return false; 33995 33996}, "Please specify a valid CPF number" ); 33997 33998// https://jqueryvalidation.org/creditcard-method/ 33999// based on https://en.wikipedia.org/wiki/Luhn_algorithm 34000$.validator.addMethod( "creditcard", function( value, element ) { 34001 if ( this.optional( element ) ) { 34002 return "dependency-mismatch"; 34003 } 34004 34005 // Accept only spaces, digits and dashes 34006 if ( /[^0-9 \-]+/.test( value ) ) { 34007 return false; 34008 } 34009 34010 var nCheck = 0, 34011 nDigit = 0, 34012 bEven = false, 34013 n, cDigit; 34014 34015 value = value.replace( /\D/g, "" ); 34016 34017 // Basing min and max length on 34018 // https://dev.ean.com/general-info/valid-card-types/ 34019 if ( value.length < 13 || value.length > 19 ) { 34020 return false; 34021 } 34022 34023 for ( n = value.length - 1; n >= 0; n-- ) { 34024 cDigit = value.charAt( n ); 34025 nDigit = parseInt( cDigit, 10 ); 34026 if ( bEven ) { 34027 if ( ( nDigit *= 2 ) > 9 ) { 34028 nDigit -= 9; 34029 } 34030 } 34031 34032 nCheck += nDigit; 34033 bEven = !bEven; 34034 } 34035 34036 return ( nCheck % 10 ) === 0; 34037}, "Please enter a valid credit card number." ); 34038 34039/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator 34040 * Redistributed under the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 34041 * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) 34042 */ 34043$.validator.addMethod( "creditcardtypes", function( value, element, param ) { 34044 if ( /[^0-9\-]+/.test( value ) ) { 34045 return false; 34046 } 34047 34048 value = value.replace( /\D/g, "" ); 34049 34050 var validTypes = 0x0000; 34051 34052 if ( param.mastercard ) { 34053 validTypes |= 0x0001; 34054 } 34055 if ( param.visa ) { 34056 validTypes |= 0x0002; 34057 } 34058 if ( param.amex ) { 34059 validTypes |= 0x0004; 34060 } 34061 if ( param.dinersclub ) { 34062 validTypes |= 0x0008; 34063 } 34064 if ( param.enroute ) { 34065 validTypes |= 0x0010; 34066 } 34067 if ( param.discover ) { 34068 validTypes |= 0x0020; 34069 } 34070 if ( param.jcb ) { 34071 validTypes |= 0x0040; 34072 } 34073 if ( param.unknown ) { 34074 validTypes |= 0x0080; 34075 } 34076 if ( param.all ) { 34077 validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; 34078 } 34079 if ( validTypes & 0x0001 && ( /^(5[12345])/.test( value ) || /^(2[234567])/.test( value ) ) ) { // Mastercard 34080 return value.length === 16; 34081 } 34082 if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa 34083 return value.length === 16; 34084 } 34085 if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex 34086 return value.length === 15; 34087 } 34088 if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub 34089 return value.length === 14; 34090 } 34091 if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute 34092 return value.length === 15; 34093 } 34094 if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover 34095 return value.length === 16; 34096 } 34097 if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb 34098 return value.length === 16; 34099 } 34100 if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb 34101 return value.length === 15; 34102 } 34103 if ( validTypes & 0x0080 ) { // Unknown 34104 return true; 34105 } 34106 return false; 34107}, "Please enter a valid credit card number." ); 34108 34109/** 34110 * Validates currencies with any given symbols by @jameslouiz 34111 * Symbols can be optional or required. Symbols required by default 34112 * 34113 * Usage examples: 34114 * currency: ["£", false] - Use false for soft currency validation 34115 * currency: ["$", false] 34116 * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc 34117 * 34118 * <input class="currencyInput" name="currencyInput"> 34119 * 34120 * Soft symbol checking 34121 * currencyInput: { 34122 * currency: ["$", false] 34123 * } 34124 * 34125 * Strict symbol checking (default) 34126 * currencyInput: { 34127 * currency: "$" 34128 * //OR 34129 * currency: ["$", true] 34130 * } 34131 * 34132 * Multiple Symbols 34133 * currencyInput: { 34134 * currency: "$,£,¢" 34135 * } 34136 */ 34137$.validator.addMethod( "currency", function( value, element, param ) { 34138 var isParamString = typeof param === "string", 34139 symbol = isParamString ? param : param[ 0 ], 34140 soft = isParamString ? true : param[ 1 ], 34141 regex; 34142 34143 symbol = symbol.replace( /,/g, "" ); 34144 symbol = soft ? symbol + "]" : symbol + "]?"; 34145 regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$"; 34146 regex = new RegExp( regex ); 34147 return this.optional( element ) || regex.test( value ); 34148 34149}, "Please specify a valid currency" ); 34150 34151$.validator.addMethod( "dateFA", function( value, element ) { 34152 return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value ); 34153}, $.validator.messages.date ); 34154 34155/** 34156 * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. 34157 * 34158 * @example $.validator.methods.date("01/01/1900") 34159 * @result true 34160 * 34161 * @example $.validator.methods.date("01/13/1990") 34162 * @result false 34163 * 34164 * @example $.validator.methods.date("01.01.1900") 34165 * @result false 34166 * 34167 * @example <input name="pippo" class="{dateITA:true}" /> 34168 * @desc Declares an optional input element whose value must be a valid date. 34169 * 34170 * @name $.validator.methods.dateITA 34171 * @type Boolean 34172 * @cat Plugins/Validate/Methods 34173 */ 34174$.validator.addMethod( "dateITA", function( value, element ) { 34175 var check = false, 34176 re = /^\d{1,2}\/\d{1,2}\/\d{4}$/, 34177 adata, gg, mm, aaaa, xdata; 34178 if ( re.test( value ) ) { 34179 adata = value.split( "/" ); 34180 gg = parseInt( adata[ 0 ], 10 ); 34181 mm = parseInt( adata[ 1 ], 10 ); 34182 aaaa = parseInt( adata[ 2 ], 10 ); 34183 xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) ); 34184 if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) { 34185 check = true; 34186 } else { 34187 check = false; 34188 } 34189 } else { 34190 check = false; 34191 } 34192 return this.optional( element ) || check; 34193}, $.validator.messages.date ); 34194 34195$.validator.addMethod( "dateNL", function( value, element ) { 34196 return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value ); 34197}, $.validator.messages.date ); 34198 34199// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept 34200$.validator.addMethod( "extension", function( value, element, param ) { 34201 param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif"; 34202 return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) ); 34203}, $.validator.format( "Please enter a value with a valid extension." ) ); 34204 34205/** 34206 * Dutch giro account numbers (not bank numbers) have max 7 digits 34207 */ 34208$.validator.addMethod( "giroaccountNL", function( value, element ) { 34209 return this.optional( element ) || /^[0-9]{1,7}$/.test( value ); 34210}, "Please specify a valid giro account number" ); 34211 34212$.validator.addMethod( "greaterThan", function( value, element, param ) { 34213 var target = $( param ); 34214 34215 if ( this.settings.onfocusout && target.not( ".validate-greaterThan-blur" ).length ) { 34216 target.addClass( "validate-greaterThan-blur" ).on( "blur.validate-greaterThan", function() { 34217 $( element ).valid(); 34218 } ); 34219 } 34220 34221 return value > target.val(); 34222}, "Please enter a greater value." ); 34223 34224$.validator.addMethod( "greaterThanEqual", function( value, element, param ) { 34225 var target = $( param ); 34226 34227 if ( this.settings.onfocusout && target.not( ".validate-greaterThanEqual-blur" ).length ) { 34228 target.addClass( "validate-greaterThanEqual-blur" ).on( "blur.validate-greaterThanEqual", function() { 34229 $( element ).valid(); 34230 } ); 34231 } 34232 34233 return value >= target.val(); 34234}, "Please enter a greater value." ); 34235 34236/** 34237 * IBAN is the international bank account number. 34238 * It has a country - specific format, that is checked here too 34239 * 34240 * Validation is case-insensitive. Please make sure to normalize input yourself. 34241 */ 34242$.validator.addMethod( "iban", function( value, element ) { 34243 34244 // Some quick simple tests to prevent needless work 34245 if ( this.optional( element ) ) { 34246 return true; 34247 } 34248 34249 // Remove spaces and to upper case 34250 var iban = value.replace( / /g, "" ).toUpperCase(), 34251 ibancheckdigits = "", 34252 leadingZeroes = true, 34253 cRest = "", 34254 cOperator = "", 34255 countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p; 34256 34257 // Check for IBAN code length. 34258 // It contains: 34259 // country code ISO 3166-1 - two letters, 34260 // two check digits, 34261 // Basic Bank Account Number (BBAN) - up to 30 chars 34262 var minimalIBANlength = 5; 34263 if ( iban.length < minimalIBANlength ) { 34264 return false; 34265 } 34266 34267 // Check the country code and find the country specific format 34268 countrycode = iban.substring( 0, 2 ); 34269 bbancountrypatterns = { 34270 "AL": "\\d{8}[\\dA-Z]{16}", 34271 "AD": "\\d{8}[\\dA-Z]{12}", 34272 "AT": "\\d{16}", 34273 "AZ": "[\\dA-Z]{4}\\d{20}", 34274 "BE": "\\d{12}", 34275 "BH": "[A-Z]{4}[\\dA-Z]{14}", 34276 "BA": "\\d{16}", 34277 "BR": "\\d{23}[A-Z][\\dA-Z]", 34278 "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}", 34279 "CR": "\\d{17}", 34280 "HR": "\\d{17}", 34281 "CY": "\\d{8}[\\dA-Z]{16}", 34282 "CZ": "\\d{20}", 34283 "DK": "\\d{14}", 34284 "DO": "[A-Z]{4}\\d{20}", 34285 "EE": "\\d{16}", 34286 "FO": "\\d{14}", 34287 "FI": "\\d{14}", 34288 "FR": "\\d{10}[\\dA-Z]{11}\\d{2}", 34289 "GE": "[\\dA-Z]{2}\\d{16}", 34290 "DE": "\\d{18}", 34291 "GI": "[A-Z]{4}[\\dA-Z]{15}", 34292 "GR": "\\d{7}[\\dA-Z]{16}", 34293 "GL": "\\d{14}", 34294 "GT": "[\\dA-Z]{4}[\\dA-Z]{20}", 34295 "HU": "\\d{24}", 34296 "IS": "\\d{22}", 34297 "IE": "[\\dA-Z]{4}\\d{14}", 34298 "IL": "\\d{19}", 34299 "IT": "[A-Z]\\d{10}[\\dA-Z]{12}", 34300 "KZ": "\\d{3}[\\dA-Z]{13}", 34301 "KW": "[A-Z]{4}[\\dA-Z]{22}", 34302 "LV": "[A-Z]{4}[\\dA-Z]{13}", 34303 "LB": "\\d{4}[\\dA-Z]{20}", 34304 "LI": "\\d{5}[\\dA-Z]{12}", 34305 "LT": "\\d{16}", 34306 "LU": "\\d{3}[\\dA-Z]{13}", 34307 "MK": "\\d{3}[\\dA-Z]{10}\\d{2}", 34308 "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}", 34309 "MR": "\\d{23}", 34310 "MU": "[A-Z]{4}\\d{19}[A-Z]{3}", 34311 "MC": "\\d{10}[\\dA-Z]{11}\\d{2}", 34312 "MD": "[\\dA-Z]{2}\\d{18}", 34313 "ME": "\\d{18}", 34314 "NL": "[A-Z]{4}\\d{10}", 34315 "NO": "\\d{11}", 34316 "PK": "[\\dA-Z]{4}\\d{16}", 34317 "PS": "[\\dA-Z]{4}\\d{21}", 34318 "PL": "\\d{24}", 34319 "PT": "\\d{21}", 34320 "RO": "[A-Z]{4}[\\dA-Z]{16}", 34321 "SM": "[A-Z]\\d{10}[\\dA-Z]{12}", 34322 "SA": "\\d{2}[\\dA-Z]{18}", 34323 "RS": "\\d{18}", 34324 "SK": "\\d{20}", 34325 "SI": "\\d{15}", 34326 "ES": "\\d{20}", 34327 "SE": "\\d{20}", 34328 "CH": "\\d{5}[\\dA-Z]{12}", 34329 "TN": "\\d{20}", 34330 "TR": "\\d{5}[\\dA-Z]{17}", 34331 "AE": "\\d{3}\\d{16}", 34332 "GB": "[A-Z]{4}\\d{14}", 34333 "VG": "[\\dA-Z]{4}\\d{16}" 34334 }; 34335 34336 bbanpattern = bbancountrypatterns[ countrycode ]; 34337 34338 // As new countries will start using IBAN in the 34339 // future, we only check if the countrycode is known. 34340 // This prevents false negatives, while almost all 34341 // false positives introduced by this, will be caught 34342 // by the checksum validation below anyway. 34343 // Strict checking should return FALSE for unknown 34344 // countries. 34345 if ( typeof bbanpattern !== "undefined" ) { 34346 ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" ); 34347 if ( !( ibanregexp.test( iban ) ) ) { 34348 return false; // Invalid country specific format 34349 } 34350 } 34351 34352 // Now check the checksum, first convert to digits 34353 ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 ); 34354 for ( i = 0; i < ibancheck.length; i++ ) { 34355 charAt = ibancheck.charAt( i ); 34356 if ( charAt !== "0" ) { 34357 leadingZeroes = false; 34358 } 34359 if ( !leadingZeroes ) { 34360 ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt ); 34361 } 34362 } 34363 34364 // Calculate the result of: ibancheckdigits % 97 34365 for ( p = 0; p < ibancheckdigits.length; p++ ) { 34366 cChar = ibancheckdigits.charAt( p ); 34367 cOperator = "" + cRest + "" + cChar; 34368 cRest = cOperator % 97; 34369 } 34370 return cRest === 1; 34371}, "Please specify a valid IBAN" ); 34372 34373$.validator.addMethod( "integer", function( value, element ) { 34374 return this.optional( element ) || /^-?\d+$/.test( value ); 34375}, "A positive or negative non-decimal number please" ); 34376 34377$.validator.addMethod( "ipv4", function( value, element ) { 34378 return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value ); 34379}, "Please enter a valid IP v4 address." ); 34380 34381$.validator.addMethod( "ipv6", function( value, element ) { 34382 return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value ); 34383}, "Please enter a valid IP v6 address." ); 34384 34385$.validator.addMethod( "lessThan", function( value, element, param ) { 34386 var target = $( param ); 34387 34388 if ( this.settings.onfocusout && target.not( ".validate-lessThan-blur" ).length ) { 34389 target.addClass( "validate-lessThan-blur" ).on( "blur.validate-lessThan", function() { 34390 $( element ).valid(); 34391 } ); 34392 } 34393 34394 return value < target.val(); 34395}, "Please enter a lesser value." ); 34396 34397$.validator.addMethod( "lessThanEqual", function( value, element, param ) { 34398 var target = $( param ); 34399 34400 if ( this.settings.onfocusout && target.not( ".validate-lessThanEqual-blur" ).length ) { 34401 target.addClass( "validate-lessThanEqual-blur" ).on( "blur.validate-lessThanEqual", function() { 34402 $( element ).valid(); 34403 } ); 34404 } 34405 34406 return value <= target.val(); 34407}, "Please enter a lesser value." ); 34408 34409$.validator.addMethod( "lettersonly", function( value, element ) { 34410 return this.optional( element ) || /^[a-z]+$/i.test( value ); 34411}, "Letters only please" ); 34412 34413$.validator.addMethod( "letterswithbasicpunc", function( value, element ) { 34414 return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value ); 34415}, "Letters or punctuation only please" ); 34416 34417// Limit the number of files in a FileList. 34418$.validator.addMethod( "maxfiles", function( value, element, param ) { 34419 if ( this.optional( element ) ) { 34420 return true; 34421 } 34422 34423 if ( $( element ).attr( "type" ) === "file" ) { 34424 if ( element.files && element.files.length > param ) { 34425 return false; 34426 } 34427 } 34428 34429 return true; 34430}, $.validator.format( "Please select no more than {0} files." ) ); 34431 34432// Limit the size of each individual file in a FileList. 34433$.validator.addMethod( "maxsize", function( value, element, param ) { 34434 if ( this.optional( element ) ) { 34435 return true; 34436 } 34437 34438 if ( $( element ).attr( "type" ) === "file" ) { 34439 if ( element.files && element.files.length ) { 34440 for ( var i = 0; i < element.files.length; i++ ) { 34441 if ( element.files[ i ].size > param ) { 34442 return false; 34443 } 34444 } 34445 } 34446 } 34447 34448 return true; 34449}, $.validator.format( "File size must not exceed {0} bytes each." ) ); 34450 34451// Limit the size of all files in a FileList. 34452$.validator.addMethod( "maxsizetotal", function( value, element, param ) { 34453 if ( this.optional( element ) ) { 34454 return true; 34455 } 34456 34457 if ( $( element ).attr( "type" ) === "file" ) { 34458 if ( element.files && element.files.length ) { 34459 var totalSize = 0; 34460 34461 for ( var i = 0; i < element.files.length; i++ ) { 34462 totalSize += element.files[ i ].size; 34463 if ( totalSize > param ) { 34464 return false; 34465 } 34466 } 34467 } 34468 } 34469 34470 return true; 34471}, $.validator.format( "Total size of all files must not exceed {0} bytes." ) ); 34472 34473 34474$.validator.addMethod( "mobileNL", function( value, element ) { 34475 return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); 34476}, "Please specify a valid mobile number" ); 34477 34478$.validator.addMethod( "mobileRU", function( phone_number, element ) { 34479 var ruPhone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); 34480 return this.optional( element ) || ruPhone_number.length > 9 && /^((\+7|7|8)+([0-9]){10})$/.test( ruPhone_number ); 34481}, "Please specify a valid mobile number" ); 34482 34483/* For UK phone functions, do the following server side processing: 34484 * Compare original input with this RegEx pattern: 34485 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ 34486 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' 34487 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. 34488 * A number of very detailed GB telephone number RegEx patterns can also be found at: 34489 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers 34490 */ 34491$.validator.addMethod( "mobileUK", function( phone_number, element ) { 34492 phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); 34493 return this.optional( element ) || phone_number.length > 9 && 34494 phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ ); 34495}, "Please specify a valid mobile number" ); 34496 34497$.validator.addMethod( "netmask", function( value, element ) { 34498 return this.optional( element ) || /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test( value ); 34499}, "Please enter a valid netmask." ); 34500 34501/* 34502 * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish 34503 * authorities to any foreigner. 34504 * 34505 * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal 34506 * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to 34507 * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter. 34508 */ 34509$.validator.addMethod( "nieES", function( value, element ) { 34510 "use strict"; 34511 34512 if ( this.optional( element ) ) { 34513 return true; 34514 } 34515 34516 var nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi ); 34517 var validChars = "TRWAGMYFPDXBNJZSQVHLCKET", 34518 letter = value.substr( value.length - 1 ).toUpperCase(), 34519 number; 34520 34521 value = value.toString().toUpperCase(); 34522 34523 // Quick format test 34524 if ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) { 34525 return false; 34526 } 34527 34528 // X means same number 34529 // Y means number + 10000000 34530 // Z means number + 20000000 34531 value = value.replace( /^[X]/, "0" ) 34532 .replace( /^[Y]/, "1" ) 34533 .replace( /^[Z]/, "2" ); 34534 34535 number = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 ); 34536 34537 return validChars.charAt( parseInt( number, 10 ) % 23 ) === letter; 34538 34539}, "Please specify a valid NIE number." ); 34540 34541/* 34542 * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals 34543 */ 34544$.validator.addMethod( "nifES", function( value, element ) { 34545 "use strict"; 34546 34547 if ( this.optional( element ) ) { 34548 return true; 34549 } 34550 34551 value = value.toUpperCase(); 34552 34553 // Basic format test 34554 if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) { 34555 return false; 34556 } 34557 34558 // Test NIF 34559 if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) { 34560 return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) ); 34561 } 34562 34563 // Test specials NIF (starts with K, L or M) 34564 if ( /^[KLM]{1}/.test( value ) ) { 34565 return ( value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 1 ) % 23 ) ); 34566 } 34567 34568 return false; 34569 34570}, "Please specify a valid NIF number." ); 34571 34572/* 34573 * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies 34574 */ 34575$.validator.addMethod( "nipPL", function( value ) { 34576 "use strict"; 34577 34578 value = value.replace( /[^0-9]/g, "" ); 34579 34580 if ( value.length !== 10 ) { 34581 return false; 34582 } 34583 34584 var arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ]; 34585 var intSum = 0; 34586 for ( var i = 0; i < 9; i++ ) { 34587 intSum += arrSteps[ i ] * value[ i ]; 34588 } 34589 var int2 = intSum % 11; 34590 var intControlNr = ( int2 === 10 ) ? 0 : int2; 34591 34592 return ( intControlNr === parseInt( value[ 9 ], 10 ) ); 34593}, "Please specify a valid NIP number." ); 34594 34595/** 34596 * Created for project jquery-validation. 34597 * @Description Brazillian PIS or NIS number (Número de Identificação Social Pis ou Pasep) is the equivalent of a 34598 * Brazilian tax registration number NIS of PIS numbers have 11 digits in total: 10 numbers followed by 1 check numbers 34599 * that are being used for validation. 34600 * @copyright (c) 21/08/2018 13:14, Cleiton da Silva Mendonça 34601 * @author Cleiton da Silva Mendonça <[email protected]> 34602 * @link http://gitlab.com/csmendonca Gitlab of Cleiton da Silva Mendonça 34603 * @link http://github.com/csmendonca Github of Cleiton da Silva Mendonça 34604 */ 34605$.validator.addMethod( "nisBR", function( value ) { 34606 var number; 34607 var cn; 34608 var sum = 0; 34609 var dv; 34610 var count; 34611 var multiplier; 34612 34613 // Removing special characters from value 34614 value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); 34615 34616 // Checking value to have 11 digits only 34617 if ( value.length !== 11 ) { 34618 return false; 34619 } 34620 34621 //Get check number of value 34622 cn = parseInt( value.substring( 10, 11 ), 10 ); 34623 34624 //Get number with 10 digits of the value 34625 number = parseInt( value.substring( 0, 10 ), 10 ); 34626 34627 for ( count = 2; count < 12; count++ ) { 34628 multiplier = count; 34629 if ( count === 10 ) { 34630 multiplier = 2; 34631 } 34632 if ( count === 11 ) { 34633 multiplier = 3; 34634 } 34635 sum += ( ( number % 10 ) * multiplier ); 34636 number = parseInt( number / 10, 10 ); 34637 } 34638 dv = ( sum % 11 ); 34639 34640 if ( dv > 1 ) { 34641 dv = ( 11 - dv ); 34642 } else { 34643 dv = 0; 34644 } 34645 34646 if ( cn === dv ) { 34647 return true; 34648 } else { 34649 return false; 34650 } 34651}, "Please specify a valid NIS/PIS number" ); 34652 34653$.validator.addMethod( "notEqualTo", function( value, element, param ) { 34654 return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param ); 34655}, "Please enter a different value, values must not be the same." ); 34656 34657$.validator.addMethod( "nowhitespace", function( value, element ) { 34658 return this.optional( element ) || /^\S+$/i.test( value ); 34659}, "No white space please" ); 34660 34661/** 34662* Return true if the field value matches the given format RegExp 34663* 34664* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/) 34665* @result true 34666* 34667* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/) 34668* @result false 34669* 34670* @name $.validator.methods.pattern 34671* @type Boolean 34672* @cat Plugins/Validate/Methods 34673*/ 34674$.validator.addMethod( "pattern", function( value, element, param ) { 34675 if ( this.optional( element ) ) { 34676 return true; 34677 } 34678 if ( typeof param === "string" ) { 34679 param = new RegExp( "^(?:" + param + ")$" ); 34680 } 34681 return param.test( value ); 34682}, "Invalid format." ); 34683 34684/** 34685 * Dutch phone numbers have 10 digits (or 11 and start with +31). 34686 */ 34687$.validator.addMethod( "phoneNL", function( value, element ) { 34688 return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); 34689}, "Please specify a valid phone number." ); 34690 34691/** 34692 * Polish telephone numbers have 9 digits. 34693 * 34694 * Mobile phone numbers starts with following digits: 34695 * 45, 50, 51, 53, 57, 60, 66, 69, 72, 73, 78, 79, 88. 34696 * 34697 * Fixed-line numbers starts with area codes: 34698 * 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 29, 32, 33, 34699 * 34, 41, 42, 43, 44, 46, 48, 52, 54, 55, 56, 58, 59, 61, 34700 * 62, 63, 65, 67, 68, 71, 74, 75, 76, 77, 81, 82, 83, 84, 34701 * 85, 86, 87, 89, 91, 94, 95. 34702 * 34703 * Ministry of National Defence numbers and VoIP numbers starts with 26 and 39. 34704 * 34705 * Excludes intelligent networks (premium rate, shared cost, free phone numbers). 34706 * 34707 * Poland National Numbering Plan http://www.itu.int/oth/T02020000A8/en 34708 */ 34709$.validator.addMethod( "phonePL", function( phone_number, element ) { 34710 phone_number = phone_number.replace( /\s+/g, "" );
34711 var regexp = /^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/; 34712 return this.optional( element ) || regexp.test( phone_number ); 34713}, "Please specify a valid phone number" ); 34714 34715/* For UK phone functions, do the following server side processing: 34716 * Compare original input with this RegEx pattern: 34717 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ 34718 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' 34719 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. 34720 * A number of very detailed GB telephone number RegEx patterns can also be found at: 34721 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers 34722 */ 34723 34724// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers 34725$.validator.addMethod( "phonesUK", function( phone_number, element ) { 34726 phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); 34727 return this.optional( element ) || phone_number.length > 9 && 34728 phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ ); 34729}, "Please specify a valid uk phone number" ); 34730 34731/* For UK phone functions, do the following server side processing: 34732 * Compare original input with this RegEx pattern: 34733 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ 34734 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' 34735 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. 34736 * A number of very detailed GB telephone number RegEx patterns can also be found at: 34737 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers 34738 */ 34739$.validator.addMethod( "phoneUK", function( phone_number, element ) { 34740 phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); 34741 return this.optional( element ) || phone_number.length > 9 && 34742 phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ ); 34743}, "Please specify a valid phone number" ); 34744 34745/** 34746 * Matches US phone number format 34747 * 34748 * where the area code may not start with 1 and the prefix may not start with 1 34749 * allows '-' or ' ' as a separator and allows parens around area code 34750 * some people may want to put a '1' in front of their number 34751 * 34752 * 1(212)-999-2345 or 34753 * 212 999 2344 or 34754 * 212-999-0983 34755 * 34756 * but not 34757 * 111-123-5434 34758 * and not 34759 * 212 123 4567 34760 */ 34761$.validator.addMethod( "phoneUS", function( phone_number, element ) { 34762 phone_number = phone_number.replace( /\s+/g, "" ); 34763 return this.optional( element ) || phone_number.length > 9 && 34764 phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/ ); 34765}, "Please specify a valid phone number" ); 34766 34767/* 34768* Valida CEPs do brasileiros: 34769* 34770* Formatos aceitos: 34771* 99999-999 34772* 99.999-999 34773* 99999999 34774*/ 34775$.validator.addMethod( "postalcodeBR", function( cep_value, element ) { 34776 return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value ); 34777}, "Informe um CEP válido." ); 34778 34779/** 34780 * Matches a valid Canadian Postal Code 34781 * 34782 * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element ) 34783 * @result true 34784 * 34785 * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element ) 34786 * @result false 34787 * 34788 * @name jQuery.validator.methods.postalCodeCA 34789 * @type Boolean 34790 * @cat Plugins/Validate/Methods 34791 */ 34792$.validator.addMethod( "postalCodeCA", function( value, element ) { 34793 return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value ); 34794}, "Please specify a valid postal code" ); 34795 34796/* Matches Italian postcode (CAP) */ 34797$.validator.addMethod( "postalcodeIT", function( value, element ) { 34798 return this.optional( element ) || /^\d{5}$/.test( value ); 34799}, "Please specify a valid postal code" ); 34800 34801$.validator.addMethod( "postalcodeNL", function( value, element ) { 34802 return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value ); 34803}, "Please specify a valid postal code" ); 34804 34805// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK) 34806$.validator.addMethod( "postcodeUK", function( value, element ) { 34807 return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value ); 34808}, "Please specify a valid UK postcode
vendor: 5,517 bytes, lines 34808-34945
34808" ); 34809 34810/* 34811 * Lets you say "at least X inputs that match selector Y must be filled." 34812 * 34813 * The end result is that neither of these inputs: 34814 * 34815 * <input class="productinfo" name="partnumber"> 34816 * <input class="productinfo" name="description"> 34817 * 34818 * ...will validate unless at least one of them is filled. 34819 * 34820 * partnumber: {require_from_group: [1,".productinfo"]}, 34821 * description: {require_from_group: [1,".productinfo"]} 34822 * 34823 * options[0]: number of fields that must be filled in the group 34824 * options[1]: CSS selector that defines the group of conditionally required fields 34825 */ 34826$.validator.addMethod( "require_from_group", function( value, element, options ) { 34827 var $fields = $( options[ 1 ], element.form ), 34828 $fieldsFirst = $fields.eq( 0 ), 34829 validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ), 34830 isValid = $fields.filter( function() { 34831 return validator.elementValue( this ); 34832 } ).length >= options[ 0 ]; 34833 34834 // Store the cloned validator for future validation 34835 $fieldsFirst.data( "valid_req_grp", validator ); 34836 34837 // If element isn't being validated, run each require_from_group field's validation rules 34838 if ( !$( element ).data( "being_validated" ) ) { 34839 $fields.data( "being_validated", true ); 34840 $fields.each( function() { 34841 validator.element( this ); 34842 } ); 34843 $fields.data( "being_validated", false ); 34844 } 34845 return isValid; 34846}, $.validator.format( "Please fill at least {0} of these fields." ) ); 34847 34848/* 34849 * Lets you say "either at least X inputs that match selector Y must be filled, 34850 * OR they must all be skipped (left blank)." 34851 * 34852 * The end result, is that none of these inputs: 34853 * 34854 * <input class="productinfo" name="partnumber"> 34855 * <input class="productinfo" name="description"> 34856 * <input class="productinfo" name="color"> 34857 * 34858 * ...will validate unless either at least two of them are filled, 34859 * OR none of them are. 34860 * 34861 * partnumber: {skip_or_fill_minimum: [2,".productinfo"]}, 34862 * description: {skip_or_fill_minimum: [2,".productinfo"]}, 34863 * color: {skip_or_fill_minimum: [2,".productinfo"]} 34864 * 34865 * options[0]: number of fields that must be filled in the group 34866 * options[1]: CSS selector that defines the group of conditionally required fields 34867 * 34868 */ 34869$.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) { 34870 var $fields = $( options[ 1 ], element.form ), 34871 $fieldsFirst = $fields.eq( 0 ), 34872 validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ), 34873 numberFilled = $fields.filter( function() { 34874 return validator.elementValue( this ); 34875 } ).length, 34876 isValid = numberFilled === 0 || numberFilled >= options[ 0 ]; 34877 34878 // Store the cloned validator for future validation 34879 $fieldsFirst.data( "valid_skip", validator ); 34880 34881 // If element isn't being validated, run each skip_or_fill_minimum field's validation rules 34882 if ( !$( element ).data( "being_validated" ) ) { 34883 $fields.data( "being_validated", true ); 34884 $fields.each( function() { 34885 validator.element( this ); 34886 } ); 34887 $fields.data( "being_validated", false ); 34888 } 34889 return isValid; 34890}, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) ); 34891 34892/* Validates US States and/or Territories by @jdforsythe 34893 * Can be case insensitive or require capitalization - default is case insensitive 34894 * Can include US Territories or not - default does not 34895 * Can include US Military postal abbreviations (AA, AE, AP) - default does not 34896 * 34897 * Note: "States" always includes DC (District of Colombia) 34898 * 34899 * Usage examples: 34900 * 34901 * This is the default - case insensitive, no territories, no military zones 34902 * stateInput: { 34903 * caseSensitive: false, 34904 * includeTerritories: false, 34905 * includeMilitary: false 34906 * } 34907 * 34908 * Only allow capital letters, no territories, no military zones 34909 * stateInput: { 34910 * caseSensitive: false 34911 * } 34912 * 34913 * Case insensitive, include territories but not military zones 34914 * stateInput: { 34915 * includeTerritories: true 34916 * } 34917 * 34918 * Only allow capital letters, include territories and military zones 34919 * stateInput: { 34920 * caseSensitive: true, 34921 * includeTerritories: true, 34922 * includeMilitary: true 34923 * } 34924 * 34925 */ 34926$.validator.addMethod( "stateUS", function( value, element, options ) { 34927 var isDefault = typeof options === "undefined", 34928 caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive, 34929 includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories, 34930 includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary, 34931 regex; 34932 34933 if ( !includeTerritories && !includeMilitary ) { 34934 regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; 34935 } else if ( includeTerritories && includeMilitary ) { 34936 regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; 34937 } else if ( includeTerritories ) { 34938 regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; 34939 } else { 34940 regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; 34941 } 34942 34943 regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" ); 34944 return this.optional( element ) || regex.test( value ); 34945}, "Please specify a valid state
vendor: 2,891 bytes, lines 34945-34986
34945" ); 34946 34947// TODO check if value starts with <, otherwise don't try stripping anything 34948$.validator.addMethod( "strippedminlength", function( value, element, param ) { 34949 return $( value ).text().length >= param; 34950}, $.validator.format( "Please enter at least {0} characters" ) ); 34951 34952$.validator.addMethod( "time", function( value, element ) { 34953 return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value ); 34954}, "Please enter a valid time, between 00:00 and 23:59" ); 34955 34956$.validator.addMethod( "time12h", function( value, element ) { 34957 return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value ); 34958}, "Please enter a valid time in 12-hour am/pm format" ); 34959 34960// Same as url, but TLD is optional 34961$.validator.addMethod( "url2", function( value, element ) { 34962 return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value ); 34963}, $.validator.messages.url ); 34964 34965/** 34966 * Return true, if the value is a valid vehicle identification number (VIN). 34967 * 34968 * Works with all kind of text inputs. 34969 * 34970 * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" /> 34971 * @desc Declares a required input element whose value must be a valid vehicle identification number. 34972 * 34973 * @name $.validator.methods.vinUS 34974 * @type Boolean 34975 * @cat Plugins/Validate/Methods 34976 */ 34977$.validator.addMethod( "vinUS", function( v ) { 34978 if ( v.length !== 17 ) { 34979 return false; 34980 } 34981 34982 var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ], 34983 VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ], 34984 FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ], 34985 rs = 0, 34986 i, n, d, f, cd, cdv;
34987 34988 for ( i = 0; i < 17; i++ ) { 34989 f = FL[ i ]; 34990 d = v.slice( i, i + 1 ); 34991 if ( i === 8 ) { 34992 cdv = d; 34993 } 34994 if ( !isNaN( d ) ) { 34995 d *= f; 34996 } else { 34997 for ( n = 0; n < LL.length; n++ ) { 34998 if ( d.toUpperCase() === LL[ n ] ) { 34999 d = VL[ n ]; 35000 d *= f; 35001 if ( isNaN( cdv ) && n === 8 ) { 35002 cdv = LL[ n ]; 35003 } 35004 break; 35005 } 35006 } 35007 } 35008 rs += d; 35009 } 35010 cd = rs % 11; 35011 if ( cd === 10 ) { 35012 cd = "X"; 35013 } 35014 if ( cd === cdv ) { 35015 return true; 35016 } 35017 return false; 35018}, "The specified vehicle identification number (VIN) is invalid." ); 35019 35020$.validator.addMethod( "zipcodeUS", function( value, element ) { 35021 return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value ); 35022}, "The specified US ZIP Code is invalid" ); 35023 35024$.validator.addMethod( "ziprange", function( value, element ) { 35025 return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value ); 35026}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" ); 35027return $; 35028})); 35029/* ======================================================================== 35030 * Bootstrap: transition.js v3.3.5 35031 * http://getbootstrap.com/javascript/#transitions 35032 * ======================================================================== 35033 * Copyright 2011-2015 Twitter, Inc. 35034 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35035 * ======================================================================== */ 35036 35037 35038 35039+function ($) { 35040 'use strict'; 35041 35042 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 35043 // ============================================================ 35044 35045 function transitionEnd() { 35046 var el = document.createElement('bootstrap') 35047 35048 var transEndEventNames = { 35049 WebkitTransition : 'webkitTransitionEnd', 35050 MozTransition : 'transitionend', 35051 OTransition : 'oTransitionEnd otransitionend', 35052 transition : 'transitionend' 35053 } 35054 35055 for (var name in transEndEventNames) { 35056 if (el.style[name] !== undefined) { 35057 return { end: transEndEventNames[name] } 35058 } 35059 } 35060 35061 return false // explicit for ie8 ( ._.) 35062 } 35063 35064 // http://blog.alexmaccaw.com/css-transitions 35065 $.fn.emulateTransitionEnd = function (duration) { 35066 var called = false 35067 var $el = this 35068 $(this).one('bsTransitionEnd', function () { called = true }) 35069 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 35070 setTimeout(callback, duration) 35071 return this 35072 } 35073 35074 $(function () { 35075 $.support.transition = transitionEnd() 35076 35077 if (!$.support.transition) return 35078 35079 $.event.special.bsTransitionEnd = { 35080 bindType: $.support.transition.end, 35081 delegateType: $.support.transition.end, 35082 handle: function (e) { 35083 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 35084 } 35085 } 35086 }) 35087 35088}(jQuery); 35089/* ======================================================================== 35090 * Bootstrap: alert.js v3.3.5 35091 * http://getbootstrap.com/javascript/#alerts 35092 * ======================================================================== 35093 * Copyright 2011-2015 Twitter, Inc. 35094 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35095 * ======================================================================== */ 35096 35097 35098 35099+function ($) { 35100 'use strict'; 35101 35102 // ALERT CLASS DEFINITION 35103 // ====================== 35104 35105 var dismiss = '[data-dismiss="alert"]' 35106 var Alert = function (el) { 35107 $(el).on('click', dismiss, this.close) 35108 } 35109 35110 Alert.VERSION = '3.3.5' 35111 35112 Alert.TRANSITION_DURATION = 150 35113 35114 Alert.prototype.close = function (e) { 35115 var $this = $(this) 35116 var selector = $this.attr('data-target') 35117 35118 if (!selector) { 35119 selector = $this.attr('href') 35120 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 35121 } 35122 35123 var $parent = $(selector) 35124 35125 if (e) e.preventDefault() 35126 35127 if (!$parent.length) { 35128 $parent = $this.closest('.alert') 35129 } 35130 35131 $parent.trigger(e = $.Event('close.bs.alert')) 35132 35133 if (e.isDefaultPrevented()) return 35134 35135 $parent.removeClass('in') 35136 35137 function removeElement() { 35138 // detach from parent, fire event then clean up data 35139 $parent.detach().trigger('closed.bs.alert').remove() 35140 } 35141 35142 $.support.transition && $parent.hasClass('fade') ? 35143 $parent 35144 .one('bsTransitionEnd', removeElement) 35145 .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 35146 removeElement() 35147 } 35148 35149 35150 // ALERT PLUGIN DEFINITION 35151 // ======================= 35152 35153 function Plugin(option) { 35154 return this.each(function () { 35155 var $this = $(this) 35156 var data = $this.data('bs.alert') 35157
vendor: 4,196 bytes, lines 35158-35307
35158 if (!data) $this.data('bs.alert', (data = new Alert(this))) 35159 if (typeof option == 'string') data[option].call($this) 35160 }) 35161 } 35162 35163 var old = $.fn.alert 35164 35165 $.fn.alert = Plugin 35166 $.fn.alert.Constructor = Alert 35167 35168 35169 // ALERT NO CONFLICT 35170 // ================= 35171 35172 $.fn.alert.noConflict = function () { 35173 $.fn.alert = old 35174 return this 35175 } 35176 35177 35178 // ALERT DATA-API 35179 // ============== 35180 35181 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 35182 35183}(jQuery); 35184/* ======================================================================== 35185 * Bootstrap: button.js v3.3.5 35186 * http://getbootstrap.com/javascript/#buttons 35187 * ======================================================================== 35188 * Copyright 2011-2015 Twitter, Inc. 35189 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35190 * ======================================================================== */ 35191 35192 35193 35194+function ($) { 35195 'use strict'; 35196 35197 // BUTTON PUBLIC CLASS DEFINITION 35198 // ============================== 35199 35200 var Button = function (element, options) { 35201 this.$element = $(element) 35202 this.options = $.extend({}, Button.DEFAULTS, options) 35203 this.isLoading = false 35204 } 35205 35206 Button.VERSION = '3.3.5' 35207 35208 Button.DEFAULTS = { 35209 loadingText: 'loading...' 35210 } 35211 35212 Button.prototype.setState = function (state) { 35213 var d = 'disabled' 35214 var $el = this.$element 35215 var val = $el.is('input') ? 'val' : 'html' 35216 var data = $el.data() 35217 35218 state += 'Text' 35219 35220 if (data.resetText == null) $el.data('resetText', $el[val]()) 35221 35222 // push to event loop to allow forms to submit 35223 setTimeout($.proxy(function () { 35224 $el[val](data[state] == null ? this.options[state] : data[state]) 35225 35226 if (state == 'loadingText') { 35227 this.isLoading = true 35228 $el.addClass(d).attr(d, d) 35229 } else if (this.isLoading) { 35230 this.isLoading = false 35231 $el.removeClass(d).removeAttr(d) 35232 } 35233 }, this), 0) 35234 } 35235 35236 Button.prototype.toggle = function () { 35237 var changed = true 35238 var $parent = this.$element.closest('[data-toggle="buttons"]') 35239 35240 if ($parent.length) { 35241 var $input = this.$element.find('input') 35242 if ($input.prop('type') == 'radio') { 35243 if ($input.prop('checked')) changed = false 35244 $parent.find('.active').removeClass('active') 35245 this.$element.addClass('active') 35246 } else if ($input.prop('type') == 'checkbox') { 35247 if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false 35248 this.$element.toggleClass('active') 35249 } 35250 $input.prop('checked', this.$element.hasClass('active')) 35251 if (changed) $input.trigger('change') 35252 } else { 35253 this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 35254 this.$element.toggleClass('active') 35255 } 35256 } 35257 35258 35259 // BUTTON PLUGIN DEFINITION 35260 // ======================== 35261 35262 function Plugin(option) { 35263 return this.each(function () { 35264 var $this = $(this) 35265 var data = $this.data('bs.button') 35266 var options = typeof option == 'object' && option 35267 35268 if (!data) $this.data('bs.button', (data = new Button(this, options))) 35269 35270 if (option == 'toggle') data.toggle() 35271 else if (option) data.setState(option) 35272 }) 35273 } 35274 35275 var old = $.fn.button 35276 35277 $.fn.button = Plugin 35278 $.fn.button.Constructor = Button 35279 35280 35281 // BUTTON NO CONFLICT 35282 // ================== 35283 35284 $.fn.button.noConflict = function () { 35285 $.fn.button = old 35286 return this 35287 } 35288 35289 35290 // BUTTON DATA-API 35291 // =============== 35292 35293 $(document) 35294 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 35295 var $btn = $(e.target) 35296 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 35297 Plugin.call($btn, 'toggle') 35298 if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() 35299 }) 35300 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 35301 $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 35302 }) 35303 35304}(jQuery); 35305/* ======================================================================== 35306 * Bootstrap: carousel.js v3.3.5 35307 * http://getbootstrap.com/javascript/#carousel
vendor: 4,376 bytes, lines 35308-35449
35308 * ======================================================================== 35309 * Copyright 2011-2015 Twitter, Inc. 35310 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35311 * ======================================================================== */ 35312 35313 35314 35315+function ($) { 35316 'use strict'; 35317 35318 // CAROUSEL CLASS DEFINITION 35319 // ========================= 35320 35321 var Carousel = function (element, options) { 35322 this.$element = $(element) 35323 this.$indicators = this.$element.find('.carousel-indicators') 35324 this.options = options 35325 this.paused = null 35326 this.sliding = null 35327 this.interval = null 35328 this.$active = null 35329 this.$items = null 35330 35331 this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) 35332 35333 this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element 35334 .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 35335 .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 35336 } 35337 35338 Carousel.VERSION = '3.3.5' 35339 35340 Carousel.TRANSITION_DURATION = 600 35341 35342 Carousel.DEFAULTS = { 35343 interval: 5000, 35344 pause: 'hover', 35345 wrap: true, 35346 keyboard: true 35347 } 35348 35349 Carousel.prototype.keydown = function (e) { 35350 if (/input|textarea/i.test(e.target.tagName)) return 35351 switch (e.which) { 35352 case 37: this.prev(); break 35353 case 39: this.next(); break 35354 default: return 35355 } 35356 35357 e.preventDefault() 35358 } 35359 35360 Carousel.prototype.cycle = function (e) { 35361 e || (this.paused = false) 35362 35363 this.interval && clearInterval(this.interval) 35364 35365 this.options.interval 35366 && !this.paused 35367 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 35368 35369 return this 35370 } 35371 35372 Carousel.prototype.getItemIndex = function (item) { 35373 this.$items = item.parent().children('.item') 35374 return this.$items.index(item || this.$active) 35375 } 35376 35377 Carousel.prototype.getItemForDirection = function (direction, active) { 35378 var activeIndex = this.getItemIndex(active) 35379 var willWrap = (direction == 'prev' && activeIndex === 0) 35380 || (direction == 'next' && activeIndex == (this.$items.length - 1)) 35381 if (willWrap && !this.options.wrap) return active 35382 var delta = direction == 'prev' ? -1 : 1 35383 var itemIndex = (activeIndex + delta) % this.$items.length 35384 return this.$items.eq(itemIndex) 35385 } 35386 35387 Carousel.prototype.to = function (pos) { 35388 var that = this 35389 var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 35390 35391 if (pos > (this.$items.length - 1) || pos < 0) return 35392 35393 if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 35394 if (activeIndex == pos) return this.pause().cycle() 35395 35396 return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) 35397 } 35398 35399 Carousel.prototype.pause = function (e) { 35400 e || (this.paused = true) 35401 35402 if (this.$element.find('.next, .prev').length && $.support.transition) { 35403 this.$element.trigger($.support.transition.end) 35404 this.cycle(true) 35405 } 35406 35407 this.interval = clearInterval(this.interval) 35408 35409 return this 35410 } 35411 35412 Carousel.prototype.next = function () { 35413 if (this.sliding) return 35414 return this.slide('next') 35415 } 35416 35417 Carousel.prototype.prev = function () { 35418 if (this.sliding) return 35419 return this.slide('prev') 35420 } 35421 35422 Carousel.prototype.slide = function (type, next) { 35423 var $active = this.$element.find('.item.active') 35424 var $next = next || this.getItemForDirection(type, $active) 35425 var isCycling = this.interval 35426 var direction = type == 'next' ? 'left' : 'right' 35427 var that = this 35428 35429 if ($next.hasClass('active')) return (this.sliding = false) 35430 35431 var relatedTarget = $next[0] 35432 var slideEvent = $.Event('slide.bs.carousel', { 35433 relatedTarget: relatedTarget, 35434 direction: direction 35435 }) 35436 this.$element.trigger(slideEvent) 35437 if (slideEvent.isDefaultPrevented()) return 35438 35439 this.sliding = true 35440 35441 isCycling && this.pause() 35442 35443 if (this.$indicators.length) { 35444 this.$indicators.find('.active').removeClass('active') 35445 var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 35446 $nextIndicator && $nextIndicator.addClass('active') 35447 } 35448 35449 var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
vendor: 23,719 bytes, lines 35450-36266
35450 if ($.support.transition && this.$element.hasClass('slide')) { 35451 $next.addClass(type) 35452 $next[0].offsetWidth // force reflow 35453 $active.addClass(direction) 35454 $next.addClass(direction) 35455 $active 35456 .one('bsTransitionEnd', function () { 35457 $next.removeClass([type, direction].join(' ')).addClass('active') 35458 $active.removeClass(['active', direction].join(' ')) 35459 that.sliding = false 35460 setTimeout(function () { 35461 that.$element.trigger(slidEvent) 35462 }, 0) 35463 }) 35464 .emulateTransitionEnd(Carousel.TRANSITION_DURATION) 35465 } else { 35466 $active.removeClass('active') 35467 $next.addClass('active') 35468 this.sliding = false 35469 this.$element.trigger(slidEvent) 35470 } 35471 35472 isCycling && this.cycle() 35473 35474 return this 35475 } 35476 35477 35478 // CAROUSEL PLUGIN DEFINITION 35479 // ========================== 35480 35481 function Plugin(option) { 35482 return this.each(function () { 35483 var $this = $(this) 35484 var data = $this.data('bs.carousel') 35485 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 35486 var action = typeof option == 'string' ? option : options.slide 35487 35488 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 35489 if (typeof option == 'number') data.to(option) 35490 else if (action) data[action]() 35491 else if (options.interval) data.pause().cycle() 35492 }) 35493 } 35494 35495 var old = $.fn.carousel 35496 35497 $.fn.carousel = Plugin 35498 $.fn.carousel.Constructor = Carousel 35499 35500 35501 // CAROUSEL NO CONFLICT 35502 // ==================== 35503 35504 $.fn.carousel.noConflict = function () { 35505 $.fn.carousel = old 35506 return this 35507 } 35508 35509 35510 // CAROUSEL DATA-API 35511 // ================= 35512 35513 var clickHandler = function (e) { 35514 var href 35515 var $this = $(this) 35516 var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 35517 if (!$target.hasClass('carousel')) return 35518 var options = $.extend({}, $target.data(), $this.data()) 35519 var slideIndex = $this.attr('data-slide-to') 35520 if (slideIndex) options.interval = false 35521 35522 Plugin.call($target, options) 35523 35524 if (slideIndex) { 35525 $target.data('bs.carousel').to(slideIndex) 35526 } 35527 35528 e.preventDefault() 35529 } 35530 35531 $(document) 35532 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) 35533 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) 35534 35535 $(window).on('load', function () { 35536 $('[data-ride="carousel"]').each(function () { 35537 var $carousel = $(this) 35538 Plugin.call($carousel, $carousel.data()) 35539 }) 35540 }) 35541 35542}(jQuery); 35543/* ======================================================================== 35544 * Bootstrap: collapse.js v3.3.5 35545 * http://getbootstrap.com/javascript/#collapse 35546 * ======================================================================== 35547 * Copyright 2011-2015 Twitter, Inc. 35548 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35549 * ======================================================================== */ 35550 35551 35552 35553+function ($) { 35554 'use strict'; 35555 35556 // COLLAPSE PUBLIC CLASS DEFINITION 35557 // ================================ 35558 35559 var Collapse = function (element, options) { 35560 this.$element = $(element) 35561 this.options = $.extend({}, Collapse.DEFAULTS, options) 35562 this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + 35563 '[data-toggle="collapse"][data-target="#' + element.id + '"]') 35564 this.transitioning = null 35565 35566 if (this.options.parent) { 35567 this.$parent = this.getParent() 35568 } else { 35569 this.addAriaAndCollapsedClass(this.$element, this.$trigger) 35570 } 35571 35572 if (this.options.toggle) this.toggle() 35573 } 35574 35575 Collapse.VERSION = '3.3.5' 35576 35577 Collapse.TRANSITION_DURATION = 350 35578 35579 Collapse.DEFAULTS = { 35580 toggle: true 35581 } 35582 35583 Collapse.prototype.dimension = function () { 35584 var hasWidth = this.$element.hasClass('width') 35585 return hasWidth ? 'width' : 'height' 35586 } 35587 35588 Collapse.prototype.show = function () { 35589 if (this.transitioning || this.$element.hasClass('in')) return 35590 35591 var activesData 35592 var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 35593 35594 if (actives && actives.length) { 35595 activesData = actives.data('bs.collapse') 35596 if (activesData && activesData.transitioning) return 35597 } 35598 35599 var startEvent = $.Event('show.bs.collapse') 35600 this.$element.trigger(startEvent) 35601 if (startEvent.isDefaultPrevented()) return 35602 35603 if (actives && actives.length) { 35604 Plugin.call(actives, 'hide') 35605 activesData || actives.data('bs.collapse', null) 35606 } 35607 35608 var dimension = this.dimension() 35609 35610 this.$element 35611 .removeClass('collapse') 35612 .addClass('collapsing')[dimension](0) 35613 .attr('aria-expanded', true) 35614 35615 this.$trigger 35616 .removeClass('collapsed') 35617 .attr('aria-expanded', true) 35618 35619 this.transitioning = 1 35620 35621 var complete = function () { 35622 this.$element 35623 .removeClass('collapsing') 35624 .addClass('collapse in')[dimension]('') 35625 this.transitioning = 0 35626 this.$element 35627 .trigger('shown.bs.collapse') 35628 } 35629 35630 if (!$.support.transition) return complete.call(this) 35631 35632 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 35633 35634 this.$element 35635 .one('bsTransitionEnd', $.proxy(complete, this)) 35636 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 35637 } 35638 35639 Collapse.prototype.hide = function () { 35640 if (this.transitioning || !this.$element.hasClass('in')) return 35641 35642 var startEvent = $.Event('hide.bs.collapse') 35643 this.$element.trigger(startEvent) 35644 if (startEvent.isDefaultPrevented()) return 35645 35646 var dimension = this.dimension() 35647 35648 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 35649 35650 this.$element 35651 .addClass('collapsing') 35652 .removeClass('collapse in') 35653 .attr('aria-expanded', false) 35654 35655 this.$trigger 35656 .addClass('collapsed') 35657 .attr('aria-expanded', false) 35658 35659 this.transitioning = 1 35660 35661 var complete = function () { 35662 this.transitioning = 0 35663 this.$element 35664 .removeClass('collapsing') 35665 .addClass('collapse') 35666 .trigger('hidden.bs.collapse') 35667 } 35668 35669 if (!$.support.transition) return complete.call(this) 35670 35671 this.$element 35672 [dimension](0) 35673 .one('bsTransitionEnd', $.proxy(complete, this)) 35674 .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 35675 } 35676 35677 Collapse.prototype.toggle = function () { 35678 this[this.$element.hasClass('in') ? 'hide' : 'show']() 35679 } 35680 35681 Collapse.prototype.getParent = function () { 35682 return $(this.options.parent) 35683 .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 35684 .each($.proxy(function (i, element) { 35685 var $element = $(element) 35686 this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 35687 }, this)) 35688 .end() 35689 } 35690 35691 Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 35692 var isOpen = $element.hasClass('in') 35693 35694 $element.attr('aria-expanded', isOpen) 35695 $trigger 35696 .toggleClass('collapsed', !isOpen) 35697 .attr('aria-expanded', isOpen) 35698 } 35699 35700 function getTargetFromTrigger($trigger) { 35701 var href 35702 var target = $trigger.attr('data-target') 35703 || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 35704 35705 return $(target) 35706 } 35707 35708 35709 // COLLAPSE PLUGIN DEFINITION 35710 // ========================== 35711 35712 function Plugin(option) { 35713 return this.each(function () { 35714 var $this = $(this) 35715 var data = $this.data('bs.collapse') 35716 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 35717 35718 if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false 35719 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 35720 if (typeof option == 'string') data[option]() 35721 }) 35722 } 35723 35724 var old = $.fn.collapse 35725 35726 $.fn.collapse = Plugin 35727 $.fn.collapse.Constructor = Collapse 35728 35729 35730 // COLLAPSE NO CONFLICT 35731 // ==================== 35732 35733 $.fn.collapse.noConflict = function () { 35734 $.fn.collapse = old 35735 return this 35736 } 35737 35738 35739 // COLLAPSE DATA-API 35740 // ================= 35741 35742 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 35743 var $this = $(this) 35744 35745 if (!$this.attr('data-target')) e.preventDefault() 35746 35747 var $target = getTargetFromTrigger($this) 35748 var data = $target.data('bs.collapse') 35749 var option = data ? 'toggle' : $this.data() 35750 35751 Plugin.call($target, option) 35752 }) 35753 35754}(jQuery); 35755/* ======================================================================== 35756 * Bootstrap: dropdown.js v3.3.5 35757 * http://getbootstrap.com/javascript/#dropdowns 35758 * ======================================================================== 35759 * Copyright 2011-2015 Twitter, Inc. 35760 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35761 * ======================================================================== */ 35762 35763 35764 35765+function ($) { 35766 'use strict'; 35767 35768 // DROPDOWN CLASS DEFINITION 35769 // ========================= 35770 35771 var backdrop = '.dropdown-backdrop' 35772 var toggle = '[data-toggle="dropdown"]' 35773 var Dropdown = function (element) { 35774 $(element).on('click.bs.dropdown', this.toggle) 35775 } 35776 35777 Dropdown.VERSION = '3.3.5' 35778 35779 function getParent($this) { 35780 var selector = $this.attr('data-target') 35781 35782 if (!selector) { 35783 selector = $this.attr('href') 35784 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 35785 } 35786 35787 var $parent = selector && $(selector) 35788 35789 return $parent && $parent.length ? $parent : $this.parent() 35790 } 35791 35792 function clearMenus(e) { 35793 if (e && e.which === 3) return 35794 $(backdrop).remove() 35795 $(toggle).each(function () { 35796 var $this = $(this) 35797 var $parent = getParent($this) 35798 var relatedTarget = { relatedTarget: this } 35799 35800 if (!$parent.hasClass('open')) return 35801 35802 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return 35803 35804 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) 35805 35806 if (e.isDefaultPrevented()) return 35807 35808 $this.attr('aria-expanded', 'false') 35809 $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) 35810 }) 35811 } 35812 35813 Dropdown.prototype.toggle = function (e) { 35814 var $this = $(this) 35815 35816 if ($this.is('.disabled, :disabled')) return 35817 35818 var $parent = getParent($this) 35819 var isActive = $parent.hasClass('open') 35820 35821 clearMenus() 35822 35823 if (!isActive) { 35824 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 35825 // if mobile we use a backdrop because click events don't delegate 35826 $(document.createElement('div')) 35827 .addClass('dropdown-backdrop') 35828 .insertAfter($(this)) 35829 .on('click', clearMenus) 35830 } 35831 35832 var relatedTarget = { relatedTarget: this } 35833 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) 35834 35835 if (e.isDefaultPrevented()) return 35836 35837 $this 35838 .trigger('focus') 35839 .attr('aria-expanded', 'true') 35840 35841 $parent 35842 .toggleClass('open') 35843 .trigger('shown.bs.dropdown', relatedTarget) 35844 } 35845 35846 return false 35847 } 35848 35849 Dropdown.prototype.keydown = function (e) { 35850 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return 35851 35852 var $this = $(this) 35853 35854 e.preventDefault() 35855 e.stopPropagation() 35856 35857 if ($this.is('.disabled, :disabled')) return 35858 35859 var $parent = getParent($this) 35860 var isActive = $parent.hasClass('open') 35861 35862 if (!isActive && e.which != 27 || isActive && e.which == 27) { 35863 if (e.which == 27) $parent.find(toggle).trigger('focus') 35864 return $this.trigger('click') 35865 } 35866 35867 var desc = ' li:not(.disabled):visible a' 35868 var $items = $parent.find('.dropdown-menu' + desc) 35869 35870 if (!$items.length) return 35871 35872 var index = $items.index(e.target) 35873 35874 if (e.which == 38 && index > 0) index-- // up 35875 if (e.which == 40 && index < $items.length - 1) index++ // down 35876 if (!~index) index = 0 35877 35878 $items.eq(index).trigger('focus') 35879 } 35880 35881 35882 // DROPDOWN PLUGIN DEFINITION 35883 // ========================== 35884 35885 function Plugin(option) { 35886 return this.each(function () { 35887 var $this = $(this) 35888 var data = $this.data('bs.dropdown') 35889 35890 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) 35891 if (typeof option == 'string') data[option].call($this) 35892 }) 35893 } 35894 35895 var old = $.fn.dropdown 35896 35897 $.fn.dropdown = Plugin 35898 $.fn.dropdown.Constructor = Dropdown 35899 35900 35901 // DROPDOWN NO CONFLICT 35902 // ==================== 35903 35904 $.fn.dropdown.noConflict = function () { 35905 $.fn.dropdown = old 35906 return this 35907 } 35908 35909 35910 // APPLY TO STANDARD DROPDOWN ELEMENTS 35911 // =================================== 35912 35913 $(document) 35914 .on('click.bs.dropdown.data-api', clearMenus) 35915 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 35916 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) 35917 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) 35918 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) 35919 35920}(jQuery); 35921/* ======================================================================== 35922 * Bootstrap: modal.js v3.3.5 35923 * http://getbootstrap.com/javascript/#modals 35924 * ======================================================================== 35925 * Copyright 2011-2015 Twitter, Inc. 35926 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35927 * ======================================================================== */ 35928 35929 35930 35931+function ($) { 35932 'use strict'; 35933 35934 // MODAL CLASS DEFINITION 35935 // ====================== 35936 35937 var Modal = function (element, options) { 35938 this.options = options 35939 this.$body = $(document.body) 35940 this.$element = $(element) 35941 this.$dialog = this.$element.find('.modal-dialog') 35942 this.$backdrop = null 35943 this.isShown = null 35944 this.originalBodyPad = null 35945 this.scrollbarWidth = 0 35946 this.ignoreBackdropClick = false 35947 35948 if (this.options.remote) { 35949 this.$element 35950 .find('.modal-content') 35951 .load(this.options.remote, $.proxy(function () { 35952 this.$element.trigger('loaded.bs.modal') 35953 }, this)) 35954 } 35955 } 35956 35957 Modal.VERSION = '3.3.5' 35958 35959 Modal.TRANSITION_DURATION = 300 35960 Modal.BACKDROP_TRANSITION_DURATION = 150 35961 35962 Modal.DEFAULTS = { 35963 backdrop: true, 35964 keyboard: true, 35965 show: true 35966 } 35967 35968 Modal.prototype.toggle = function (_relatedTarget) { 35969 return this.isShown ? this.hide() : this.show(_relatedTarget) 35970 } 35971 35972 Modal.prototype.show = function (_relatedTarget) { 35973 var that = this 35974 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) 35975 35976 this.$element.trigger(e) 35977 35978 if (this.isShown || e.isDefaultPrevented()) return 35979 35980 this.isShown = true 35981 35982 this.checkScrollbar() 35983 this.setScrollbar() 35984 this.$body.addClass('modal-open') 35985 35986 this.escape() 35987 this.resize() 35988 35989 this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) 35990 35991 this.$dialog.on('mousedown.dismiss.bs.modal', function () { 35992 that.$element.one('mouseup.dismiss.bs.modal', function (e) { 35993 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true 35994 }) 35995 }) 35996 35997 this.backdrop(function () { 35998 var transition = $.support.transition && that.$element.hasClass('fade') 35999 36000 if (!that.$element.parent().length) { 36001 that.$element.appendTo(that.$body) // don't move modals dom position 36002 } 36003 36004 that.$element 36005 .show() 36006 .scrollTop(0) 36007 36008 that.adjustDialog() 36009 36010 if (transition) { 36011 that.$element[0].offsetWidth // force reflow 36012 } 36013 36014 that.$element.addClass('in') 36015 36016 that.enforceFocus() 36017 36018 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) 36019 36020 transition ? 36021 that.$dialog // wait for modal to slide in 36022 .one('bsTransitionEnd', function () { 36023 that.$element.trigger('focus').trigger(e) 36024 }) 36025 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 36026 that.$element.trigger('focus').trigger(e) 36027 }) 36028 } 36029 36030 Modal.prototype.hide = function (e) { 36031 if (e) e.preventDefault() 36032 36033 e = $.Event('hide.bs.modal') 36034 36035 this.$element.trigger(e) 36036 36037 if (!this.isShown || e.isDefaultPrevented()) return 36038 36039 this.isShown = false 36040 36041 this.escape() 36042 this.resize() 36043 36044 $(document).off('focusin.bs.modal') 36045 36046 this.$element 36047 .removeClass('in') 36048 .off('click.dismiss.bs.modal') 36049 .off('mouseup.dismiss.bs.modal') 36050 36051 this.$dialog.off('mousedown.dismiss.bs.modal') 36052 36053 $.support.transition && this.$element.hasClass('fade') ? 36054 this.$element 36055 .one('bsTransitionEnd', $.proxy(this.hideModal, this)) 36056 .emulateTransitionEnd(Modal.TRANSITION_DURATION) : 36057 this.hideModal() 36058 } 36059 36060 Modal.prototype.enforceFocus = function () { 36061 $(document) 36062 .off('focusin.bs.modal') // guard against infinite focus loop 36063 .on('focusin.bs.modal', $.proxy(function (e) { 36064 if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { 36065 this.$element.trigger('focus') 36066 } 36067 }, this)) 36068 } 36069 36070 Modal.prototype.escape = function () { 36071 if (this.isShown && this.options.keyboard) { 36072 this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { 36073 e.which == 27 && this.hide() 36074 }, this)) 36075 } else if (!this.isShown) { 36076 this.$element.off('keydown.dismiss.bs.modal') 36077 } 36078 } 36079 36080 Modal.prototype.resize = function () { 36081 if (this.isShown) { 36082 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) 36083 } else { 36084 $(window).off('resize.bs.modal') 36085 } 36086 } 36087 36088 Modal.prototype.hideModal = function () { 36089 var that = this 36090 this.$element.hide() 36091 this.backdrop(function () { 36092 that.$body.removeClass('modal-open') 36093 that.resetAdjustments() 36094 that.resetScrollbar() 36095 that.$element.trigger('hidden.bs.modal') 36096 }) 36097 } 36098 36099 Modal.prototype.removeBackdrop = function () { 36100 this.$backdrop && this.$backdrop.remove() 36101 this.$backdrop = null 36102 } 36103 36104 Modal.prototype.backdrop = function (callback) { 36105 var that = this 36106 var animate = this.$element.hasClass('fade') ? 'fade' : '' 36107 36108 if (this.isShown && this.options.backdrop) { 36109 var doAnimate = $.support.transition && animate 36110 36111 this.$backdrop = $(document.createElement('div')) 36112 .addClass('modal-backdrop ' + animate) 36113 .appendTo(this.$body) 36114 36115 this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { 36116 if (this.ignoreBackdropClick) { 36117 this.ignoreBackdropClick = false 36118 return 36119 } 36120 if (e.target !== e.currentTarget) return 36121 this.options.backdrop == 'static' 36122 ? this.$element[0].focus() 36123 : this.hide() 36124 }, this)) 36125 36126 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow 36127 36128 this.$backdrop.addClass('in') 36129 36130 if (!callback) return 36131 36132 doAnimate ? 36133 this.$backdrop 36134 .one('bsTransitionEnd', callback) 36135 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 36136 callback() 36137 36138 } else if (!this.isShown && this.$backdrop) { 36139 this.$backdrop.removeClass('in') 36140 36141 var callbackRemove = function () { 36142 that.removeBackdrop() 36143 callback && callback() 36144 } 36145 $.support.transition && this.$element.hasClass('fade') ? 36146 this.$backdrop 36147 .one('bsTransitionEnd', callbackRemove) 36148 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : 36149 callbackRemove() 36150 36151 } else if (callback) { 36152 callback() 36153 } 36154 } 36155 36156 // these following methods are used to handle overflowing modals 36157 36158 Modal.prototype.handleUpdate = function () { 36159 this.adjustDialog() 36160 } 36161 36162 Modal.prototype.adjustDialog = function () { 36163 var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight 36164 36165 this.$element.css({ 36166 paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', 36167 paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' 36168 }) 36169 } 36170 36171 Modal.prototype.resetAdjustments = function () { 36172 this.$element.css({ 36173 paddingLeft: '', 36174 paddingRight: '' 36175 }) 36176 } 36177 36178 Modal.prototype.checkScrollbar = function () { 36179 var fullWindowWidth = window.innerWidth 36180 if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 36181 var documentElementRect = document.documentElement.getBoundingClientRect() 36182 fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) 36183 } 36184 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth 36185 this.scrollbarWidth = this.measureScrollbar() 36186 } 36187 36188 Modal.prototype.setScrollbar = function () { 36189 var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) 36190 this.originalBodyPad = document.body.style.paddingRight || '' 36191 if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) 36192 } 36193 36194 Modal.prototype.resetScrollbar = function () { 36195 this.$body.css('padding-right', this.originalBodyPad) 36196 } 36197 36198 Modal.prototype.measureScrollbar = function () { // thx walsh 36199 var scrollDiv = document.createElement('div') 36200 scrollDiv.className = 'modal-scrollbar-measure' 36201 this.$body.append(scrollDiv) 36202 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth 36203 this.$body[0].removeChild(scrollDiv) 36204 return scrollbarWidth 36205 } 36206 36207 36208 // MODAL PLUGIN DEFINITION 36209 // ======================= 36210 36211 function Plugin(option, _relatedTarget) { 36212 return this.each(function () { 36213 var $this = $(this) 36214 var data = $this.data('bs.modal') 36215 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) 36216 36217 if (!data) $this.data('bs.modal', (data = new Modal(this, options))) 36218 if (typeof option == 'string') data[option](_relatedTarget) 36219 else if (options.show) data.show(_relatedTarget) 36220 }) 36221 } 36222 36223 var old = $.fn.modal 36224 36225 $.fn.modal = Plugin 36226 $.fn.modal.Constructor = Modal 36227 36228 36229 // MODAL NO CONFLICT 36230 // ================= 36231 36232 $.fn.modal.noConflict = function () { 36233 $.fn.modal = old 36234 return this 36235 } 36236 36237 36238 // MODAL DATA-API 36239 // ============== 36240 36241 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { 36242 var $this = $(this) 36243 var href = $this.attr('href') 36244 var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 36245 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) 36246 36247 if ($this.is('a')) e.preventDefault() 36248 36249 $target.one('show.bs.modal', function (showEvent) { 36250 if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown 36251 $target.one('hidden.bs.modal', function () { 36252 $this.is(':visible') && $this.trigger('focus') 36253 }) 36254 }) 36255 Plugin.call($target, option, this) 36256 }) 36257 36258}(jQuery); 36259/* ======================================================================== 36260 * Bootstrap: tooltip.js v3.3.5 36261 * http://getbootstrap.com/javascript/#tooltip 36262 * Inspired by the original jQuery.tipsy by Jason Frame 36263 * ======================================================================== 36264 * Copyright 2011-2015 Twitter, Inc. 36265 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36266 * ======================================================================== */
vendor: 15,865 bytes, lines 36267-36773
36267 36268 36269 36270+function ($) { 36271 'use strict'; 36272 36273 // TOOLTIP PUBLIC CLASS DEFINITION 36274 // =============================== 36275 36276 var Tooltip = function (element, options) { 36277 this.type = null 36278 this.options = null 36279 this.enabled = null 36280 this.timeout = null 36281 this.hoverState = null 36282 this.$element = null 36283 this.inState = null 36284 36285 this.init('tooltip', element, options) 36286 } 36287 36288 Tooltip.VERSION = '3.3.5' 36289 36290 Tooltip.TRANSITION_DURATION = 150 36291 36292 Tooltip.DEFAULTS = { 36293 animation: true, 36294 placement: 'top', 36295 selector: false, 36296 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36297 trigger: 'hover focus', 36298 title: '', 36299 delay: 0, 36300 html: false, 36301 container: false, 36302 viewport: { 36303 selector: 'body', 36304 padding: 0 36305 } 36306 } 36307 36308 Tooltip.prototype.init = function (type, element, options) { 36309 this.enabled = true 36310 this.type = type 36311 this.$element = $(element) 36312 this.options = this.getOptions(options) 36313 this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) 36314 this.inState = { click: false, hover: false, focus: false } 36315 36316 if (this.$element[0] instanceof document.constructor && !this.options.selector) { 36317 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') 36318 } 36319 36320 var triggers = this.options.trigger.split(' ') 36321 36322 for (var i = triggers.length; i--;) { 36323 var trigger = triggers[i] 36324 36325 if (trigger == 'click') { 36326 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36327 } else if (trigger != 'manual') { 36328 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36329 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36330 36331 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36332 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36333 } 36334 } 36335 36336 this.options.selector ? 36337 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36338 this.fixTitle() 36339 } 36340 36341 Tooltip.prototype.getDefaults = function () { 36342 return Tooltip.DEFAULTS 36343 } 36344 36345 Tooltip.prototype.getOptions = function (options) { 36346 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36347 36348 if (options.delay && typeof options.delay == 'number') { 36349 options.delay = { 36350 show: options.delay, 36351 hide: options.delay 36352 } 36353 } 36354 36355 return options 36356 } 36357 36358 Tooltip.prototype.getDelegateOptions = function () { 36359 var options = {} 36360 var defaults = this.getDefaults() 36361 36362 this._options && $.each(this._options, function (key, value) { 36363 if (defaults[key] != value) options[key] = value 36364 }) 36365 36366 return options 36367 } 36368 36369 Tooltip.prototype.enter = function (obj) { 36370 var self = obj instanceof this.constructor ? 36371 obj : $(obj.currentTarget).data('bs.' + this.type) 36372 36373 if (!self) { 36374 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 36375 $(obj.currentTarget).data('bs.' + this.type, self) 36376 } 36377 36378 if (obj instanceof $.Event) { 36379 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true 36380 } 36381 36382 if (self.tip().hasClass('in') || self.hoverState == 'in') { 36383 self.hoverState = 'in' 36384 return 36385 } 36386 36387 clearTimeout(self.timeout) 36388 36389 self.hoverState = 'in' 36390 36391 if (!self.options.delay || !self.options.delay.show) return self.show() 36392 36393 self.timeout = setTimeout(function () { 36394 if (self.hoverState == 'in') self.show() 36395 }, self.options.delay.show) 36396 } 36397 36398 Tooltip.prototype.isInStateTrue = function () { 36399 for (var key in this.inState) { 36400 if (this.inState[key]) return true 36401 } 36402 36403 return false 36404 } 36405 36406 Tooltip.prototype.leave = function (obj) { 36407 var self = obj instanceof this.constructor ? 36408 obj : $(obj.currentTarget).data('bs.' + this.type) 36409 36410 if (!self) { 36411 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 36412 $(obj.currentTarget).data('bs.' + this.type, self) 36413 } 36414 36415 if (obj instanceof $.Event) { 36416 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false 36417 } 36418 36419 if (self.isInStateTrue()) return 36420 36421 clearTimeout(self.timeout) 36422 36423 self.hoverState = 'out' 36424 36425 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36426 36427 self.timeout = setTimeout(function () { 36428 if (self.hoverState == 'out') self.hide() 36429 }, self.options.delay.hide) 36430 } 36431 36432 Tooltip.prototype.show = function () { 36433 var e = $.Event('show.bs.' + this.type) 36434 36435 if (this.hasContent() && this.enabled) { 36436 this.$element.trigger(e) 36437 36438 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) 36439 if (e.isDefaultPrevented() || !inDom) return 36440 var that = this 36441 36442 var $tip = this.tip() 36443 36444 var tipId = this.getUID(this.type) 36445 36446 this.setContent() 36447 $tip.attr('id', tipId) 36448 this.$element.attr('aria-describedby', tipId) 36449 36450 if (this.options.animation) $tip.addClass('fade') 36451 36452 var placement = typeof this.options.placement == 'function' ? 36453 this.options.placement.call(this, $tip[0], this.$element[0]) : 36454 this.options.placement 36455 36456 var autoToken = /\s?auto?\s?/i 36457 var autoPlace = autoToken.test(placement) 36458 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36459 36460 $tip 36461 .detach() 36462 .css({ top: 0, left: 0, display: 'block' }) 36463 .addClass(placement) 36464 .data('bs.' + this.type, this) 36465 36466 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) 36467 this.$element.trigger('inserted.bs.' + this.type) 36468 36469 var pos = this.getPosition() 36470 var actualWidth = $tip[0].offsetWidth 36471 var actualHeight = $tip[0].offsetHeight 36472 36473 if (autoPlace) { 36474 var orgPlacement = placement 36475 var viewportDim = this.getPosition(this.$viewport) 36476 36477 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : 36478 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : 36479 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : 36480 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : 36481 placement 36482 36483 $tip 36484 .removeClass(orgPlacement) 36485 .addClass(placement) 36486 } 36487 36488 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36489 36490 this.applyPlacement(calculatedOffset, placement) 36491 36492 var complete = function () { 36493 var prevHoverState = that.hoverState 36494 that.$element.trigger('shown.bs.' + that.type) 36495 that.hoverState = null 36496 36497 if (prevHoverState == 'out') that.leave(that) 36498 } 36499 36500 $.support.transition && this.$tip.hasClass('fade') ? 36501 $tip 36502 .one('bsTransitionEnd', complete) 36503 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 36504 complete() 36505 } 36506 } 36507 36508 Tooltip.prototype.applyPlacement = function (offset, placement) { 36509 var $tip = this.tip() 36510 var width = $tip[0].offsetWidth 36511 var height = $tip[0].offsetHeight 36512 36513 // manually read margins because getBoundingClientRect includes difference 36514 var marginTop = parseInt($tip.css('margin-top'), 10) 36515 var marginLeft = parseInt($tip.css('margin-left'), 10) 36516 36517 // we must check for NaN for ie 8/9 36518 if (isNaN(marginTop)) marginTop = 0 36519 if (isNaN(marginLeft)) marginLeft = 0 36520 36521 offset.top += marginTop 36522 offset.left += marginLeft 36523 36524 // $.fn.offset doesn't round pixel values 36525 // so we use setOffset directly with our own function B-0 36526 $.offset.setOffset($tip[0], $.extend({ 36527 using: function (props) { 36528 $tip.css({ 36529 top: Math.round(props.top), 36530 left: Math.round(props.left) 36531 }) 36532 } 36533 }, offset), 0) 36534 36535 $tip.addClass('in') 36536 36537 // check to see if placing tip in new offset caused the tip to resize itself 36538 var actualWidth = $tip[0].offsetWidth 36539 var actualHeight = $tip[0].offsetHeight 36540 36541 if (placement == 'top' && actualHeight != height) { 36542 offset.top = offset.top + height - actualHeight 36543 } 36544 36545 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36546 36547 if (delta.left) offset.left += delta.left 36548 else offset.top += delta.top 36549 36550 var isVertical = /top|bottom/.test(placement) 36551 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36552 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' 36553 36554 $tip.offset(offset) 36555 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) 36556 } 36557 36558 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { 36559 this.arrow() 36560 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') 36561 .css(isVertical ? 'top' : 'left', '') 36562 } 36563 36564 Tooltip.prototype.setContent = function () { 36565 var $tip = this.tip() 36566 var title = this.getTitle() 36567 36568 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36569 $tip.removeClass('fade in top bottom left right') 36570 } 36571 36572 Tooltip.prototype.hide = function (callback) { 36573 var that = this 36574 var $tip = $(this.$tip) 36575 var e = $.Event('hide.bs.' + this.type) 36576 36577 function complete() { 36578 if (that.hoverState != 'in') $tip.detach() 36579 that.$element 36580 .removeAttr('aria-describedby') 36581 .trigger('hidden.bs.' + that.type) 36582 callback && callback() 36583 } 36584 36585 this.$element.trigger(e) 36586 36587 if (e.isDefaultPrevented()) return 36588 36589 $tip.removeClass('in') 36590 36591 $.support.transition && $tip.hasClass('fade') ? 36592 $tip 36593 .one('bsTransitionEnd', complete) 36594 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 36595 complete() 36596 36597 this.hoverState = null 36598 36599 return this 36600 } 36601 36602 Tooltip.prototype.fixTitle = function () { 36603 var $e = this.$element 36604 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { 36605 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36606 } 36607 } 36608 36609 Tooltip.prototype.hasContent = function () { 36610 return this.getTitle() 36611 } 36612 36613 Tooltip.prototype.getPosition = function ($element) { 36614 $element = $element || this.$element 36615 36616 var el = $element[0] 36617 var isBody = el.tagName == 'BODY' 36618 36619 var elRect = el.getBoundingClientRect() 36620 if (elRect.width == null) { 36621 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 36622 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) 36623 } 36624 var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() 36625 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } 36626 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null 36627 36628 return $.extend({}, elRect, scroll, outerDims, elOffset) 36629 } 36630 36631 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36632 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36633 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36634 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36635 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36636 36637 } 36638 36639 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36640 var delta = { top: 0, left: 0 } 36641 if (!this.$viewport) return delta 36642 36643 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36644 var viewportDimensions = this.getPosition(this.$viewport) 36645 36646 if (/right|left/.test(placement)) { 36647 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36648 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36649 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36650 delta.top = viewportDimensions.top - topEdgeOffset 36651 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36652 delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset 36653 } 36654 } else { 36655 var leftEdgeOffset = pos.left - viewportPadding 36656 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36657 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36658 delta.left = viewportDimensions.left - leftEdgeOffset 36659 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow 36660 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36661 } 36662 } 36663 36664 return delta 36665 } 36666 36667 Tooltip.prototype.getTitle = function () { 36668 var title 36669 var $e = this.$element 36670 var o = this.options 36671 36672 title = $e.attr('data-original-title') 36673 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36674 36675 return title 36676 } 36677 36678 Tooltip.prototype.getUID = function (prefix) { 36679 do prefix += ~~(Math.random() * 1000000) 36680 while (document.getElementById(prefix)) 36681 return prefix 36682 } 36683 36684 Tooltip.prototype.tip = function () { 36685 if (!this.$tip) { 36686 this.$tip = $(this.options.template) 36687 if (this.$tip.length != 1) { 36688 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') 36689 } 36690 } 36691 return this.$tip 36692 } 36693 36694 Tooltip.prototype.arrow = function () { 36695 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) 36696 } 36697 36698 Tooltip.prototype.enable = function () { 36699 this.enabled = true 36700 } 36701 36702 Tooltip.prototype.disable = function () { 36703 this.enabled = false 36704 } 36705 36706 Tooltip.prototype.toggleEnabled = function () { 36707 this.enabled = !this.enabled 36708 } 36709 36710 Tooltip.prototype.toggle = function (e) { 36711 var self = this 36712 if (e) { 36713 self = $(e.currentTarget).data('bs.' + this.type) 36714 if (!self) { 36715 self = new this.constructor(e.currentTarget, this.getDelegateOptions()) 36716 $(e.currentTarget).data('bs.' + this.type, self) 36717 } 36718 } 36719 36720 if (e) { 36721 self.inState.click = !self.inState.click 36722 if (self.isInStateTrue()) self.enter(self) 36723 else self.leave(self) 36724 } else { 36725 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36726 } 36727 } 36728 36729 Tooltip.prototype.destroy = function () { 36730 var that = this 36731 clearTimeout(this.timeout) 36732 this.hide(function () { 36733 that.$element.off('.' + that.type).removeData('bs.' + that.type) 36734 if (that.$tip) { 36735 that.$tip.detach() 36736 } 36737 that.$tip = null 36738 that.$arrow = null 36739 that.$viewport = null 36740 }) 36741 } 36742 36743 36744 // TOOLTIP PLUGIN DEFINITION 36745 // ========================= 36746 36747 function Plugin(option) { 36748 return this.each(function () { 36749 var $this = $(this) 36750 var data = $this.data('bs.tooltip') 36751 var options = typeof option == 'object' && option 36752 36753 if (!data && /destroy|hide/.test(option)) return 36754 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36755 if (typeof option == 'string') data[option]() 36756 }) 36757 } 36758 36759 var old = $.fn.tooltip 36760 36761 $.fn.tooltip = Plugin 36762 $.fn.tooltip.Constructor = Tooltip 36763 36764 36765 // TOOLTIP NO CONFLICT 36766 // =================== 36767 36768 $.fn.tooltip.noConflict = function () { 36769 $.fn.tooltip = old 36770 return this 36771 } 36772 36773}(jQuery);
vendor: 14,836 bytes, lines 36774-37298
36774/* ======================================================================== 36775 * Bootstrap: popover.js v3.3.5 36776 * http://getbootstrap.com/javascript/#popovers 36777 * ======================================================================== 36778 * Copyright 2011-2015 Twitter, Inc. 36779 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36780 * ======================================================================== */ 36781 36782 36783 36784+function ($) { 36785 'use strict'; 36786 36787 // POPOVER PUBLIC CLASS DEFINITION 36788 // =============================== 36789 36790 var Popover = function (element, options) { 36791 this.init('popover', element, options) 36792 } 36793 36794 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') 36795 36796 Popover.VERSION = '3.3.5' 36797 36798 Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { 36799 placement: 'right', 36800 trigger: 'click', 36801 content: '', 36802 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' 36803 }) 36804 36805 36806 // NOTE: POPOVER EXTENDS tooltip.js 36807 // ================================ 36808 36809 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) 36810 36811 Popover.prototype.constructor = Popover 36812 36813 Popover.prototype.getDefaults = function () { 36814 return Popover.DEFAULTS 36815 } 36816 36817 Popover.prototype.setContent = function () { 36818 var $tip = this.tip() 36819 var title = this.getTitle() 36820 var content = this.getContent() 36821 36822 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 36823 $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events 36824 this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' 36825 ](content) 36826 36827 $tip.removeClass('fade top bottom left right in') 36828 36829 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do 36830 // this manually by checking the contents. 36831 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() 36832 } 36833 36834 Popover.prototype.hasContent = function () { 36835 return this.getTitle() || this.getContent() 36836 } 36837 36838 Popover.prototype.getContent = function () { 36839 var $e = this.$element 36840 var o = this.options 36841 36842 return $e.attr('data-content') 36843 || (typeof o.content == 'function' ? 36844 o.content.call($e[0]) : 36845 o.content) 36846 } 36847 36848 Popover.prototype.arrow = function () { 36849 return (this.$arrow = this.$arrow || this.tip().find('.arrow')) 36850 } 36851 36852 36853 // POPOVER PLUGIN DEFINITION 36854 // ========================= 36855 36856 function Plugin(option) { 36857 return this.each(function () { 36858 var $this = $(this) 36859 var data = $this.data('bs.popover') 36860 var options = typeof option == 'object' && option 36861 36862 if (!data && /destroy|hide/.test(option)) return 36863 if (!data) $this.data('bs.popover', (data = new Popover(this, options))) 36864 if (typeof option == 'string') data[option]() 36865 }) 36866 } 36867 36868 var old = $.fn.popover 36869 36870 $.fn.popover = Plugin 36871 $.fn.popover.Constructor = Popover 36872 36873 36874 // POPOVER NO CONFLICT 36875 // =================== 36876 36877 $.fn.popover.noConflict = function () { 36878 $.fn.popover = old 36879 return this 36880 } 36881 36882}(jQuery); 36883/* ======================================================================== 36884 * Bootstrap: scrollspy.js v3.3.5 36885 * http://getbootstrap.com/javascript/#scrollspy 36886 * ======================================================================== 36887 * Copyright 2011-2015 Twitter, Inc. 36888 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36889 * ======================================================================== */ 36890 36891 36892 36893+function ($) { 36894 'use strict'; 36895 36896 // SCROLLSPY CLASS DEFINITION 36897 // ========================== 36898 36899 function ScrollSpy(element, options) { 36900 this.$body = $(document.body) 36901 this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) 36902 this.options = $.extend({}, ScrollSpy.DEFAULTS, options) 36903 this.selector = (this.options.target || '') + ' .nav li > a' 36904 this.offsets = [] 36905 this.targets = [] 36906 this.activeTarget = null 36907 this.scrollHeight = 0 36908 36909 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) 36910 this.refresh() 36911 this.process() 36912 } 36913 36914 ScrollSpy.VERSION = '3.3.5' 36915 36916 ScrollSpy.DEFAULTS = { 36917 offset: 10 36918 } 36919 36920 ScrollSpy.prototype.getScrollHeight = function () { 36921 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) 36922 } 36923 36924 ScrollSpy.prototype.refresh = function () { 36925 var that = this 36926 var offsetMethod = 'offset' 36927 var offsetBase = 0 36928 36929 this.offsets = [] 36930 this.targets = [] 36931 this.scrollHeight = this.getScrollHeight() 36932 36933 if (!$.isWindow(this.$scrollElement[0])) { 36934 offsetMethod = 'position' 36935 offsetBase = this.$scrollElement.scrollTop() 36936 } 36937 36938 this.$body 36939 .find(this.selector) 36940 .map(function () { 36941 var $el = $(this) 36942 var href = $el.data('target') || $el.attr('href') 36943 var $href = /^#./.test(href) && $(href) 36944 36945 return ($href 36946 && $href.length 36947 && $href.is(':visible') 36948 && [[$href[offsetMethod]().top + offsetBase, href]]) || null 36949 }) 36950 .sort(function (a, b) { return a[0] - b[0] }) 36951 .each(function () { 36952 that.offsets.push(this[0]) 36953 that.targets.push(this[1]) 36954 }) 36955 } 36956 36957 ScrollSpy.prototype.process = function () { 36958 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 36959 var scrollHeight = this.getScrollHeight() 36960 var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() 36961 var offsets = this.offsets 36962 var targets = this.targets 36963 var activeTarget = this.activeTarget 36964 var i 36965 36966 if (this.scrollHeight != scrollHeight) { 36967 this.refresh() 36968 } 36969 36970 if (scrollTop >= maxScroll) { 36971 return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) 36972 } 36973 36974 if (activeTarget && scrollTop < offsets[0]) { 36975 this.activeTarget = null 36976 return this.clear() 36977 } 36978 36979 for (i = offsets.length; i--;) { 36980 activeTarget != targets[i] 36981 && scrollTop >= offsets[i] 36982 && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) 36983 && this.activate(targets[i]) 36984 } 36985 } 36986 36987 ScrollSpy.prototype.activate = function (target) { 36988 this.activeTarget = target 36989 36990 this.clear() 36991 36992 var selector = this.selector + 36993 '[data-target="' + target + '"],' + 36994 this.selector + '[href="' + target + '"]' 36995 36996 var active = $(selector) 36997 .parents('li') 36998 .addClass('active') 36999 37000 if (active.parent('.dropdown-menu').length) { 37001 active = active 37002 .closest('li.dropdown') 37003 .addClass('active') 37004 } 37005 37006 active.trigger('activate.bs.scrollspy') 37007 } 37008 37009 ScrollSpy.prototype.clear = function () { 37010 $(this.selector) 37011 .parentsUntil(this.options.target, '.active') 37012 .removeClass('active') 37013 } 37014 37015 37016 // SCROLLSPY PLUGIN DEFINITION 37017 // =========================== 37018 37019 function Plugin(option) { 37020 return this.each(function () { 37021 var $this = $(this) 37022 var data = $this.data('bs.scrollspy') 37023 var options = typeof option == 'object' && option 37024 37025 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) 37026 if (typeof option == 'string') data[option]() 37027 }) 37028 } 37029 37030 var old = $.fn.scrollspy 37031 37032 $.fn.scrollspy = Plugin 37033 $.fn.scrollspy.Constructor = ScrollSpy 37034 37035 37036 // SCROLLSPY NO CONFLICT 37037 // ===================== 37038 37039 $.fn.scrollspy.noConflict = function () { 37040 $.fn.scrollspy = old 37041 return this 37042 } 37043 37044 37045 // SCROLLSPY DATA-API 37046 // ================== 37047 37048 $(window).on('load.bs.scrollspy.data-api', function () { 37049 $('[data-spy="scroll"]').each(function () { 37050 var $spy = $(this) 37051 Plugin.call($spy, $spy.data()) 37052 }) 37053 }) 37054 37055}(jQuery); 37056/* ======================================================================== 37057 * Bootstrap: tab.js v3.3.5 37058 * http://getbootstrap.com/javascript/#tabs 37059 * ======================================================================== 37060 * Copyright 2011-2015 Twitter, Inc. 37061 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 37062 * ======================================================================== */ 37063 37064 37065 37066+function ($) { 37067 'use strict'; 37068 37069 // TAB CLASS DEFINITION 37070 // ==================== 37071 37072 var Tab = function (element) { 37073 // jscs:disable requireDollarBeforejQueryAssignment 37074 this.element = $(element) 37075 // jscs:enable requireDollarBeforejQueryAssignment 37076 } 37077 37078 Tab.VERSION = '3.3.5' 37079 37080 Tab.TRANSITION_DURATION = 150 37081 37082 Tab.prototype.show = function () { 37083 var $this = this.element 37084 var $ul = $this.closest('ul:not(.dropdown-menu)') 37085 var selector = $this.data('target') 37086 37087 if (!selector) { 37088 selector = $this.attr('href') 37089 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 37090 } 37091 37092 if ($this.parent('li').hasClass('active')) return 37093 37094 var $previous = $ul.find('.active:last a') 37095 var hideEvent = $.Event('hide.bs.tab', { 37096 relatedTarget: $this[0] 37097 }) 37098 var showEvent = $.Event('show.bs.tab', { 37099 relatedTarget: $previous[0] 37100 }) 37101 37102 $previous.trigger(hideEvent) 37103 $this.trigger(showEvent) 37104 37105 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return 37106 37107 var $target = $(selector) 37108 37109 this.activate($this.closest('li'), $ul) 37110 this.activate($target, $target.parent(), function () { 37111 $previous.trigger({ 37112 type: 'hidden.bs.tab', 37113 relatedTarget: $this[0] 37114 }) 37115 $this.trigger({ 37116 type: 'shown.bs.tab', 37117 relatedTarget: $previous[0] 37118 }) 37119 }) 37120 } 37121 37122 Tab.prototype.activate = function (element, container, callback) { 37123 var $active = container.find('> .active') 37124 var transition = callback 37125 && $.support.transition 37126 && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) 37127 37128 function next() { 37129 $active 37130 .removeClass('active') 37131 .find('> .dropdown-menu > .active') 37132 .removeClass('active') 37133 .end() 37134 .find('[data-toggle="tab"]') 37135 .attr('aria-expanded', false) 37136 37137 element 37138 .addClass('active') 37139 .find('[data-toggle="tab"]') 37140 .attr('aria-expanded', true) 37141 37142 if (transition) { 37143 element[0].offsetWidth // reflow for transition 37144 element.addClass('in') 37145 } else { 37146 element.removeClass('fade') 37147 } 37148 37149 if (element.parent('.dropdown-menu').length) { 37150 element 37151 .closest('li.dropdown') 37152 .addClass('active') 37153 .end() 37154 .find('[data-toggle="tab"]') 37155 .attr('aria-expanded', true) 37156 } 37157 37158 callback && callback() 37159 } 37160 37161 $active.length && transition ? 37162 $active 37163 .one('bsTransitionEnd', next) 37164 .emulateTransitionEnd(Tab.TRANSITION_DURATION) : 37165 next() 37166 37167 $active.removeClass('in') 37168 } 37169 37170 37171 // TAB PLUGIN DEFINITION 37172 // ===================== 37173 37174 function Plugin(option) { 37175 return this.each(function () { 37176 var $this = $(this) 37177 var data = $this.data('bs.tab') 37178 37179 if (!data) $this.data('bs.tab', (data = new Tab(this))) 37180 if (typeof option == 'string') data[option]() 37181 }) 37182 } 37183 37184 var old = $.fn.tab 37185 37186 $.fn.tab = Plugin 37187 $.fn.tab.Constructor = Tab 37188 37189 37190 // TAB NO CONFLICT 37191 // =============== 37192 37193 $.fn.tab.noConflict = function () { 37194 $.fn.tab = old 37195 return this 37196 } 37197 37198 37199 // TAB DATA-API 37200 // ============ 37201 37202 var clickHandler = function (e) { 37203 e.preventDefault() 37204 Plugin.call($(this), 'show') 37205 } 37206 37207 $(document) 37208 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) 37209 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) 37210 37211}(jQuery); 37212/* ======================================================================== 37213 * Bootstrap: affix.js v3.3.5 37214 * http://getbootstrap.com/javascript/#affix 37215 * ======================================================================== 37216 * Copyright 2011-2015 Twitter, Inc. 37217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 37218 * ======================================================================== */ 37219 37220 37221 37222+function ($) { 37223 'use strict'; 37224 37225 // AFFIX CLASS DEFINITION 37226 // ====================== 37227 37228 var Affix = function (element, options) { 37229 this.options = $.extend({}, Affix.DEFAULTS, options) 37230 37231 this.$target = $(this.options.target) 37232 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 37233 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 37234 37235 this.$element = $(element) 37236 this.affixed = null 37237 this.unpin = null 37238 this.pinnedOffset = null 37239 37240 this.checkPosition() 37241 } 37242 37243 Affix.VERSION = '3.3.5' 37244 37245 Affix.RESET = 'affix affix-top affix-bottom' 37246 37247 Affix.DEFAULTS = { 37248 offset: 0, 37249 target: window 37250 } 37251 37252 Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { 37253 var scrollTop = this.$target.scrollTop() 37254 var position = this.$element.offset() 37255 var targetHeight = this.$target.height() 37256 37257 if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false 37258 37259 if (this.affixed == 'bottom') { 37260 if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' 37261 return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' 37262 } 37263 37264 var initializing = this.affixed == null 37265 var colliderTop = initializing ? scrollTop : position.top 37266 var colliderHeight = initializing ? targetHeight : height 37267 37268 if (offsetTop != null && scrollTop <= offsetTop) return 'top' 37269 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' 37270 37271 return false 37272 } 37273 37274 Affix.prototype.getPinnedOffset = function () { 37275 if (this.pinnedOffset) return this.pinnedOffset 37276 this.$element.removeClass(Affix.RESET).addClass('affix') 37277 var scrollTop = this.$target.scrollTop() 37278 var position = this.$element.offset() 37279 return (this.pinnedOffset = position.top - scrollTop) 37280 } 37281 37282 Affix.prototype.checkPositionWithEventLoop = function () { 37283 setTimeout($.proxy(this.checkPosition, this), 1) 37284 } 37285 37286 Affix.prototype.checkPosition = function () { 37287 if (!this.$element.is(':visible')) return 37288 37289 var height = this.$element.height() 37290 var offset = this.options.offset 37291 var offsetTop = offset.top 37292 var offsetBottom = offset.bottom 37293 var scrollHeight = Math.max($(document).height(), $(document.body).height()) 37294 37295 if (typeof offset != 'object') offsetBottom = offsetTop = offset 37296 if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 37297 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 37298
37299 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) 37300 37301 if (this.affixed != affix) { 37302 if (this.unpin != null) this.$element.css('top', '') 37303 37304 var affixType = 'affix' + (affix ? '-' + affix : '') 37305 var e = $.Event(affixType + '.bs.affix') 37306 37307 this.$element.trigger(e) 37308 37309 if (e.isDefaultPrevented()) return 37310 37311 this.affixed = affix 37312 this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 37313 37314 this.$element 37315 .removeClass(Affix.RESET) 37316 .addClass(affixType) 37317 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') 37318 } 37319 37320 if (affix == 'bottom') { 37321 this.$element.offset({ 37322 top: scrollHeight - height - offsetBottom 37323 }) 37324 } 37325 } 37326 37327 37328 // AFFIX PLUGIN DEFINITION 37329 // ======================= 37330 37331 function Plugin(option) { 37332 return this.each(function () { 37333 var $this = $(this) 37334 var data = $this.data('bs.affix') 37335 var options = typeof option == 'object' && option 37336 37337 if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 37338 if (typeof option == 'string') data[option]() 37339 }) 37340 } 37341 37342 var old = $.fn.affix 37343 37344 $.fn.affix = Plugin 37345 $.fn.affix.Constructor = Affix 37346 37347 37348 // AFFIX NO CONFLICT 37349 // ================= 37350 37351 $.fn.affix.noConflict = function () { 37352 $.fn.affix = old 37353 return this 37354 } 37355 37356 37357 // AFFIX DATA-API 37358 // ============== 37359 37360 $(window).on('load', function () { 37361 $('[data-spy="affix"]').each(function () { 37362 var $spy = $(this) 37363 var data = $spy.data() 37364 37365 data.offset = data.offset || {} 37366 37367 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom 37368 if (data.offsetTop != null) data.offset.top = data.offsetTop 37369 37370 Plugin.call($spy, data) 37371 }) 37372 }) 37373 37374}(jQuery); 37375 37376 37377 37378 37379 37380 37381 37382 37383 37384 37385 37386 37387// Underscore.js 1.4.4 37388// http://underscorejs.org 37389// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. 37390// Underscore may be freely distributed under the MIT license. 37391 37392(function() { 37393 37394 // Baseline setup 37395 // -------------- 37396 37397 // Establish the root object, `window` in the browser, or `global` on the server. 37398 var root = this; 37399 37400 // Save the previous value of the `_` variable. 37401 var previousUnderscore = root._; 37402 37403 // Establish the object that gets returned to break out of a loop iteration. 37404 var breaker = {}; 37405 37406 // Save bytes in the minified (but not gzipped) version: 37407 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 37408 37409 // Create quick reference variables for speed access to core prototypes. 37410 var push = ArrayProto.push, 37411 slice = ArrayProto.slice, 37412 concat = ArrayProto.concat, 37413 toString = ObjProto.toString, 37414 hasOwnProperty = ObjProto.hasOwnProperty; 37415 37416 // All **ECMAScript 5** native function implementations that we hope to use 37417 // are declared here. 37418 var 37419 nativeForEach = ArrayProto.forEach, 37420 nativeMap = ArrayProto.map, 37421 nativeReduce = ArrayProto.reduce, 37422 nativeReduceRight = ArrayProto.reduceRight, 37423 nativeFilter = ArrayProto.filter, 37424 nativeEvery = ArrayProto.every, 37425 nativeSome = ArrayProto.some, 37426 nativeIndexOf = ArrayProto.indexOf, 37427 nativeLastIndexOf = ArrayProto.lastIndexOf, 37428 nativeIsArray = Array.isArray, 37429 nativeKeys = Object.keys, 37430 nativeBind = FuncProto.bind; 37431 37432 // Create a safe reference to the Underscore object for use below. 37433 var _ = function(obj) { 37434 if (obj instanceof _) return obj; 37435 if (!(this instanceof _)) return new _(obj); 37436 this._wrapped = obj; 37437 }; 37438 37439 // Export the Underscore object for **Node.js**, with 37440 // backwards-compatibility for the old `require()` API. If we're in 37441 // the browser, add `_` as a global object via a string identifier, 37442 // for Closure Compiler "advanced" mode. 37443 if (typeof exports !== 'undefined') { 37444 if (typeof module !== 'undefined' && module.exports) { 37445 exports = module.exports = _; 37446 } 37447 exports._ = _; 37448 } else { 37449 root._ = _; 37450 } 37451 37452 // Current version. 37453 _.VERSION = '1.4.4'; 37454 37455 // Collection Functions 37456 // -------------------- 37457 37458 // The cornerstone, an `each` implementation, aka `forEach`. 37459 // Handles objects with the built-in `forEach`, arrays, and raw objects.
37460 // Delegates to **ECMAScript 5**'s native `forEach` if available. 37461 var each = _.each = _.forEach = function(obj, iterator, context) { 37462 if (obj == null) return; 37463 if (nativeForEach && obj.forEach === nativeForEach) { 37464 obj.forEach(iterator, context); 37465 } else if (obj.length === +obj.length) { 37466 for (var i = 0, l = obj.length; i < l; i++) { 37467 if (iterator.call(context, obj[i], i, obj) === breaker) return; 37468 } 37469 } else { 37470 for (var key in obj) { 37471 if (_.has(obj, key)) { 37472 if (iterator.call(context, obj[key], key, obj) === breaker) return; 37473 } 37474 } 37475 } 37476 }; 37477 37478 // Return the results of applying the iterator to each element. 37479 // Delegates to **ECMAScript 5**'s native `map` if available. 37480 _.map = _.collect = function(obj, iterator, context) { 37481 var results = []; 37482 if (obj == null) return results; 37483 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 37484 each(obj, function(value, index, list) { 37485 results[results.length] = iterator.call(context, value, index, list); 37486 }); 37487 return results; 37488 }; 37489 37490 var reduceError = 'Reduce of empty array with no initial value'; 37491 37492 // **Reduce** builds up a single result from a list of values, aka `inject`, 37493 // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. 37494 _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { 37495 var initial = arguments.length > 2; 37496 if (obj == null) obj = []; 37497 if (nativeReduce && obj.reduce === nativeReduce) { 37498 if (context) iterator = _.bind(iterator, context); 37499 return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); 37500 } 37501 each(obj, function(value, index, list) { 37502 if (!initial) { 37503 memo = value; 37504 initial = true; 37505 } else { 37506 memo = iterator.call(context, memo, value, index, list); 37507 } 37508 }); 37509 if (!initial) throw new TypeError(reduceError); 37510 return memo; 37511 }; 37512 37513 // The right-associative version of reduce, also known as `foldr`. 37514 // Delegates to **ECMAScript 5**'s native `reduceRight` if available. 37515 _.reduceRight = _.foldr = function(obj, iterator, memo, context) { 37516 var initial = arguments.length > 2; 37517 if (obj == null) obj = []; 37518 if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { 37519 if (context) iterator = _.bind(iterator, context); 37520 return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); 37521 } 37522 var length = obj.length; 37523 if (length !== +length) { 37524 var keys = _.keys(obj); 37525 length = keys.length; 37526 } 37527 each(obj, function(value, index, list) { 37528 index = keys ? keys[--length] : --length; 37529 if (!initial) { 37530 memo = obj[index]; 37531 initial = true; 37532 } else { 37533 memo = iterator.call(context, memo, obj[index], index, list); 37534 } 37535 }); 37536 if (!initial) throw new TypeError(reduceError); 37537 return memo; 37538 }; 37539 37540 // Return the first value which passes a truth test. Aliased as `detect`. 37541 _.find = _.detect = function(obj, iterator, context) { 37542 var result; 37543 any(obj, function(value, index, list) { 37544 if (iterator.call(context, value, index, list)) { 37545 result = value; 37546 return true; 37547 } 37548 }); 37549 return result; 37550 }; 37551 37552 // Return all the elements that pass a truth test. 37553 // Delegates to **ECMAScript 5**'s native `filter` if available. 37554 // Aliased as `select`. 37555 _.filter = _.select = function(obj, iterator, context) { 37556 var results = []; 37557 if (obj == null) return results; 37558 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); 37559 each(obj, function(value, index, list) { 37560 if (iterator.call(context, value, index, list)) results[results.length] = value; 37561 }); 37562 return results; 37563 }; 37564 37565 // Return all the elements for which a truth test fails. 37566 _.reject = function(obj, iterator, context) { 37567 return _.filter(obj, function(value, index, list) { 37568 return !iterator.call(context, value, index, list); 37569 }, context); 37570 }; 37571 37572 // Determine whether all of the elements match a truth test. 37573 // Delegates to **ECMAScript 5**'s native `every` if available. 37574 // Aliased as `all`. 37575 _.every = _.all = function(obj, iterator, context) { 37576 iterator || (iterator = _.identity); 37577 var result = true; 37578 if (obj == null) return result; 37579 if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); 37580 each(obj, function(value, index, list) { 37581 if (!(result = result && iterator.call(context, value, index, list))) return breaker; 37582 }); 37583 return !!result; 37584 }; 37585 37586 // Determine if at least one element in the object matches a truth test. 37587 // Delegates to **ECMAScript 5**'s native `some` if available. 37588 // Aliased as `any`. 37589 var any = _.some = _.any = function(obj, iterator, context) { 37590 iterator || (iterator = _.identity); 37591 var result = false;
37592 if (obj == null) return result; 37593 if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); 37594 each(obj, function(value, index, list) { 37595 if (result || (result = iterator.call(context, value, index, list))) return breaker; 37596 }); 37597 return !!result; 37598 }; 37599 37600 // Determine if the array or object contains a given value (using `===`). 37601 // Aliased as `include`. 37602 _.contains = _.include = function(obj, target) { 37603 if (obj == null) return false; 37604 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; 37605 return any(obj, function(value) { 37606 return value === target; 37607 }); 37608 }; 37609 37610 // Invoke a method (with arguments) on every item in a collection. 37611 _.invoke = function(obj, method) { 37612 var args = slice.call(arguments, 2); 37613 var isFunc = _.isFunction(method); 37614 return _.map(obj, function(value) { 37615 return (isFunc ? method : value[method]).apply(value, args); 37616 }); 37617 }; 37618 37619 // Convenience version of a common use case of `map`: fetching a property. 37620 _.pluck = function(obj, key) { 37621 return _.map(obj, function(value){ return value[key]; }); 37622 }; 37623 37624 // Convenience version of a common use case of `filter`: selecting only objects 37625 // containing specific `key:value` pairs. 37626 _.where = function(obj, attrs, first) { 37627 if (_.isEmpty(attrs)) return first ? null : []; 37628 return _[first ? 'find' : 'filter'](obj, function(value) { 37629 for (var key in attrs) { 37630 if (attrs[key] !== value[key]) return false; 37631 } 37632 return true; 37633 }); 37634 }; 37635 37636 // Convenience version of a common use case of `find`: getting the first object 37637 // containing specific `key:value` pairs. 37638 _.findWhere = function(obj, attrs) { 37639 return _.where(obj, attrs, true); 37640 }; 37641 37642 // Return the maximum element or (element-based computation). 37643 // Can't optimize arrays of integers longer than 65,535 elements. 37644 // See: https://bugs.webkit.org/show_bug.cgi?id=80797 37645 _.max = function(obj, iterator, context) { 37646 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { 37647 return Math.max.apply(Math, obj); 37648 } 37649 if (!iterator && _.isEmpty(obj)) return -Infinity; 37650 var result = {computed : -Infinity, value: -Infinity}; 37651 each(obj, function(value, index, list) { 37652 var computed = iterator ? iterator.call(context, value, index, list) : value; 37653 computed >= result.computed && (result = {value : value, computed : computed}); 37654 }); 37655 return result.value; 37656 }; 37657 37658 // Return the minimum element (or element-based computation). 37659 _.min = function(obj, iterator, context) { 37660 if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { 37661 return Math.min.apply(Math, obj); 37662 } 37663 if (!iterator && _.isEmpty(obj)) return Infinity; 37664 var result = {computed : Infinity, value: Infinity}; 37665 each(obj, function(value, index, list) { 37666 var computed = iterator ? iterator.call(context, value, index, list) : value; 37667 computed < result.computed && (result = {value : value, computed : computed}); 37668 }); 37669 return result.value; 37670 }; 37671 37672 // Shuffle an array. 37673 _.shuffle = function(obj) { 37674 var rand; 37675 var index = 0; 37676 var shuffled = []; 37677 each(obj, function(value) { 37678 rand = _.random(index++); 37679 shuffled[index - 1] = shuffled[rand]; 37680 shuffled[rand] = value; 37681 }); 37682 return shuffled; 37683 }; 37684 37685 // An internal function to generate lookup iterators. 37686 var lookupIterator = function(value) { 37687 return _.isFunction(value) ? value : function(obj){ return obj[value]; }; 37688 }; 37689 37690 // Sort the object's values by a criterion produced by an iterator. 37691 _.sortBy = function(obj, value, context) { 37692 var iterator = lookupIterator(value); 37693 return _.pluck(_.map(obj, function(value, index, list) { 37694 return { 37695 value : value, 37696 index : index, 37697 criteria : iterator.call(context, value, index, list) 37698 }; 37699 }).sort(function(left, right) { 37700 var a = left.criteria; 37701 var b = right.criteria; 37702 if (a !== b) { 37703 if (a > b || a === void 0) return 1; 37704 if (a < b || b === void 0) return -1; 37705 } 37706 return left.index < right.index ? -1 : 1; 37707 }), 'value'); 37708 }; 37709 37710 // An internal function used for aggregate "group by" operations. 37711 var group = function(obj, value, context, behavior) { 37712 var result = {}; 37713 var iterator = lookupIterator(value || _.identity); 37714 each(obj, function(value, index) { 37715 var key = iterator.call(context, value, index, obj); 37716 behavior(result, key, value); 37717 }); 37718 return result; 37719 }; 37720 37721 // Groups the object's values by a criterion. Pass either a string attribute 37722 // to group by, or a function that returns the criterion. 37723 _.groupBy = function(obj, value, context) { 37724 return group(obj, value, context, function(result, key, value) { 37725 (_.has(result, key) ? result[key] : (result[key] = [])).push(value); 37726 }); 37727 }; 37728 37729 // Counts instances of an object that group by a certain criterion. Pass 37730 // either a string attribute to count by, or a function that returns the 37731 // criterion. 37732 _.countBy = function(obj, value, context) { 37733 return group(obj, value, context, function(result, key) { 37734 if (!_.has(result, key)) result[key] = 0; 37735 result[key]++; 37736 }); 37737 }; 37738 37739 // Use a comparator function to figure out the smallest index at which 37740 // an object should be inserted so as to maintain order. Uses binary search. 37741 _.sortedIndex = function(array, obj, iterator, context) { 37742 iterator = iterator == null ? _.identity : lookupIterator(iterator); 37743 var value = iterator.call(context, obj); 37744 var low = 0, high = array.length; 37745 while (low < high) { 37746 var mid = (low + high) >>> 1; 37747 iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; 37748 } 37749 return low; 37750 }; 37751 37752 // Safely convert anything iterable into a real, live array. 37753 _.toArray = function(obj) { 37754 if (!obj) return []; 37755 if (_.isArray(obj)) return slice.call(obj); 37756 if (obj.length === +obj.length) return _.map(obj, _.identity); 37757 return _.values(obj); 37758 }; 37759 37760 // Return the number of elements in an object. 37761 _.size = function(obj) { 37762 if (obj == null) return 0; 37763 return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; 37764 }; 37765 37766 // Array Functions 37767 // --------------- 37768 37769 // Get the first element of an array. Passing **n** will return the first N 37770 // values in the array. Aliased as `head` and `take`. The **guard** check 37771 // allows it to work with `_.map`. 37772 _.first = _.head = _.take = function(array, n, guard) { 37773 if (array == null) return void 0; 37774 return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; 37775 }; 37776 37777 // Returns everything but the last entry of the array. Especially useful on 37778 // the arguments object. Passing **n** will return all the values in 37779 // the array, excluding the last N. The **guard** check allows it to work with 37780 // `_.map`. 37781 _.initial = function(array, n, guard) { 37782 return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); 37783 }; 37784 37785 // Get the last element of an array. Passing **n** will return the last N 37786 // values in the array. The **guard** check allows it to work with `_.map`. 37787 _.last = function(array, n, guard) { 37788 if (array == null) return void 0; 37789 if ((n != null) && !guard) { 37790 return slice.call(array, Math.max(array.length - n, 0)); 37791 } else { 37792 return array[array.length - 1]; 37793 } 37794 }; 37795 37796 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. 37797 // Especially useful on the arguments object. Passing an **n** will return 37798 // the rest N values in the array. The **guard** 37799 // check allows it to work with `_.map`. 37800 _.rest = _.tail = _.drop = function(array, n, guard) { 37801 return slice.call(array, (n == null) || guard ? 1 : n); 37802 }; 37803 37804 // Trim out all falsy values from an array.
37805 _.compact = function(array) { 37806 return _.filter(array, _.identity); 37807 }; 37808 37809 // Internal implementation of a recursive `flatten` function. 37810 var flatten = function(input, shallow, output) { 37811 each(input, function(value) { 37812 if (_.isArray(value)) { 37813 shallow ? push.apply(output, value) : flatten(value, shallow, output); 37814 } else { 37815 output.push(value); 37816 } 37817 }); 37818 return output; 37819 }; 37820 37821 // Return a completely flattened version of an array. 37822 _.flatten = function(array, shallow) { 37823 return flatten(array, shallow, []); 37824 }; 37825 37826 // Return a version of the array that does not contain the specified value(s). 37827 _.without = function(array) { 37828 return _.difference(array, slice.call(arguments, 1)); 37829 }; 37830 37831 // Produce a duplicate-free version of the array. If the array has already 37832 // been sorted, you have the option of using a faster algorithm. 37833 // Aliased as `unique`. 37834 _.uniq = _.unique = function(array, isSorted, iterator, context) { 37835 if (_.isFunction(isSorted)) { 37836 context = iterator; 37837 iterator = isSorted; 37838 isSorted = false; 37839 } 37840 var initial = iterator ? _.map(array, iterator, context) : array; 37841 var results = []; 37842 var seen = []; 37843 each(initial, function(value, index) { 37844 if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { 37845 seen.push(value); 37846 results.push(array[index]); 37847 } 37848 }); 37849 return results; 37850 }; 37851 37852 // Produce an array that contains the union: each distinct element from all of 37853 // the passed-in arrays. 37854 _.union = function() { 37855 return _.uniq(concat.apply(ArrayProto, arguments)); 37856 }; 37857 37858 // Produce an array that contains every item shared between all the 37859 // passed-in arrays. 37860 _.intersection = function(array) { 37861 var rest = slice.call(arguments, 1); 37862 return _.filter(_.uniq(array), function(item) { 37863 return _.every(rest, function(other) { 37864 return _.indexOf(other, item) >= 0; 37865 }); 37866 }); 37867 }; 37868 37869 // Take the difference between one array and a number of other arrays. 37870 // Only the elements present in just the first array will remain. 37871 _.difference = function(array) { 37872 var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); 37873 return _.filter(array, function(value){ return !_.contains(rest, value); }); 37874 }; 37875 37876 // Zip together multiple lists into a single array -- elements that share 37877 // an index go together. 37878 _.zip = function() { 37879 var args = slice.call(arguments); 37880 var length = _.max(_.pluck(args, 'length')); 37881 var results = new Array(length); 37882 for (var i = 0; i < length; i++) { 37883 results[i] = _.pluck(args, "" + i); 37884 } 37885 return results; 37886 }; 37887 37888 // Converts lists into objects. Pass either a single array of `[key, value]` 37889 // pairs, or two parallel arrays of the same length -- one of keys, and one of 37890 // the corresponding values. 37891 _.object = function(list, values) { 37892 if (list == null) return {}; 37893 var result = {}; 37894 for (var i = 0, l = list.length; i < l; i++) { 37895 if (values) { 37896 result[list[i]] = values[i]; 37897 } else { 37898 result[list[i][0]] = list[i][1]; 37899 } 37900 } 37901 return result; 37902 }; 37903 37904 // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), 37905 // we need this function. Return the position of the first occurrence of an 37906 // item in an array, or -1 if the item is not included in the array. 37907 // Delegates to **ECMAScript 5**'s native `indexOf` if available. 37908 // If the array is large and already in sort order, pass `true` 37909 // for **isSorted** to use binary search. 37910 _.indexOf = function(array, item, isSorted) { 37911 if (array == null) return -1; 37912 var i = 0, l = array.length; 37913 if (isSorted) { 37914 if (typeof isSorted == 'number') { 37915 i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); 37916 } else { 37917 i = _.sortedIndex(array, item); 37918 return array[i] === item ? i : -1; 37919 } 37920 } 37921 if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); 37922 for (; i < l; i++) if (array[i] === item) return i; 37923 return -1; 37924 }; 37925 37926 // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. 37927 _.lastIndexOf = function(array, item, from) { 37928 if (array == null) return -1; 37929 var hasIndex = from != null; 37930 if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { 37931 return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); 37932 } 37933 var i = (hasIndex ? from : array.length); 37934 while (i--) if (array[i] === item) return i; 37935 return -1; 37936 }; 37937 37938 // Generate an integer Array containing an arithmetic progression. A port of 37939 // the native Python `range()` function. See 37940 // [the Python documentation](http://docs.python.org/library/functions.html#range). 37941 _.range = function(start, stop, step) { 37942 if (arguments.length <= 1) { 37943 stop = start || 0; 37944 start = 0; 37945 } 37946 step = arguments[2] || 1; 37947 37948 var len = Math.max(Math.ceil((stop - start) / step), 0); 37949 var idx = 0; 37950 var range = new Array(len); 37951 37952 while(idx < len) { 37953 range[idx++] = start; 37954 start += step; 37955 } 37956 37957 return range; 37958 }; 37959 37960 // Function (ahem) Functions 37961 // ------------------ 37962 37963 // Create a function bound to a given object (assigning `this`, and arguments, 37964 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if 37965 // available. 37966 _.bind = function(func, context) { 37967 if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 37968 var args = slice.call(arguments, 2); 37969 return function() { 37970 return func.apply(context, args.concat(slice.call(arguments))); 37971 }; 37972 }; 37973 37974 // Partially apply a function by creating a version that has had some of its 37975 // arguments pre-filled, without changing its dynamic `this` context. 37976 _.partial = function(func) { 37977 var args = slice.call(arguments, 1); 37978 return function() { 37979 return func.apply(this, args.concat(slice.call(arguments))); 37980 }; 37981 }; 37982 37983 // Bind all of an object's methods to that object. Useful for ensuring that 37984 // all callbacks defined on an object belong to it. 37985 _.bindAll = function(obj) { 37986 var funcs = slice.call(arguments, 1);
37987 if (funcs.length === 0) funcs = _.functions(obj); 37988 each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); 37989 return obj; 37990 }; 37991 37992 // Memoize an expensive function by storing its results. 37993 _.memoize = function(func, hasher) { 37994 var memo = {}; 37995 hasher || (hasher = _.identity); 37996 return function() { 37997 var key = hasher.apply(this, arguments); 37998 return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); 37999 }; 38000 }; 38001 38002 // Delays a function for the given number of milliseconds, and then calls 38003 // it with the arguments supplied. 38004 _.delay = function(func, wait) { 38005 var args = slice.call(arguments, 2); 38006 return setTimeout(function(){ return func.apply(null, args); }, wait); 38007 }; 38008 38009 // Defers a function, scheduling it to run after the current call stack has 38010 // cleared. 38011 _.defer = function(func) { 38012 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); 38013 }; 38014 38015 // Returns a function, that, when invoked, will only be triggered at most once 38016 // during a given window of time. 38017 _.throttle = function(func, wait) { 38018 var context, args, timeout, result; 38019 var previous = 0; 38020 var later = function() { 38021 previous = new Date; 38022 timeout = null; 38023 result = func.apply(context, args); 38024 }; 38025 return function() { 38026 var now = new Date; 38027 var remaining = wait - (now - previous); 38028 context = this; 38029 args = arguments; 38030 if (remaining <= 0) { 38031 clearTimeout(timeout); 38032 timeout = null; 38033 previous = now; 38034 result = func.apply(context, args); 38035 } else if (!timeout) { 38036 timeout = setTimeout(later, remaining); 38037 } 38038 return result; 38039 }; 38040 }; 38041 38042 // Returns a function, that, as long as it continues to be invoked, will not 38043 // be triggered. The function will be called after it stops being called for 38044 // N milliseconds. If `immediate` is passed, trigger the function on the 38045 // leading edge, instead of the trailing. 38046 _.debounce = function(func, wait, immediate) { 38047 var timeout, result; 38048 return function() { 38049 var context = this, args = arguments; 38050 var later = function() { 38051 timeout = null; 38052 if (!immediate) result = func.apply(context, args); 38053 }; 38054 var callNow = immediate && !timeout; 38055 clearTimeout(timeout); 38056 timeout = setTimeout(later, wait); 38057 if (callNow) result = func.apply(context, args); 38058 return result; 38059 }; 38060 }; 38061 38062 // Returns a function that will be executed at most one time, no matter how 38063 // often you call it. Useful for lazy initialization. 38064 _.once = function(func) { 38065 var ran = false, memo; 38066 return function() { 38067 if (ran) return memo; 38068 ran = true; 38069 memo = func.apply(this, arguments); 38070 func = null; 38071 return memo; 38072 }; 38073 }; 38074 38075 // Returns the first function passed as an argument to the second, 38076 // allowing you to adjust arguments, run code before and after, and 38077 // conditionally execute the original function. 38078 _.wrap = function(func, wrapper) { 38079 return function() { 38080 var args = [func]; 38081 push.apply(args, arguments); 38082 return wrapper.apply(this, args); 38083 }; 38084 }; 38085 38086 // Returns a function that is the composition of a list of functions, each 38087 // consuming the return value of the function that follows. 38088 _.compose = function() { 38089 var funcs = arguments; 38090 return function() { 38091 var args = arguments; 38092 for (var i = funcs.length - 1; i >= 0; i--) { 38093 args = [funcs[i].apply(this, args)]; 38094 } 38095 return args[0]; 38096 }; 38097 }; 38098 38099 // Returns a function that will only be executed after being called N times. 38100 _.after = function(times, func) { 38101 if (times <= 0) return func(); 38102 return function() { 38103 if (--times < 1) { 38104 return func.apply(this, arguments); 38105 } 38106 }; 38107 }; 38108 38109 // Object Functions 38110 // ---------------- 38111 38112 // Retrieve the names of an object's properties. 38113 // Delegates to **ECMAScript 5**'s native `Object.keys` 38114 _.keys = nativeKeys || function(obj) { 38115 if (obj !== Object(obj)) throw new TypeError('Invalid object'); 38116 var keys = []; 38117 for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; 38118 return keys; 38119 }; 38120 38121 // Retrieve the values of an object's properties. 38122 _.values = function(obj) { 38123 var values = []; 38124 for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); 38125 return values; 38126 }; 38127 38128 // Convert an object into a list of `[key, value]` pairs. 38129 _.pairs = function(obj) { 38130 var pairs = []; 38131 for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); 38132 return pairs; 38133 }; 38134 38135 // Invert the keys and values of an object. The values must be serializable. 38136 _.invert = function(obj) { 38137 var result = {}; 38138 for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; 38139 return result; 38140 }; 38141 38142 // Return a sorted list of the function names available on the object. 38143 // Aliased as `methods` 38144 _.functions = _.methods = function(obj) { 38145 var names = []; 38146 for (var key in obj) { 38147 if (_.isFunction(obj[key])) names.push(key); 38148 } 38149 return names.sort(); 38150 }; 38151 38152 // Extend a given object with all the properties in passed-in object(s). 38153 _.extend = function(obj) { 38154 each(slice.call(arguments, 1), function(source) { 38155 if (source) { 38156 for (var prop in source) { 38157 obj[prop] = source[prop]; 38158 } 38159 } 38160 }); 38161 return obj; 38162 }; 38163 38164 // Return a copy of the object only containing the whitelisted properties. 38165 _.pick = function(obj) { 38166 var copy = {}; 38167 var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); 38168 each(keys, function(key) { 38169 if (key in obj) copy[key] = obj[key]; 38170 }); 38171 return copy; 38172 }; 38173
38174 // Return a copy of the object without the blacklisted properties. 38175 _.omit = function(obj) { 38176 var copy = {}; 38177 var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); 38178 for (var key in obj) { 38179 if (!_.contains(keys, key)) copy[key] = obj[key]; 38180 } 38181 return copy; 38182 }; 38183 38184 // Fill in a given object with default properties. 38185 _.defaults = function(obj) { 38186 each(slice.call(arguments, 1), function(source) { 38187 if (source) { 38188 for (var prop in source) { 38189 if (obj[prop] == null) obj[prop] = source[prop]; 38190 } 38191 } 38192 }); 38193 return obj; 38194 }; 38195 38196 // Create a (shallow-cloned) duplicate of an object. 38197 _.clone = function(obj) { 38198 if (!_.isObject(obj)) return obj; 38199 return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 38200 }; 38201 38202 // Invokes interceptor with the obj, and then returns obj. 38203 // The primary purpose of this method is to "tap into" a method chain, in 38204 // order to perform operations on intermediate results within the chain. 38205 _.tap = function(obj, interceptor) { 38206 interceptor(obj); 38207 return obj; 38208 }; 38209 38210 // Internal recursive comparison function for `isEqual`. 38211 var eq = function(a, b, aStack, bStack) { 38212 // Identical objects are equal. `0 === -0`, but they aren't identical. 38213 // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. 38214 if (a === b) return a !== 0 || 1 / a == 1 / b; 38215 // A strict comparison is necessary because `null == undefined`. 38216 if (a == null || b == null) return a === b; 38217 // Unwrap any wrapped objects. 38218 if (a instanceof _) a = a._wrapped; 38219 if (b instanceof _) b = b._wrapped; 38220 // Compare `[[Class]]` names. 38221 var className = toString.call(a); 38222 if (className != toString.call(b)) return false; 38223 switch (className) { 38224 // Strings, numbers, dates, and booleans are compared by value. 38225 case '[object String]': 38226 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is 38227 // equivalent to `new String("5")`. 38228 return a == String(b); 38229 case '[object Number]': 38230 // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for 38231 // other numeric values. 38232 return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); 38233 case '[object Date]': 38234 case '[object Boolean]': 38235 // Coerce dates and booleans to numeric primitive values. Dates are compared by their 38236 // millisecond representations. Note that invalid dates with millisecond representations 38237 // of `NaN` are not equivalent. 38238 return +a == +b; 38239 // RegExps are compared by their source patterns and flags. 38240 case '[object RegExp]': 38241 return a.source == b.source && 38242 a.global == b.global && 38243 a.multiline == b.multiline && 38244 a.ignoreCase == b.ignoreCase; 38245 } 38246 if (typeof a != 'object' || typeof b != 'object') return false; 38247 // Assume equality for cyclic structures. The algorithm for detecting cyclic 38248 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 38249 var length = aStack.length; 38250 while (length--) { 38251 // Linear search. Performance is inversely proportional to the number of 38252 // unique nested structures. 38253 if (aStack[length] == a) return bStack[length] == b; 38254 } 38255 // Add the first object to the stack of traversed objects. 38256 aStack.push(a); 38257 bStack.push(b); 38258 var size = 0, result = true; 38259 // Recursively compare objects and arrays. 38260 if (className == '[object Array]') { 38261 // Compare array lengths to determine if a deep comparison is necessary. 38262 size = a.length; 38263 result = size == b.length; 38264 if (result) { 38265 // Deep compare the contents, ignoring non-numeric properties. 38266 while (size--) { 38267 if (!(result = eq(a[size], b[size], aStack, bStack))) break; 38268 } 38269 } 38270 } else { 38271 // Objects with different constructors are not equivalent, but `Object`s 38272 // from different frames are. 38273 var aCtor = a.constructor, bCtor = b.constructor; 38274 if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && 38275 _.isFunction(bCtor) && (bCtor instanceof bCtor))) { 38276 return false;
38277 } 38278 // Deep compare objects. 38279 for (var key in a) { 38280 if (_.has(a, key)) { 38281 // Count the expected number of properties. 38282 size++; 38283 // Deep compare each member. 38284 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; 38285 } 38286 } 38287 // Ensure that both objects contain the same number of properties. 38288 if (result) { 38289 for (key in b) { 38290 if (_.has(b, key) && !(size--)) break; 38291 } 38292 result = !size; 38293 } 38294 } 38295 // Remove the first object from the stack of traversed objects. 38296 aStack.pop(); 38297 bStack.pop(); 38298 return result; 38299 }; 38300 38301 // Perform a deep comparison to check if two objects are equal. 38302 _.isEqual = function(a, b) { 38303 return eq(a, b, [], []); 38304 }; 38305 38306 // Is a given array, string, or object empty? 38307 // An "empty" object has no enumerable own-properties. 38308 _.isEmpty = function(obj) { 38309 if (obj == null) return true; 38310 if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; 38311 for (var key in obj) if (_.has(obj, key)) return false; 38312 return true; 38313 }; 38314 38315 // Is a given value a DOM element? 38316 _.isElement = function(obj) { 38317 return !!(obj && obj.nodeType === 1); 38318 }; 38319 38320 // Is a given value an array? 38321 // Delegates to ECMA5's native Array.isArray 38322 _.isArray = nativeIsArray || function(obj) { 38323 return toString.call(obj) == '[object Array]'; 38324 }; 38325 38326 // Is a given variable an object? 38327 _.isObject = function(obj) { 38328 return obj === Object(obj); 38329 }; 38330 38331 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. 38332 each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { 38333 _['is' + name] = function(obj) { 38334 return toString.call(obj) == '[object ' + name + ']'; 38335 }; 38336 }); 38337 38338 // Define a fallback version of the method in browsers (ahem, IE), where 38339 // there isn't any inspectable "Arguments" type. 38340 if (!_.isArguments(arguments)) { 38341 _.isArguments = function(obj) { 38342 return !!(obj && _.has(obj, 'callee')); 38343 }; 38344 } 38345 38346 // Optimize `isFunction` if appropriate. 38347 if (typeof (/./) !== 'function') { 38348 _.isFunction = function(obj) { 38349 return typeof obj === 'function'; 38350 }; 38351 } 38352 38353 // Is a given object a finite number? 38354 _.isFinite = function(obj) { 38355 return isFinite(obj) && !isNaN(parseFloat(obj)); 38356 }; 38357 38358 // Is the given value `NaN`? (NaN is the only number which does not equal itself). 38359 _.isNaN = function(obj) { 38360 return _.isNumber(obj) && obj != +obj; 38361 }; 38362 38363 // Is a given value a boolean? 38364 _.isBoolean = function(obj) { 38365 return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; 38366 }; 38367 38368 // Is a given value equal to null? 38369 _.isNull = function(obj) { 38370 return obj === null; 38371 }; 38372 38373 // Is a given variable undefined? 38374 _.isUndefined = function(obj) { 38375 return obj === void 0; 38376 }; 38377 38378 // Shortcut function for checking if an object has a given property directly 38379 // on itself (in other words, not on a prototype). 38380 _.has = function(obj, key) { 38381 return hasOwnProperty.call(obj, key); 38382 }; 38383 38384 // Utility Functions 38385 // ----------------- 38386 38387 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 38388 // previous owner. Returns a reference to the Underscore object. 38389 _.noConflict = function() { 38390 root._ = previousUnderscore; 38391 return this; 38392 }; 38393 38394 // Keep the identity function around for default iterators. 38395 _.identity = function(value) { 38396 return value; 38397 }; 38398 38399 // Run a function **n** times. 38400 _.times = function(n, iterator, context) { 38401 var accum = Array(n); 38402 for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); 38403 return accum; 38404 }; 38405 38406 // Return a random integer between min and max (inclusive). 38407 _.random = function(min, max) { 38408 if (max == null) { 38409 max = min; 38410 min = 0; 38411 } 38412 return min + Math.floor(Math.random() * (max - min + 1)); 38413 }; 38414 38415 // List of HTML entities for escaping. 38416 var entityMap = { 38417 escape: { 38418 '&': '&', 38419 '<': '<', 38420 '>': '>', 38421 '"': '"', 38422 "'": ''', 38423 '/': '/' 38424 } 38425 }; 38426 entityMap.unescape = _.invert(entityMap.escape); 38427 38428 // Regexes containing the keys and values listed immediately above. 38429 var entityRegexes = { 38430 escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), 38431 unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') 38432 }; 38433 38434 // Functions for escaping and unescaping strings to/from HTML interpolation. 38435 _.each(['escape', 'unescape'], function(method) { 38436 _[method] = function(string) { 38437 if (string == null) return ''; 38438 return ('' + string).replace(entityRegexes[method], function(match) { 38439 return entityMap[method][match]; 38440 }); 38441 }; 38442 }); 38443 38444 // If the value of the named property is a function then invoke it; 38445 // otherwise, return it. 38446 _.result = function(object, property) { 38447 if (object == null) return null; 38448 var value = object[property]; 38449 return _.isFunction(value) ? value.call(object) : value; 38450 }; 38451 38452 // Add your own custom functions to the Underscore object. 38453 _.mixin = function(obj) { 38454 each(_.functions(obj), function(name){ 38455 var func = _[name] = obj[name]; 38456 _.prototype[name] = function() { 38457 var args = [this._wrapped]; 38458 push.apply(args, arguments); 38459 return result.call(this, func.apply(_, args)); 38460 }; 38461 }); 38462 }; 38463 38464 // Generate a unique integer id (unique within the entire client session). 38465 // Useful for temporary DOM ids. 38466 var idCounter = 0; 38467 _.uniqueId = function(prefix) { 38468 var id = ++idCounter + ''; 38469 return prefix ? prefix + id : id; 38470 }; 38471 38472 // By default, Underscore uses ERB-style template delimiters, change the 38473 // following template settings to use alternative delimiters. 38474 _.templateSettings = { 38475 evaluate : /<%([\s\S]+?)%>/g, 38476 interpolate : /<%=([\s\S]+?)%>/g, 38477 escape : /<%-([\s\S]+?)%>/g 38478 }; 38479 38480 // When customizing `templateSettings`, if you don't want to define an 38481 // interpolation, evaluation or escaping regex, we need one that is 38482 // guaranteed not to match. 38483 var noMatch = /(.)^/; 38484 38485 // Certain characters need to be escaped so that they can be put into a 38486 // string literal. 38487 var escapes = { 38488 "'": "'", 38489 '\\': '\\', 38490 '\r': 'r', 38491 '\n': 'n', 38492 '\t': 't', 38493 '\u2028': 'u2028', 38494 '\u2029': 'u2029' 38495 }; 38496 38497 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; 38498 38499 // JavaScript micro-templating, similar to John Resig's implementation. 38500 // Underscore templating handles arbitrary delimiters, preserves whitespace, 38501 // and correctly escapes quotes within interpolated code. 38502 _.template = function(text, data, settings) { 38503 var render; 38504 settings = _.defaults({}, settings, _.templateSettings); 38505 38506 // Combine delimiters into one regular expression via alternation. 38507 var matcher = new RegExp([
38508 (settings.escape || noMatch).source, 38509 (settings.interpolate || noMatch).source, 38510 (settings.evaluate || noMatch).source 38511 ].join('|') + '|$', 'g'); 38512 38513 // Compile the template source, escaping string literals appropriately. 38514 var index = 0; 38515 var source = "__p+='"; 38516 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 38517 source += text.slice(index, offset) 38518 .replace(escaper, function(match) { return '\\' + escapes[match]; }); 38519 38520 if (escape) { 38521 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 38522 } 38523 if (interpolate) { 38524 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 38525 } 38526 if (evaluate) { 38527 source += "';\n" + evaluate + "\n__p+='"; 38528 } 38529 index = offset + match.length; 38530 return match; 38531 }); 38532 source += "';\n"; 38533 38534 // If a variable is not specified, place data values in local scope. 38535 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 38536 38537 source = "var __t,__p='',__j=Array.prototype.join," + 38538 "print=function(){__p+=__j.call(arguments,'');};\n" + 38539 source + "return __p;\n"; 38540 38541 try { 38542 render = new Function(settings.variable || 'obj', '_', source); 38543 } catch (e) { 38544 e.source = source; 38545 throw e; 38546 } 38547 38548 if (data) return render(data, _); 38549 var template = function(data) { 38550 return render.call(this, data, _); 38551 }; 38552 38553 // Provide the compiled function source as a convenience for precompilation. 38554 template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; 38555 38556 return template; 38557 }; 38558 38559 // Add a "chain" function, which will delegate to the wrapper. 38560 _.chain = function(obj) { 38561 return _(obj).chain(); 38562 }; 38563 38564 // OOP 38565 // --------------- 38566 // If Underscore is called as a function, it returns a wrapped object that 38567 // can be used OO-style. This wrapper holds altered versions of all the 38568 // underscore functions. Wrapped objects may be chained. 38569 38570 // Helper function to continue chaining intermediate results. 38571 var result = function(obj) { 38572 return this._chain ? _(obj).chain() : obj; 38573 }; 38574 38575 // Add all of the Underscore functions to the wrapper object. 38576 _.mixin(_); 38577 38578 // Add all mutator Array functions to the wrapper. 38579 each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 38580 var method = ArrayProto[name]; 38581 _.prototype[name] = function() { 38582 var obj = this._wrapped; 38583 method.apply(obj, arguments); 38584 if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; 38585 return result.call(this, obj); 38586 }; 38587 }); 38588 38589 // Add all accessor Array functions to the wrapper. 38590 each(['concat', 'join', 'slice'], function(name) { 38591 var method = ArrayProto[name]; 38592 _.prototype[name] = function() { 38593 return result.call(this, method.apply(this._wrapped, arguments)); 38594 }; 38595 }); 38596 38597 _.extend(_.prototype, { 38598 38599 // Start chaining a wrapped Underscore object. 38600 chain: function() { 38601 this._chain = true; 38602 return this; 38603 }, 38604 38605 // Extracts the result from a wrapped and chained object. 38606 value: function() { 38607 return this._wrapped; 38608 } 38609 38610 }); 38611 38612}).call(this); 38613// Backbone.js 0.9.9 38614 38615// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. 38616// Backbone may be freely distributed under the MIT license. 38617// For all details and documentation: 38618// http://backbonejs.org 38619 38620(function(){ 38621 38622 // Initial Setup 38623 // ------------- 38624 38625 // Save a reference to the global object (`window` in the browser, `exports` 38626 // on the server). 38627 var root = this; 38628 38629 // Save the previous value of the `Backbone` variable, so that it can be 38630 // restored later on, if `noConflict` is used. 38631 var previousBackbone = root.Backbone; 38632 38633 // Create a local reference to array methods. 38634 var array = []; 38635 var push = array.push; 38636 var slice = array.slice; 38637 var splice = array.splice; 38638 38639 // The top-level namespace. All public Backbone classes and modules will 38640 // be attached to this. Exported for both CommonJS and the browser. 38641 var Backbone; 38642 if (typeof exports !== 'undefined') { 38643 Backbone = exports; 38644 } else { 38645 Backbone = root.Backbone = {}; 38646 } 38647 38648 // Current version of the library. Keep in sync with `package.json`. 38649 Backbone.VERSION = '0.9.9'; 38650 38651 // Require Underscore, if we're on the server, and it's not already present. 38652 var _ = root._; 38653 if (!_ && (typeof require !== 'undefined')) _ = require('underscore'); 38654 38655 // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable. 38656 Backbone.$ = root.jQuery || root.Zepto || root.ender; 38657 38658 // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable 38659 // to its previous owner. Returns a reference to this Backbone object.
38660 Backbone.noConflict = function() { 38661 root.Backbone = previousBackbone; 38662 return this; 38663 }; 38664 38665 // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option 38666 // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and 38667 // set a `X-Http-Method-Override` header. 38668 Backbone.emulateHTTP = false; 38669 38670 // Turn on `emulateJSON` to support legacy servers that can't deal with direct 38671 // `application/json` requests ... will encode the body as 38672 // `application/x-www-form-urlencoded` instead and will send the model in a 38673 // form param named `model`. 38674 Backbone.emulateJSON = false; 38675 38676 // Backbone.Events 38677 // --------------- 38678 38679 // Regular expression used to split event strings. 38680 var eventSplitter = /\s+/; 38681 38682 // Implement fancy features of the Events API such as multiple event 38683 // names `"change blur"` and jQuery-style event maps `{change: action}` 38684 // in terms of the existing API. 38685 var eventsApi = function(obj, action, name, rest) { 38686 if (!name) return true; 38687 if (typeof name === 'object') { 38688 for (var key in name) { 38689 obj[action].apply(obj, [key, name[key]].concat(rest)); 38690 } 38691 } else if (eventSplitter.test(name)) { 38692 var names = name.split(eventSplitter); 38693 for (var i = 0, l = names.length; i < l; i++) { 38694 obj[action].apply(obj, [names[i]].concat(rest)); 38695 } 38696 } else { 38697 return true; 38698 } 38699 }; 38700 38701 // Optimized internal dispatch function for triggering events. Tries to 38702 // keep the usual cases speedy (most Backbone events have 3 arguments). 38703 var triggerEvents = function(obj, events, args) { 38704 var ev, i = -1, l = events.length; 38705 switch (args.length) { 38706 case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); 38707 return; 38708 case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]); 38709 return; 38710 case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]); 38711 return; 38712 case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]); 38713 return; 38714 default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); 38715 } 38716 }; 38717 38718 // A module that can be mixed in to *any object* in order to provide it with 38719 // custom events. You may bind with `on` or remove with `off` callback 38720 // functions to an event; `trigger`-ing an event fires all callbacks in 38721 // succession. 38722 // 38723 // var object = {}; 38724 // _.extend(object, Backbone.Events); 38725 // object.on('expand', function(){ alert('expanded'); }); 38726 // object.trigger('expand'); 38727 // 38728 var Events = Backbone.Events = { 38729 38730 // Bind one or more space separated events, or an events map, 38731 // to a `callback` function. Passing `"all"` will bind the callback to 38732 // all events fired. 38733 on: function(name, callback, context) { 38734 if (!(eventsApi(this, 'on', name, [callback, context]) && callback)) return this; 38735 this._events || (this._events = {}); 38736 var list = this._events[name] || (this._events[name] = []); 38737 list.push({callback: callback, context: context, ctx: context || this}); 38738 return this; 38739 }, 38740 38741 // Bind events to only be triggered a single time. After the first time 38742 // the callback is invoked, it will be removed. 38743 once: function(name, callback, context) { 38744 if (!(eventsApi(this, 'once', name, [callback, context]) && callback)) return this; 38745 var self = this; 38746 var once = _.once(function() { 38747 self.off(name, once); 38748 callback.apply(this, arguments); 38749 }); 38750 once._callback = callback; 38751 this.on(name, once, context); 38752 return this; 38753 }, 38754 38755 // Remove one or many callbacks. If `context` is null, removes all 38756 // callbacks with that function. If `callback` is null, removes all 38757 // callbacks for the event. If `events` is null, removes all bound 38758 // callbacks for all events. 38759 off: function(name, callback, context) { 38760 var list, ev, events, names, i, l, j, k; 38761 if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; 38762 if (!name && !callback && !context) { 38763 this._events = {}; 38764 return this; 38765 } 38766 38767 names = name ? [name] : _.keys(this._events); 38768 for (i = 0, l = names.length; i < l; i++) { 38769 name = names[i]; 38770 if (list = this._events[name]) { 38771 events = []; 38772 if (callback || context) { 38773 for (j = 0, k = list.length; j < k; j++) { 38774 ev = list[j]; 38775 if ((callback && callback !== (ev.callback._callback || ev.callback)) || 38776 (context && context !== ev.context)) { 38777 events.push(ev); 38778 } 38779 } 38780 } 38781 this._events[name] = events; 38782 } 38783 } 38784 38785 return this; 38786 }, 38787 38788 // Trigger one or many events, firing all bound callbacks. Callbacks are 38789 // passed the same arguments as `trigger` is, apart from the event name 38790 // (unless you're listening on `"all"`, which will cause your callback to 38791 // receive the true name of the event as the first argument). 38792 trigger: function(name) { 38793 if (!this._events) return this; 38794 var args = slice.call(arguments, 1); 38795 if (!eventsApi(this, 'trigger', name, args)) return this; 38796 var events = this._events[name]; 38797 var allEvents = this._events.all; 38798 if (events) triggerEvents(this, events, args); 38799 if (allEvents) triggerEvents(this, allEvents, arguments); 38800 return this; 38801 }, 38802 38803 // An inversion-of-control version of `on`. Tell *this* object to listen to 38804 // an event in another object ... keeping track of what it's listening to. 38805 listenTo: function(object, events, callback) { 38806 var listeners = this._listeners || (this._listeners = {}); 38807 var id = object._listenerId || (object._listenerId = _.uniqueId('l')); 38808 listeners[id] = object; 38809 object.on(events, callback || this, this); 38810 return this; 38811 }, 38812 38813 // Tell this object to stop listening to either specific events ... or 38814 // to every object it's currently listening to. 38815 stopListening: function(object, events, callback) { 38816 var listeners = this._listeners; 38817 if (!listeners) return; 38818 if (object) { 38819 object.off(events, callback, this); 38820 if (!events && !callback) delete listeners[object._listenerId]; 38821 } else { 38822 for (var id in listeners) { 38823 listeners[id].off(null, null, this); 38824 } 38825 this._listeners = {}; 38826 } 38827 return this; 38828 } 38829 }; 38830 38831 // Aliases for backwards compatibility. 38832 Events.bind = Events.on; 38833 Events.unbind = Events.off; 38834 38835 // Allow the `Backbone` object to serve as a global event bus, for folks who 38836 // want global "pubsub" in a convenient place. 38837 _.extend(Backbone, Events); 38838 38839 // Backbone.Model 38840 // -------------- 38841 38842 // Create a new model, with defined attributes. A client id (`cid`) 38843 // is automatically generated and assigned for you. 38844 var Model = Backbone.Model = function(attributes, options) { 38845 var defaults; 38846 var attrs = attributes || {}; 38847 this.cid = _.uniqueId('c'); 38848 this.changed = {}; 38849 this.attributes = {}; 38850 this._changes = []; 38851 if (options && options.collection) this.collection = options.collection; 38852 if (options && options.parse) attrs = this.parse(attrs); 38853 if (defaults = _.result(this, 'defaults')) _.defaults(attrs, defaults); 38854 this.set(attrs, {silent: true}); 38855 this._currentAttributes = _.clone(this.attributes); 38856 this._previousAttributes = _.clone(this.attributes); 38857 this.initialize.apply(this, arguments); 38858 }; 38859 38860 // Attach all inheritable methods to the Model prototype. 38861 _.extend(Model.prototype, Events, { 38862 38863 // A hash of attributes whose current and previous value differ. 38864 changed: null, 38865 38866 // The default name for the JSON `id` attribute is `"id"`. MongoDB and 38867 // CouchDB users may want to set this to `"_id"`. 38868 idAttribute: 'id', 38869 38870 // Initialize is an empty function by default. Override it with your own 38871 // initialization logic. 38872 initialize: function(){}, 38873 38874 // Return a copy of the model's `attributes` object. 38875 toJSON: function(options) { 38876 return _.clone(this.attributes); 38877 }, 38878 38879 // Proxy `Backbone.sync` by default. 38880 sync: function() { 38881 return Backbone.sync.apply(this, arguments); 38882 }, 38883 38884 // Get the value of an attribute. 38885 get: function(attr) { 38886 return this.attributes[attr]; 38887 }, 38888 38889 // Get the HTML-escaped value of an attribute. 38890 escape: function(attr) { 38891 return _.escape(this.get(attr)); 38892 }, 38893 38894 // Returns `true` if the attribute contains a value that is not null 38895 // or undefined. 38896 has: function(attr) { 38897 return this.get(attr) != null; 38898 }, 38899 38900 // Set a hash of model attributes on the object, firing `"change"` unless 38901 // you choose to silence it. 38902 set: function(key, val, options) { 38903 var attr, attrs; 38904 if (key == null) return this; 38905 38906 // Handle both `"key", value` and `{key: value}` -style arguments. 38907 if (_.isObject(key)) { 38908 attrs = key; 38909 options = val; 38910 } else { 38911 (attrs = {})[key] = val; 38912 } 38913 38914 // Extract attributes and options. 38915 var silent = options && options.silent; 38916 var unset = options && options.unset; 38917 38918 // Run validation.
38919 if (!this._validate(attrs, options)) return false; 38920 38921 // Check for changes of `id`. 38922 if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; 38923 38924 var now = this.attributes; 38925 38926 // For each `set` attribute... 38927 for (attr in attrs) { 38928 val = attrs[attr]; 38929 38930 // Update or delete the current value, and track the change. 38931 unset ? delete now[attr] : now[attr] = val; 38932 this._changes.push(attr, val); 38933 } 38934 38935 // Signal that the model's state has potentially changed, and we need 38936 // to recompute the actual changes. 38937 this._hasComputed = false; 38938 38939 // Fire the `"change"` events. 38940 if (!silent) this.change(options); 38941 return this; 38942 }, 38943 38944 // Remove an attribute from the model, firing `"change"` unless you choose 38945 // to silence it. `unset` is a noop if the attribute doesn't exist. 38946 unset: function(attr, options) { 38947 return this.set(attr, void 0, _.extend({}, options, {unset: true})); 38948 }, 38949 38950 // Clear all attributes on the model, firing `"change"` unless you choose 38951 // to silence it. 38952 clear: function(options) { 38953 var attrs = {}; 38954 for (var key in this.attributes) attrs[key] = void 0; 38955 return this.set(attrs, _.extend({}, options, {unset: true})); 38956 }, 38957 38958 // Fetch the model from the server. If the server's representation of the 38959 // model differs from its current attributes, they will be overriden, 38960 // triggering a `"change"` event. 38961 fetch: function(options) { 38962 options = options ? _.clone(options) : {}; 38963 if (options.parse === void 0) options.parse = true; 38964 var model = this; 38965 var success = options.success; 38966 options.success = function(resp, status, xhr) { 38967 if (!model.set(model.parse(resp), options)) return false; 38968 if (success) success(model, resp, options); 38969 }; 38970 return this.sync('read', this, options); 38971 }, 38972 38973 // Set a hash of model attributes, and sync the model to the server. 38974 // If the server returns an attributes hash that differs, the model's 38975 // state will be `set` again. 38976 save: function(key, val, options) { 38977 var attrs, current, done; 38978 38979 // Handle both `"key", value` and `{key: value}` -style arguments. 38980 if (key == null || _.isObject(key)) { 38981 attrs = key; 38982 options = val; 38983 } else if (key != null) { 38984 (attrs = {})[key] = val; 38985 } 38986 options = options ? _.clone(options) : {}; 38987 38988 // If we're "wait"-ing to set changed attributes, validate early. 38989 if (options.wait) { 38990 if (attrs && !this._validate(attrs, options)) return false; 38991 current = _.clone(this.attributes); 38992 } 38993 38994 // Regular saves `set` attributes before persisting to the server. 38995 var silentOptions = _.extend({}, options, {silent: true}); 38996 if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) { 38997 return false; 38998 } 38999 39000 // Do not persist invalid models. 39001 if (!attrs && !this._validate(null, options)) return false; 39002 39003 // After a successful server-side save, the client is (optionally) 39004 // updated with the server-side state. 39005 var model = this; 39006 var success = options.success; 39007 options.success = function(resp, status, xhr) { 39008 done = true; 39009 var serverAttrs = model.parse(resp); 39010 if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); 39011 if (!model.set(serverAttrs, options)) return false; 39012 if (success) success(model, resp, options); 39013 }; 39014 39015 // Finish configuring and sending the Ajax request. 39016 var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); 39017 if (method == 'patch') options.attrs = attrs; 39018 var xhr = this.sync(method, this, options); 39019 39020 // When using `wait`, reset attributes to original values unless 39021 // `success` has been called already. 39022 if (!done && options.wait) { 39023 this.clear(silentOptions); 39024 this.set(current, silentOptions); 39025 } 39026 39027 return xhr; 39028 }, 39029 39030 // Destroy this model on the server if it was already persisted. 39031 // Optimistically removes the model from its collection, if it has one. 39032 // If `wait: true` is passed, waits for the server to respond before removal. 39033 destroy: function(options) { 39034 options = options ? _.clone(options) : {}; 39035 var model = this; 39036 var success = options.success; 39037 39038 var destroy = function() { 39039 model.trigger('destroy', model, model.collection, options); 39040 }; 39041 39042 options.success = function(resp) { 39043 if (options.wait || model.isNew()) destroy(); 39044 if (success) success(model, resp, options); 39045 }; 39046 39047 if (this.isNew()) { 39048 options.success(); 39049 return false;
39050 } 39051 39052 var xhr = this.sync('delete', this, options); 39053 if (!options.wait) destroy(); 39054 return xhr; 39055 }, 39056 39057 // Default URL for the model's representation on the server -- if you're 39058 // using Backbone's restful methods, override this to change the endpoint 39059 // that will be called. 39060 url: function() { 39061 var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError(); 39062 if (this.isNew()) return base; 39063 return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id); 39064 }, 39065 39066 // **parse** converts a response into the hash of attributes to be `set` on 39067 // the model. The default implementation is just to pass the response along. 39068 parse: function(resp) { 39069 return resp; 39070 }, 39071 39072 // Create a new model with identical attributes to this one. 39073 clone: function() { 39074 return new this.constructor(this.attributes); 39075 }, 39076 39077 // A model is new if it has never been saved to the server, and lacks an id. 39078 isNew: function() { 39079 return this.id == null; 39080 }, 39081 39082 // Call this method to manually fire a `"change"` event for this model and 39083 // a `"change:attribute"` event for each changed attribute. 39084 // Calling this will cause all objects observing the model to update. 39085 change: function(options) { 39086 var changing = this._changing; 39087 this._changing = true; 39088 39089 // Generate the changes to be triggered on the model. 39090 var triggers = this._computeChanges(true); 39091 39092 this._pending = !!triggers.length; 39093 39094 for (var i = triggers.length - 2; i >= 0; i -= 2) { 39095 this.trigger('change:' + triggers[i], this, triggers[i + 1], options); 39096 } 39097 39098 if (changing) return this; 39099 39100 // Trigger a `change` while there have been changes. 39101 while (this._pending) { 39102 this._pending = false; 39103 this.trigger('change', this, options); 39104 this._previousAttributes = _.clone(this.attributes); 39105 } 39106 39107 this._changing = false; 39108 return this; 39109 }, 39110 39111 // Determine if the model has changed since the last `"change"` event. 39112 // If you specify an attribute name, determine if that attribute has changed. 39113 hasChanged: function(attr) { 39114 if (!this._hasComputed) this._computeChanges(); 39115 if (attr == null) return !_.isEmpty(this.changed); 39116 return _.has(this.changed, attr); 39117 }, 39118
39119 // Return an object containing all the attributes that have changed, or 39120 // false if there are no changed attributes. Useful for determining what 39121 // parts of a view need to be updated and/or what attributes need to be 39122 // persisted to the server. Unset attributes will be set to undefined. 39123 // You can also pass an attributes object to diff against the model, 39124 // determining if there *would be* a change. 39125 changedAttributes: function(diff) { 39126 if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; 39127 var val, changed = false, old = this._previousAttributes; 39128 for (var attr in diff) { 39129 if (_.isEqual(old[attr], (val = diff[attr]))) continue; 39130 (changed || (changed = {}))[attr] = val; 39131 } 39132 return changed; 39133 }, 39134 39135 // Looking at the built up list of `set` attribute changes, compute how 39136 // many of the attributes have actually changed. If `loud`, return a 39137 // boiled-down list of only the real changes. 39138 _computeChanges: function(loud) { 39139 this.changed = {}; 39140 var already = {}; 39141 var triggers = []; 39142 var current = this._currentAttributes; 39143 var changes = this._changes; 39144 39145 // Loop through the current queue of potential model changes. 39146 for (var i = changes.length - 2; i >= 0; i -= 2) { 39147 var key = changes[i], val = changes[i + 1]; 39148 if (already[key]) continue; 39149 already[key] = true; 39150 39151 // Check if the attribute has been modified since the last change, 39152 // and update `this.changed` accordingly. If we're inside of a `change` 39153 // call, also add a trigger to the list. 39154 if (current[key] !== val) { 39155 this.changed[key] = val; 39156 if (!loud) continue; 39157 triggers.push(key, val); 39158 current[key] = val; 39159 } 39160 } 39161 if (loud) this._changes = []; 39162 39163 // Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`. 39164 this._hasComputed = true; 39165 return triggers; 39166 }, 39167 39168 // Get the previous value of an attribute, recorded at the time the last 39169 // `"change"` event was fired. 39170 previous: function(attr) { 39171 if (attr == null || !this._previousAttributes) return null; 39172 return this._previousAttributes[attr]; 39173 }, 39174 39175 // Get all of the attributes of the model at the time of the previous 39176 // `"change"` event. 39177 previousAttributes: function() { 39178 return _.clone(this._previousAttributes); 39179 }, 39180 39181 // Run validation against the next complete set of model attributes, 39182 // returning `true` if all is well. If a specific `error` callback has 39183 // been passed, call that instead of firing the general `"error"` event. 39184 _validate: function(attrs, options) { 39185 if (!this.validate) return true; 39186 attrs = _.extend({}, this.attributes, attrs); 39187 var error = this.validate(attrs, options); 39188 if (!error) return true; 39189 if (options && options.error) options.error(this, error, options); 39190 this.trigger('error', this, error, options); 39191 return false; 39192 } 39193 39194 }); 39195 39196 // Backbone.Collection 39197 // ------------------- 39198 39199 // Provides a standard collection class for our sets of models, ordered 39200 // or unordered. If a `comparator` is specified, the Collection will maintain 39201 // its models in sort order, as they're added and removed. 39202 var Collection = Backbone.Collection = function(models, options) { 39203 options || (options = {}); 39204 if (options.model) this.model = options.model; 39205 if (options.comparator !== void 0) this.comparator = options.comparator; 39206 this._reset(); 39207 this.initialize.apply(this, arguments); 39208 if (models) this.reset(models, _.extend({silent: true}, options)); 39209 }; 39210 39211 // Define the Collection's inheritable methods. 39212 _.extend(Collection.prototype, Events, { 39213 39214 // The default model for a collection is just a **Backbone.Model**. 39215 // This should be overridden in most cases. 39216 model: Model, 39217 39218 // Initialize is an empty function by default. Override it with your own 39219 // initialization logic. 39220 initialize: function(){}, 39221 39222 // The JSON representation of a Collection is an array of the 39223 // models' attributes. 39224 toJSON: function(options) { 39225 return this.map(function(model){ return model.toJSON(options); }); 39226 }, 39227 39228 // Proxy `Backbone.sync` by default. 39229 sync: function() { 39230 return Backbone.sync.apply(this, arguments); 39231 }, 39232 39233 // Add a model, or list of models to the set. Pass **silent** to avoid 39234 // firing the `add` event for every new model. 39235 add: function(models, options) { 39236 var i, args, length, model, existing, needsSort; 39237 var at = options && options.at; 39238 var sort = ((options && options.sort) == null ? true : options.sort); 39239 models = _.isArray(models) ? models.slice() : [models]; 39240 39241 // Turn bare objects into model references, and prevent invalid models 39242 // from being added. 39243 for (i = models.length - 1; i >= 0; i--) { 39244 if(!(model = this._prepareModel(models[i], options))) { 39245 this.trigger("error", this, models[i], options); 39246 models.splice(i, 1); 39247 continue; 39248 } 39249 models[i] = model; 39250 39251 existing = model.id != null && this._byId[model.id]; 39252 // If a duplicate is found, prevent it from being added and 39253 // optionally merge it into the existing model. 39254 if (existing || this._byCid[model.cid]) { 39255 if (options && options.merge && existing) { 39256 existing.set(model.attributes, options); 39257 needsSort = sort; 39258 } 39259 models.splice(i, 1); 39260 continue; 39261 } 39262 39263 // Listen to added models' events, and index models for lookup by 39264 // `id` and by `cid`. 39265 model.on('all', this._onModelEvent, this); 39266 this._byCid[model.cid] = model; 39267 if (model.id != null) this._byId[model.id] = model; 39268 } 39269 39270 // See if sorting is needed, update `length` and splice in new models. 39271 if (models.length) needsSort = sort; 39272 this.length += models.length; 39273 args = [at != null ? at : this.models.length, 0]; 39274 push.apply(args, models); 39275 splice.apply(this.models, args); 39276 39277 // Sort the collection if appropriate. 39278 if (needsSort && this.comparator && at == null) this.sort({silent: true}); 39279 39280 if (options && options.silent) return this; 39281 39282 // Trigger `add` events. 39283 while (model = models.shift()) { 39284 model.trigger('add', model, this, options); 39285 } 39286 39287 return this; 39288 }, 39289 39290 // Remove a model, or a list of models from the set. Pass silent to avoid 39291 // firing the `remove` event for every model removed. 39292 remove: function(models, options) { 39293 var i, l, index, model;
39294 options || (options = {}); 39295 models = _.isArray(models) ? models.slice() : [models]; 39296 for (i = 0, l = models.length; i < l; i++) { 39297 model = this.get(models[i]); 39298 if (!model) continue; 39299 delete this._byId[model.id]; 39300 delete this._byCid[model.cid]; 39301 index = this.indexOf(model); 39302 this.models.splice(index, 1); 39303 this.length--; 39304 if (!options.silent) { 39305 options.index = index; 39306 model.trigger('remove', model, this, options); 39307 } 39308 this._removeReference(model); 39309 } 39310 return this; 39311 }, 39312 39313 // Add a model to the end of the collection. 39314 push: function(model, options) { 39315 model = this._prepareModel(model, options); 39316 this.add(model, _.extend({at: this.length}, options)); 39317 return model; 39318 }, 39319 39320 // Remove a model from the end of the collection. 39321 pop: function(options) { 39322 var model = this.at(this.length - 1); 39323 this.remove(model, options); 39324 return model; 39325 }, 39326 39327 // Add a model to the beginning of the collection. 39328 unshift: function(model, options) { 39329 model = this._prepareModel(model, options); 39330 this.add(model, _.extend({at: 0}, options)); 39331 return model; 39332 }, 39333 39334 // Remove a model from the beginning of the collection. 39335 shift: function(options) { 39336 var model = this.at(0); 39337 this.remove(model, options); 39338 return model; 39339 }, 39340 39341 // Slice out a sub-array of models from the collection. 39342 slice: function(begin, end) { 39343 return this.models.slice(begin, end); 39344 }, 39345 39346 // Get a model from the set by id. 39347 get: function(obj) { 39348 if (obj == null) return void 0; 39349 return this._byId[obj.id != null ? obj.id : obj] || this._byCid[obj.cid || obj]; 39350 }, 39351 39352 // Get the model at the given index. 39353 at: function(index) { 39354 return this.models[index]; 39355 }, 39356 39357 // Return models with matching attributes. Useful for simple cases of `filter`. 39358 where: function(attrs) { 39359 if (_.isEmpty(attrs)) return []; 39360 return this.filter(function(model) { 39361 for (var key in attrs) { 39362 if (attrs[key] !== model.get(key)) return false; 39363 } 39364 return true; 39365 }); 39366 }, 39367 39368 // Force the collection to re-sort itself. You don't need to call this under 39369 // normal circumstances, as the set will maintain sort order as each item 39370 // is added. 39371 sort: function(options) { 39372 if (!this.comparator) { 39373 throw new Error('Cannot sort a set without a comparator'); 39374 } 39375 39376 if (_.isString(this.comparator) || this.comparator.length === 1) { 39377 this.models = this.sortBy(this.comparator, this); 39378 } else { 39379 this.models.sort(_.bind(this.comparator, this)); 39380 } 39381 39382 if (!options || !options.silent) this.trigger('sort', this, options); 39383 return this; 39384 }, 39385 39386 // Pluck an attribute from each model in the collection. 39387 pluck: function(attr) { 39388 return _.invoke(this.models, 'get', attr); 39389 }, 39390 39391 // Smartly update a collection with a change set of models, adding, 39392 // removing, and merging as necessary. 39393 update: function(models, options) { 39394 var model, i, l, existing; 39395 var add = [], remove = [], modelMap = {}; 39396 var idAttr = this.model.prototype.idAttribute; 39397 options = _.extend({add: true, merge: true, remove: true}, options); 39398 if (options.parse) models = this.parse(models); 39399 39400 // Allow a single model (or no argument) to be passed. 39401 if (!_.isArray(models)) models = models ? [models] : []; 39402 39403 // Proxy to `add` for this case, no need to iterate... 39404 if (options.add && !options.remove) return this.add(models, options); 39405 39406 // Determine which models to add and merge, and which to remove. 39407 for (i = 0, l = models.length; i < l; i++) { 39408 model = models[i]; 39409 existing = this.get(model.id || model.cid || model[idAttr]); 39410 if (options.remove && existing) modelMap[existing.cid] = true; 39411 if ((options.add && !existing) || (options.merge && existing)) { 39412 add.push(model); 39413 } 39414 } 39415 if (options.remove) { 39416 for (i = 0, l = this.models.length; i < l; i++) { 39417 model = this.models[i]; 39418 if (!modelMap[model.cid]) remove.push(model); 39419 } 39420 } 39421 39422 // Remove models (if applicable) before we add and merge the rest. 39423 if (remove.length) this.remove(remove, options); 39424 if (add.length) this.add(add, options); 39425 return this; 39426 }, 39427 39428 // When you have more items than you want to add or remove individually, 39429 // you can reset the entire set with a new list of models, without firing 39430 // any `add` or `remove` events. Fires `reset` when finished. 39431 reset: function(models, options) {
39432 options || (options = {}); 39433 if (options.parse) models = this.parse(models); 39434 for (var i = 0, l = this.models.length; i < l; i++) { 39435 this._removeReference(this.models[i]); 39436 } 39437 options.previousModels = this.models; 39438 this._reset(); 39439 if (models) this.add(models, _.extend({silent: true}, options)); 39440 if (!options.silent) this.trigger('reset', this, options); 39441 return this; 39442 }, 39443 39444 // Fetch the default set of models for this collection, resetting the 39445 // collection when they arrive. If `add: true` is passed, appends the 39446 // models to the collection instead of resetting. 39447 fetch: function(options) { 39448 options = options ? _.clone(options) : {}; 39449 if (options.parse === void 0) options.parse = true; 39450 var collection = this; 39451 var success = options.success; 39452 options.success = function(resp, status, xhr) { 39453 var method = options.update ? 'update' : 'reset'; 39454 collection[method](resp, options); 39455 if (success) success(collection, resp, options); 39456 }; 39457 return this.sync('read', this, options); 39458 }, 39459 39460 // Create a new instance of a model in this collection. Add the model to the 39461 // collection immediately, unless `wait: true` is passed, in which case we 39462 // wait for the server to agree. 39463 create: function(model, options) { 39464 var collection = this; 39465 options = options ? _.clone(options) : {}; 39466 model = this._prepareModel(model, options); 39467 if (!model) return false; 39468 if (!options.wait) collection.add(model, options); 39469 var success = options.success; 39470 options.success = function(model, resp, options) { 39471 if (options.wait) collection.add(model, options); 39472 if (success) success(model, resp, options); 39473 }; 39474 model.save(null, options); 39475 return model; 39476 }, 39477 39478 // **parse** converts a response into a list of models to be added to the 39479 // collection. The default implementation is just to pass it through. 39480 parse: function(resp) { 39481 return resp; 39482 }, 39483 39484 // Create a new collection with an identical list of models as this one. 39485 clone: function() { 39486 return new this.constructor(this.models); 39487 }, 39488 39489 // Proxy to _'s chain. Can't be proxied the same way the rest of the 39490 // underscore methods are proxied because it relies on the underscore 39491 // constructor. 39492 chain: function() { 39493 return _(this.models).chain(); 39494 }, 39495 39496 // Reset all internal state. Called when the collection is reset. 39497 _reset: function() { 39498 this.length = 0; 39499 this.models = []; 39500 this._byId = {}; 39501 this._byCid = {}; 39502 }, 39503 39504 // Prepare a model or hash of attributes to be added to this collection. 39505 _prepareModel: function(attrs, options) { 39506 if (attrs instanceof Model) { 39507 if (!attrs.collection) attrs.collection = this; 39508 return attrs; 39509 } 39510 options || (options = {}); 39511 options.collection = this; 39512 var model = new this.model(attrs, options); 39513 if (!model._validate(attrs, options)) return false; 39514 return model; 39515 }, 39516 39517 // Internal method to remove a model's ties to a collection. 39518 _removeReference: function(model) { 39519 if (this === model.collection) delete model.collection; 39520 model.off('all', this._onModelEvent, this); 39521 }, 39522 39523 // Internal method called every time a model in the set fires an event. 39524 // Sets need to update their indexes when models change ids. All other 39525 // events simply proxy through. "add" and "remove" events that originate 39526 // in other collections are ignored. 39527 _onModelEvent: function(event, model, collection, options) { 39528 if ((event === 'add' || event === 'remove') && collection !== this) return; 39529 if (event === 'destroy') this.remove(model, options); 39530 if (model && event === 'change:' + model.idAttribute) { 39531 delete this._byId[model.previous(model.idAttribute)]; 39532 if (model.id != null) this._byId[model.id] = model; 39533 } 39534 this.trigger.apply(this, arguments); 39535 } 39536 39537 }); 39538 39539 // Underscore methods that we want to implement on the Collection. 39540 var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', 39541 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', 39542 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', 39543 'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take', 39544 'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle', 39545 'lastIndexOf', 'isEmpty']; 39546
39547 // Mix in each Underscore method as a proxy to `Collection#models`. 39548 _.each(methods, function(method) { 39549 Collection.prototype[method] = function() { 39550 var args = slice.call(arguments); 39551 args.unshift(this.models); 39552 return _[method].apply(_, args); 39553 }; 39554 }); 39555 39556 // Underscore methods that take a property name as an argument. 39557 var attributeMethods = ['groupBy', 'countBy', 'sortBy']; 39558 39559 // Use attributes instead of properties. 39560 _.each(attributeMethods, function(method) { 39561 Collection.prototype[method] = function(value, context) { 39562 var iterator = _.isFunction(value) ? value : function(model) { 39563 return model.get(value); 39564 }; 39565 return _[method](this.models, iterator, context); 39566 }; 39567 }); 39568 39569 // Backbone.Router 39570 // --------------- 39571 39572 // Routers map faux-URLs to actions, and fire events when routes are 39573 // matched. Creating a new one sets its `routes` hash, if not set statically. 39574 var Router = Backbone.Router = function(options) { 39575 options || (options = {}); 39576 if (options.routes) this.routes = options.routes; 39577 this._bindRoutes(); 39578 this.initialize.apply(this, arguments); 39579 }; 39580 39581 // Cached regular expressions for matching named param parts and splatted 39582 // parts of route strings. 39583 var optionalParam = /\((.*?)\)/g; 39584 var namedParam = /:\w+/g; 39585 var splatParam = /\*\w+/g; 39586 var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; 39587 39588 // Set up all inheritable **Backbone.Router** properties and methods. 39589 _.extend(Router.prototype, Events, { 39590 39591 // Initialize is an empty function by default. Override it with your own 39592 // initialization logic. 39593 initialize: function(){}, 39594 39595 // Manually bind a single named route to a callback. For example: 39596 // 39597 // this.route('search/:query/p:num', 'search', function(query, num) { 39598 // ... 39599 // }); 39600 // 39601 route: function(route, name, callback) { 39602 if (!_.isRegExp(route)) route = this._routeToRegExp(route); 39603 if (!callback) callback = this[name]; 39604 Backbone.history.route(route, _.bind(function(fragment) { 39605 var args = this._extractParameters(route, fragment); 39606 callback && callback.apply(this, args); 39607 this.trigger.apply(this, ['route:' + name].concat(args)); 39608 Backbone.history.trigger('route', this, name, args); 39609 }, this)); 39610 return this; 39611 }, 39612 39613 // Simple proxy to `Backbone.history` to save a fragment into the history. 39614 navigate: function(fragment, options) { 39615 Backbone.history.navigate(fragment, options); 39616 return this; 39617 }, 39618 39619 // Bind all defined routes to `Backbone.history`. We have to reverse the 39620 // order of the routes here to support behavior where the most general 39621 // routes can be defined at the bottom of the route map. 39622 _bindRoutes: function() { 39623 if (!this.routes) return; 39624 var route, routes = _.keys(this.routes); 39625 while ((route = routes.pop()) != null) { 39626 this.route(route, this.routes[route]); 39627 } 39628 }, 39629 39630 // Convert a route string into a regular expression, suitable for matching 39631 // against the current location hash. 39632 _routeToRegExp: function(route) { 39633 route = route.replace(escapeRegExp, '\\$&') 39634 .replace(optionalParam, '(?:$1)?') 39635 .replace(namedParam, '([^\/]+)') 39636 .replace(splatParam, '(.*?)'); 39637 return new RegExp('^' + route + '$'); 39638 }, 39639 39640 // Given a route, and a URL fragment that it matches, return the array of 39641 // extracted parameters. 39642 _extractParameters: function(route, fragment) { 39643 return route.exec(fragment).slice(1); 39644 } 39645 39646 }); 39647 39648 // Backbone.History 39649 // ---------------- 39650 39651 // Handles cross-browser history management, based on URL fragments. If the 39652 // browser does not support `onhashchange`, falls back to polling. 39653 var History = Backbone.History = function() { 39654 this.handlers = []; 39655 _.bindAll(this, 'checkUrl'); 39656 39657 // #1653 - Ensure that `History` can be used outside of the browser. 39658 if (typeof window !== 'undefined') { 39659 this.location = window.location; 39660 this.history = window.history; 39661 } 39662 }; 39663 39664 // Cached regex for stripping a leading hash/slash and trailing space. 39665 var routeStripper = /^[#\/]|\s+$/g; 39666 39667 // Cached regex for stripping leading and trailing slashes. 39668 var rootStripper = /^\/+|\/+$/g; 39669 39670 // Cached regex for detecting MSIE. 39671 var isExplorer = /msie [\w.]+/; 39672 39673 // Cached regex for removing a trailing slash. 39674 var trailingSlash = /\/$/; 39675 39676 // Has the history handling already been started? 39677 History.started = false;
39678 39679 // Set up all inheritable **Backbone.History** properties and methods. 39680 _.extend(History.prototype, Events, { 39681 39682 // The default interval to poll for hash changes, if necessary, is 39683 // twenty times a second. 39684 interval: 50, 39685 39686 // Gets the true hash value. Cannot use location.hash directly due to bug 39687 // in Firefox where location.hash will always be decoded. 39688 getHash: function(window) { 39689 var match = (window || this).location.href.match(/#(.*)$/); 39690 return match ? match[1] : ''; 39691 }, 39692 39693 // Get the cross-browser normalized URL fragment, either from the URL, 39694 // the hash, or the override. 39695 getFragment: function(fragment, forcePushState) { 39696 if (fragment == null) { 39697 if (this._hasPushState || !this._wantsHashChange || forcePushState) { 39698 fragment = this.location.pathname; 39699 var root = this.root.replace(trailingSlash, ''); 39700 if (!fragment.indexOf(root)) fragment = fragment.substr(root.length); 39701 } else { 39702 fragment = this.getHash(); 39703 } 39704 } 39705 return fragment.replace(routeStripper, ''); 39706 }, 39707 39708 // Start the hash change handling, returning `true` if the current URL matches 39709 // an existing route, and `false` otherwise. 39710 start: function(options) { 39711 if (History.started) throw new Error("Backbone.history has already been started"); 39712 History.started = true; 39713 39714 // Figure out the initial configuration. Do we need an iframe? 39715 // Is pushState desired ... is it available? 39716 this.options = _.extend({}, {root: '/'}, this.options, options); 39717 this.root = this.options.root; 39718 this._wantsHashChange = this.options.hashChange !== false; 39719 this._wantsPushState = !!this.options.pushState; 39720 this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); 39721 var fragment = this.getFragment(); 39722 var docMode = document.documentMode; 39723 var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); 39724 39725 // Normalize root to always include a leading and trailing slash. 39726 this.root = ('/' + this.root + '/').replace(rootStripper, '/'); 39727 39728 if (oldIE && this._wantsHashChange) { 39729 this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow; 39730 this.navigate(fragment); 39731 } 39732 39733 // Depending on whether we're using pushState or hashes, and whether 39734 // 'onhashchange' is supported, determine how we check the URL state. 39735 if (this._hasPushState) { 39736 Backbone.$(window).bind('popstate', this.checkUrl); 39737 } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { 39738 Backbone.$(window).bind('hashchange', this.checkUrl); 39739 } else if (this._wantsHashChange) { 39740 this._checkUrlInterval = setInterval(this.checkUrl, this.interval); 39741 } 39742 39743 // Determine if we need to change the base url, for a pushState link 39744 // opened by a non-pushState browser. 39745 this.fragment = fragment; 39746 var loc = this.location; 39747 var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root; 39748 39749 // If we've started off with a route from a `pushState`-enabled browser, 39750 // but we're currently in a browser that doesn't support it... 39751 if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) { 39752 this.fragment = this.getFragment(null, true); 39753 this.location.replace(this.root + this.location.search + '#' + this.fragment); 39754 // Return immediately as browser will do redirect to new url 39755 return true; 39756 39757 // Or if we've started out with a hash-based route, but we're currently 39758 // in a browser where it could be `pushState`-based instead... 39759 } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) { 39760 this.fragment = this.getHash().replace(routeStripper, ''); 39761 this.history.replaceState({}, document.title, this.root + this.fragment + loc.search); 39762 } 39763 39764 if (!this.options.silent) return this.loadUrl(); 39765 }, 39766 39767 // Disable Backbone.history, perhaps temporarily. Not useful in a real app, 39768 // but possibly useful for unit testing Routers. 39769 stop: function() { 39770 Backbone.$(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl); 39771 clearInterval(this._checkUrlInterval); 39772 History.started = false;
39773 }, 39774 39775 // Add a route to be tested when the fragment changes. Routes added later 39776 // may override previous routes. 39777 route: function(route, callback) { 39778 this.handlers.unshift({route: route, callback: callback}); 39779 }, 39780 39781 // Checks the current URL to see if it has changed, and if it has, 39782 // calls `loadUrl`, normalizing across the hidden iframe. 39783 checkUrl: function(e) { 39784 var current = this.getFragment(); 39785 if (current === this.fragment && this.iframe) { 39786 current = this.getFragment(this.getHash(this.iframe)); 39787 } 39788 if (current === this.fragment) return false; 39789 if (this.iframe) this.navigate(current); 39790 this.loadUrl() || this.loadUrl(this.getHash()); 39791 }, 39792 39793 // Attempt to load the current URL fragment. If a route succeeds with a 39794 // match, returns `true`. If no defined routes matches the fragment, 39795 // returns `false`. 39796 loadUrl: function(fragmentOverride) { 39797 var fragment = this.fragment = this.getFragment(fragmentOverride); 39798 var matched = _.any(this.handlers, function(handler) { 39799 if (handler.route.test(fragment)) { 39800 handler.callback(fragment); 39801 return true; 39802 } 39803 }); 39804 return matched; 39805 }, 39806 39807 // Save a fragment into the hash history, or replace the URL state if the 39808 // 'replace' option is passed. You are responsible for properly URL-encoding 39809 // the fragment in advance. 39810 // 39811 // The options object can contain `trigger: true` if you wish to have the 39812 // route callback be fired (not usually desirable), or `replace: true`, if 39813 // you wish to modify the current URL without adding an entry to the history. 39814 navigate: function(fragment, options) { 39815 if (!History.started) return false; 39816 if (!options || options === true) options = {trigger: options}; 39817 fragment = this.getFragment(fragment || ''); 39818 if (this.fragment === fragment) return; 39819 this.fragment = fragment; 39820 var url = this.root + fragment; 39821 39822 // If pushState is available, we use it to set the fragment as a real URL. 39823 if (this._hasPushState) { 39824 this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url); 39825 39826 // If hash changes haven't been explicitly disabled, update the hash 39827 // fragment to store history. 39828 } else if (this._wantsHashChange) { 39829 this._updateHash(this.location, fragment, options.replace); 39830 if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) { 39831 // Opening and closing the iframe tricks IE7 and earlier to push a 39832 // history entry on hash-tag change. When replace is true, we don't 39833 // want this. 39834 if(!options.replace) this.iframe.document.open().close(); 39835 this._updateHash(this.iframe.location, fragment, options.replace); 39836 } 39837 39838 // If you've told us that you explicitly don't want fallback hashchange- 39839 // based history, then `navigate` becomes a page refresh. 39840 } else { 39841 return this.location.assign(url); 39842 } 39843 if (options.trigger) this.loadUrl(fragment); 39844 }, 39845 39846 // Update the hash location, either replacing the current entry, or adding 39847 // a new one to the browser history. 39848 _updateHash: function(location, fragment, replace) { 39849 if (replace) { 39850 var href = location.href.replace(/(javascript:|#).*$/, ''); 39851 location.replace(href + '#' + fragment); 39852 } else { 39853 // #1649 - Some browsers require that `hash` contains a leading #. 39854 location.hash = '#' + fragment; 39855 } 39856 } 39857 39858 }); 39859 39860 // Create the default Backbone.history. 39861 Backbone.history = new History; 39862 39863 // Backbone.View 39864 // ------------- 39865 39866 // Creating a Backbone.View creates its initial element outside of the DOM, 39867 // if an existing element is not provided... 39868 var View = Backbone.View = function(options) { 39869 this.cid = _.uniqueId('view'); 39870 this._configure(options || {}); 39871 this._ensureElement(); 39872 this.initialize.apply(this, arguments); 39873 this.delegateEvents(); 39874 }; 39875 39876 // Cached regex to split keys for `delegate`. 39877 var delegateEventSplitter = /^(\S+)\s*(.*)$/; 39878 39879 // List of view options to be merged as properties. 39880 var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; 39881 39882 // Set up all inheritable **Backbone.View** properties and methods. 39883 _.extend(View.prototype, Events, { 39884 39885 // The default `tagName` of a View's element is `"div"`. 39886 tagName: 'div', 39887 39888 // jQuery delegate for element lookup, scoped to DOM elements within the 39889 // current view. This should be prefered to global lookups where possible. 39890 $: function(selector) { 39891 return this.$el.find(selector); 39892 }, 39893 39894 // Initialize is an empty function by default. Override it with your own 39895 // initialization logic. 39896 initialize: function(){}, 39897 39898 // **render** is the core function that your view should override, in order 39899 // to populate its element (`this.el`), with the appropriate HTML. The 39900 // convention is for **render** to always return `this`. 39901 render: function() { 39902 return this; 39903 }, 39904 39905 // Remove this view by taking the element out of the DOM, and removing any 39906 // applicable Backbone.Events listeners. 39907 remove: function() { 39908 this.$el.remove(); 39909 this.stopListening(); 39910 return this; 39911 }, 39912 39913 // For small amounts of DOM Elements, where a full-blown template isn't 39914 // needed, use **make** to manufacture elements, one at a time. 39915 // 39916 // var el = this.make('li', {'class': 'row'}, this.model.escape('title')); 39917 // 39918 make: function(tagName, attributes, content) { 39919 var el = document.createElement(tagName); 39920 if (attributes) Backbone.$(el).attr(attributes); 39921 if (content != null) Backbone.$(el).html(content); 39922 return el; 39923 }, 39924 39925 // Change the view's element (`this.el` property), including event 39926 // re-delegation. 39927 setElement: function(element, delegate) { 39928 if (this.$el) this.undelegateEvents(); 39929 this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); 39930 this.el = this.$el[0]; 39931 if (delegate !== false) this.delegateEvents(); 39932 return this; 39933 }, 39934 39935 // Set callbacks, where `this.events` is a hash of 39936 // 39937 // *{"event selector": "callback"}* 39938 // 39939 // { 39940 // 'mousedown .title': 'edit', 39941 // 'click .button': 'save' 39942 // 'click .open': function(e) { ... } 39943 // } 39944 // 39945 // pairs. Callbacks will be bound to the view, with `this` set properly. 39946 // Uses event delegation for efficiency. 39947 // Omitting the selector binds the event to `this.el`. 39948 // This only works for delegate-able events: not `focus`, `blur`, and 39949 // not `change`, `submit`, and `reset` in Internet Explorer. 39950 delegateEvents: function(events) { 39951 if (!(events || (events = _.result(this, 'events')))) return; 39952 this.undelegateEvents(); 39953 for (var key in events) { 39954 var method = events[key]; 39955 if (!_.isFunction(method)) method = this[events[key]];
39956 if (!method) throw new Error('Method "' + events[key] + '" does not exist'); 39957 var match = key.match(delegateEventSplitter); 39958 var eventName = match[1], selector = match[2]; 39959 method = _.bind(method, this); 39960 eventName += '.delegateEvents' + this.cid; 39961 if (selector === '') { 39962 this.$el.bind(eventName, method); 39963 } else { 39964 this.$el.delegate(selector, eventName, method); 39965 } 39966 } 39967 }, 39968 39969 // Clears all callbacks previously bound to the view with `delegateEvents`. 39970 // You usually don't need to use this, but may wish to if you have multiple 39971 // Backbone views attached to the same DOM element. 39972 undelegateEvents: function() { 39973 this.$el.unbind('.delegateEvents' + this.cid); 39974 }, 39975 39976 // Performs the initial configuration of a View with a set of options. 39977 // Keys with special meaning *(model, collection, id, className)*, are 39978 // attached directly to the view. 39979 _configure: function(options) { 39980 if (this.options) options = _.extend({}, _.result(this, 'options'), options); 39981 _.extend(this, _.pick(options, viewOptions)); 39982 this.options = options; 39983 }, 39984 39985 // Ensure that the View has a DOM element to render into. 39986 // If `this.el` is a string, pass it through `$()`, take the first 39987 // matching element, and re-assign it to `el`. Otherwise, create 39988 // an element from the `id`, `className` and `tagName` properties. 39989 _ensureElement: function() { 39990 if (!this.el) { 39991 var attrs = _.extend({}, _.result(this, 'attributes')); 39992 if (this.id) attrs.id = _.result(this, 'id'); 39993 if (this.className) attrs['class'] = _.result(this, 'className'); 39994 this.setElement(this.make(_.result(this, 'tagName'), attrs), false); 39995 } else { 39996 this.setElement(_.result(this, 'el'), false); 39997 } 39998 } 39999 40000 }); 40001 40002 // Backbone.sync 40003 // ------------- 40004 40005 // Map from CRUD to HTTP for our default `Backbone.sync` implementation. 40006 var methodMap = { 40007 'create': 'POST', 40008 'update': 'PUT', 40009 'patch': 'PATCH', 40010 'delete': 'DELETE', 40011 'read': 'GET' 40012 }; 40013 40014 // Override this function to change the manner in which Backbone persists 40015 // models to the server. You will be passed the type of request, and the 40016 // model in question. By default, makes a RESTful Ajax request 40017 // to the model's `url()`. Some possible customizations could be: 40018 // 40019 // * Use `setTimeout` to batch rapid-fire updates into a single request. 40020 // * Send up the models as XML instead of JSON. 40021 // * Persist models via WebSockets instead of Ajax. 40022 // 40023 // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests 40024 // as `POST`, with a `_method` parameter containing the true HTTP method, 40025 // as well as all requests with the body as `application/x-www-form-urlencoded` 40026 // instead of `application/json` with the model in a param named `model`. 40027 // Useful when interfacing with server-side languages like **PHP** that make 40028 // it difficult to read the body of `PUT` requests. 40029 Backbone.sync = function(method, model, options) { 40030 var type = methodMap[method]; 40031 40032 // Default options, unless specified. 40033 _.defaults(options || (options = {}), { 40034 emulateHTTP: Backbone.emulateHTTP, 40035 emulateJSON: Backbone.emulateJSON 40036 }); 40037 40038 // Default JSON-request options. 40039 var params = {type: type, dataType: 'json'}; 40040 40041 // Ensure that we have a URL. 40042 if (!options.url) { 40043 params.url = _.result(model, 'url') || urlError(); 40044 } 40045 40046 // Ensure that we have the appropriate request data. 40047 if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { 40048 params.contentType = 'application/json'; 40049 params.data = JSON.stringify(options.attrs || model.toJSON(options)); 40050 } 40051 40052 // For older servers, emulate JSON by encoding the request into an HTML-form. 40053 if (options.emulateJSON) { 40054 params.contentType = 'application/x-www-form-urlencoded'; 40055 params.data = params.data ? {model: params.data} : {}; 40056 } 40057 40058 // For older servers, emulate HTTP by mimicking the HTTP method with `_method` 40059 // And an `X-HTTP-Method-Override` header. 40060 if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { 40061 params.type = 'POST'; 40062 if (options.emulateJSON) params.data._method = type; 40063 var beforeSend = options.beforeSend; 40064 options.beforeSend = function(xhr) { 40065 xhr.setRequestHeader('X-HTTP-Method-Override', type); 40066 if (beforeSend) return beforeSend.apply(this, arguments); 40067 }; 40068 } 40069 40070 // Don't process data on a non-GET request. 40071 if (params.type !== 'GET' && !options.emulateJSON) { 40072 params.processData = false;
40073 } 40074 40075 var success = options.success; 40076 options.success = function(resp, status, xhr) { 40077 if (success) success(resp, status, xhr); 40078 model.trigger('sync', model, resp, options); 40079 }; 40080 40081 var error = options.error; 40082 options.error = function(xhr, status, thrown) { 40083 if (error) error(model, xhr, options); 40084 model.trigger('error', model, xhr, options); 40085 }; 40086 40087 // Make the request, allowing the user to override any Ajax options. 40088 var xhr = Backbone.ajax(_.extend(params, options)); 40089 model.trigger('request', model, xhr, options); 40090 return xhr; 40091 }; 40092 40093 // Set the default implementation of `Backbone.ajax` to proxy through to `$`. 40094 Backbone.ajax = function() { 40095 return Backbone.$.ajax.apply(Backbone.$, arguments); 40096 }; 40097 40098 // Helpers 40099 // ------- 40100 40101 // Helper function to correctly set up the prototype chain, for subclasses. 40102 // Similar to `goog.inherits`, but uses a hash of prototype properties and 40103 // class properties to be extended. 40104 var extend = function(protoProps, staticProps) { 40105 var parent = this; 40106 var child; 40107 40108 // The constructor function for the new subclass is either defined by you 40109 // (the "constructor" property in your `extend` definition), or defaulted 40110 // by us to simply call the parent's constructor. 40111 if (protoProps && _.has(protoProps, 'constructor')) { 40112 child = protoProps.constructor; 40113 } else { 40114 child = function(){ parent.apply(this, arguments); }; 40115 } 40116 40117 // Add static properties to the constructor function, if supplied.
40118 _.extend(child, parent, staticProps); 40119 40120 // Set the prototype chain to inherit from `parent`, without calling 40121 // `parent`'s constructor function. 40122 var Surrogate = function(){ this.constructor = child; }; 40123 Surrogate.prototype = parent.prototype; 40124 child.prototype = new Surrogate; 40125 40126 // Add prototype properties (instance properties) to the subclass, 40127 // if supplied. 40128 if (protoProps) _.extend(child.prototype, protoProps); 40129 40130 // Set a convenience property in case the parent's prototype is needed 40131 // later. 40132 child.__super__ = parent.prototype; 40133 40134 return child; 40135 }; 40136 40137 // Set up inheritance for the model, collection, router, view and history. 40138 Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend; 40139 40140 // Throw an error when a URL is needed, and none is supplied. 40141 var urlError = function() { 40142 throw new Error('A "url" property or function must be specified'); 40143 }; 40144 40145}).call(this); 40146(function($) { 40147 var methodMap = { 40148 'create': 'POST', 40149 'update': 'PUT', 40150 'delete': 'DELETE', 40151 'read' : 'GET' 40152 }; 40153 40154 var getUrl = function(object) { 40155 if (!(object && object.url)) return null; 40156 return _.isFunction(object.url) ? object.url() : object.url; 40157 }; 40158 40159 var urlError = function() { 40160 throw new Error("A 'url' property or function must be specified"); 40161 }; 40162 40163 Backbone.sync = function(method, model, options) { 40164 var type = methodMap[method]; 40165 40166 // Default JSON-request options. 40167 var params = _.extend({ 40168 type: type, 40169 dataType: 'json', 40170 beforeSend: function( xhr ) { 40171 var token = $('meta[name="csrf-token"]').attr('content'); 40172 if (token) xhr.setRequestHeader('X-CSRF-Token', token); 40173 40174 model.trigger('sync:start'); 40175 } 40176 }, options); 40177 40178 if (!params.url) { 40179 params.url = getUrl(model) || urlError(); 40180 } 40181 40182 // Ensure that we have the appropriate request data. 40183 if (!params.data && model && (method == 'create' || method == 'update')) { 40184 params.contentType = 'application/json'; 40185 40186 var data = {} 40187 40188 if(model.paramRoot) { 40189 data[model.paramRoot] = model.toJSON(); 40190 } else { 40191 data = model.toJSON(); 40192 } 40193 40194 params.data = JSON.stringify(data) 40195 } 40196 40197 // Don't process data on a non-GET request. 40198 if (params.type !== 'GET') { 40199 params.processData = false; 40200 } 40201 40202 // Trigger the sync end event 40203 var complete = options.complete; 40204 params.complete = function(jqXHR, textStatus) { 40205 model.trigger('sync:end'); 40206 if (complete) complete(jqXHR, textStatus); 40207 }; 40208 40209 // Make the request. 40210 return $.ajax(params); 40211 } 40212 40213})(jQuery); 40214/** 40215 * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com) 40216 * 40217 * Dual licensed under the MIT and GPL licenses. 40218 * This basically means you can use this code however you want for 40219 * free, but don't claim to have written it yourself! 40220 * Donations always accepted: http://www.JavascriptToolbox.com/donate/ 40221 * 40222 * Please do not link to the .js files on javascripttoolbox.com from 40223 * your site. Copy the files locally to your server instead. 40224 * 40225 */ 40226 40227eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('8.$2m=1.2n;8.Q=u(x){e(x<0||x>9?"":"0")+x};8.1g=B R(\'2o\',\'2p\',\'2l\',\'2k\',\'1z\',\'2g\',\'2h\',\'2i\',\'2j\',\'2q\',\'2r\',\'2y\');8.14=B R(\'2z\',\'2A\',\'2x\',\'2w\',\'1z\',\'2s\',\'2t\',\'2u\',\'2v\',\'2f\',\'2b\',\'1R\');8.1d=B R(\'1W\',\'1Z\',\'1Y\',\'1V\',\'1U\',\'1S\',\'1T\');8.1f=B R(\'1X\',\'2e\',\'20\',\'2c\',\'2d\',\'2a\',\'27\');8.1s=1L;3(!8.C.1c){8.C.1c=u(){b S=7.1y();e(S<16?S+16:S)}}8.1q=u(r,t){3(1e(t)=="1a"||t==f||t==""){b 1D=B R(\'y-M-d\',\'G d, y\',\'G d,y\',\'y-G-d\',\'d-G-y\',\'G d\',\'G-d\',\'d-G\');b 1v=B R(\'M/d/y\',\'M-d-y\',\'M.d.y\',\'M/d\',\'M-d\');b 1t=B R(\'d/M/y\',\'d-M-y\',\'d.M.y\',\'d/M\',\'d-M\');b 1u=B R(1D,8.1s?1v:1t,8.1s?1t:1v);Z(b i=0;i<1u.g;i++){b l=1u[i];Z(b j=0;j<l.g;j++){b d=8.1q(r,l[j]);
402273(d!=f){e d}}}e f};7.1I=u(r){Z(b i=0;i<r.g;i++){3("26".2C(r.U(i))==-1){e 13}}e 1L};7.O=u(1E,i,1i,1C){Z(b x=1C;x>=1i;x--){b 5=1E.T(i,i+x);3(5.g<1i){e f}3(7.1I(5)){e 5}}e f};r=r+"";t=t+"";b o=0;b D=0;b c="";b 5="";b 2T="";b x,y;b A=B 8().1c();b v=1;b I=1;b p=0;b J=0;b L=0;b 10="";W(D<t.g){c=t.U(D);5="";W((t.U(D)==c)&&(D<t.g)){5+=t.U(D++)}3(5=="19"||5=="S"||5=="y"){3(5=="19"){x=4;y=4}3(5=="S"){x=2;y=2}3(5=="y"){x=2;y=4}A=7.O(r,o,x,y);3(A==f){e f}o+=A.g;3(A.g==2){3(A>2V){A=16+(A-0)}q{A=2R+(A-0)}}}q 3(5=="G"||5=="1P"){v=0;b Y=(5=="G"?(8.1g.2O(8.14)):8.14);Z(b i=0;i<Y.g;i++){b 1h=Y[i];3(r.T(o,o+1h.g).V()==1h.V()){v=(i%12)+1;o+=1h.g;1A}}3((v<1)||(v>12)){e f}}q 3(5=="1r"||5=="E"){b Y=(5=="1r"?8.1d:8.1f);Z(b i=0;i<Y.g;i++){b 18=Y[i];3(r.T(o,o+18.g).V()==18.V()){o+=18.g;1A}}}q 3(5=="1o"||5=="M"){v=7.O(r,o,5.g,2);3(v==f||(v<1)||(v>12)){e f}o+=v.g}q 3(5=="1m"||5=="d"){I=7.O(r,o,5.g,2);3(I==f||(I<1)||(I>2E)){e f}o+=I.g}q 3(5=="p"||5=="h"){p=7.O(r,o,5.g,2);3(p==f||(p<1)||(p>12)){e f}o+=p.g}q 3(5=="1k"||5=="H"){p=7.O(r,o,5.g,2);3(p==f||(p<0)||(p>23)){e f}o+=p.g}q 3(5=="1l"||5=="K"){p=7.O(r,o,5.g,2);3(p==f||(p<0)||(p>11)){e f}o+=p.g;p++}q 3(5=="1j"||5=="k"){p=7.O(r,o,5.g,2);3(p==f||(p<1)||(p>24)){e f}o+=p.g;p--}q 3(5=="J"||5=="m"){J=7.O(r,o,5.g,2);3(J==f||(J<0)||(J>1K)){e f}o+=J.g}q 3(5=="L"||5=="s"){L=7.O(r,o,5.g,2);3(L==f||(L<0)||(L>1K)){e f}o+=L.g}q 3(5=="a"){3(r.T(o,o+2).V()=="2J"){10="1w"}q 3(r.T(o,o+2).V()=="2N"){10="1x"}q{e f}o+=2}q{3(r.T(o,o+5.g)!=5){e f}q{o+=5.g}}}3(o!=r.g){e f}3(v==2){3(((A%4==0)&&(A%2M!=0))||(A%2L==0)){3(I>29){e f}}q{3(I>28){e f}}}3((v==4)||(v==6)||(v==9)||(v==11)){3(I>2K){e f}}3(p<12&&10=="1x"){p=p-0+12}q 3(p>11&&10=="1w"){p-=12}e B 8(A,v-1,I,p,J,L)};8.2I=u(r,t){e(8.1q(r,t)!=f)};8.C.2D=u(F){3(F==f){e 13}e(7.P()<F.P())};8.C.2F=u(F){3(F==f){e 13}e(7.P()>F.P())};8.C.2G=u(F){3(F==f){e 13}e(7.P()==F.P())};8.C.2W=u(F){3(F==f){e 13}b 1J=B 8(7.P()).1p();b 1F=B 8(F.P()).1p();e(1J.P()==1F.P())};8.C.t=u(t){t=t+"";b X="";b D=0;b c="";b 5="";b y=7.1y()+"";b M=7.1b()+1;b d=7.1Q();b E=7.15();b H=7.1N();b m=7.1G();b s=7.1H();b 19,S,G,1o,1m,p,h,J,L,10,1k,H,1l,K,1j,k;b n=B 2B();3(y.g<4){y=""+(+y+16)}n["y"]=""+y;n["19"]=y;n["S"]=y.T(2,4);n["M"]=M;n["1o"]=8.Q(M);n["G"]=8.1g[M-1];n["1P"]=8.14[M-1];n["d"]=d;n["1m"]=8.Q(d);n["E"]=8.1f[E];n["1r"]=8.1d[E];n["H"]=H;n["1k"]=8.Q(H);3(H==0){n["h"]=12}q 3(H>12){n["h"]=H-12}q{n["h"]=H}n["p"]=8.Q(n["h"]);n["K"]=n["h"]-1;n["k"]=n["H"]+1;n["1l"]=8.Q(n["K"]);n["1j"]=8.Q(n["k"]);3(H>11){n["a"]="1x"}q{n["a"]="1w"}n["m"]=m;n["J"]=8.Q(m);n["s"]=s;n["L"]=8.Q(s);W(D<t.g){c=t.U(D);5="";W((t.U(D)==c)&&(D<t.g)){5+=t.U(D++)}3(1e(n[5])!="1a"){X=X+n[5]}q{X=X+5}}e X};8.C.2P=u(){e 8.1d[7.15()]};8.C.2H=u(){e 8.1f[7.15()]};8.C.2U=u(){e 8.1g[7.1b()]};8.C.2Q=u(){e 8.14[7.1b()]};8.C.1p=u(){7.1O(0);7.1B(0);7.1M(0);7.2S(0);e 7};8.C.1n=u(N,z){3(1e(N)=="1a"||N==f||1e(z)=="1a"||z==f){e 7}z=+z;3(N==\'y\'){7.25(7.1c()+z)}q 3(N==\'M\'){7.22(7.1b()+z)}q 3(N==\'d\'){7.21(7.1Q()+z)}q 3(N==\'w\'){b 17=(z>0)?1:-1;W(z!=0){7.1n(\'d\',17);W(7.15()==0||7.15()==6){7.1n(\'d\',17)}z-=17}}q 3(N==\'h\'){7.1O(7.1N()+z)}q 3(N==\'m\'){7.1B(7.1G()+z)}q 3(N==\'s\'){7.1M(7.1H()+z)}e 7};',62,183,'|||if||token||this|Date|||var|||return|null|length|||||||value|i_val|hh|else|val||format|function|month||||number|year|new|prototype|i_format||date2|MMM||date|mm||ss||interval|getInt|getTime|LZ|Array|yy|substring|charAt|toLowerCase|while|result|names|for|ampm|||false|monthAbbreviations|getDay|1900|step|day_name|yyyy|undefined|getMonth|getFullYear|dayNames|typeof|dayAbbreviations|monthNames|month_name|minlength|kk|HH|KK|dd|add|MM|clearTime|parseString|EE|preferAmericanFormat|dateFirst|checkList|monthFirst|AM|PM|getYear|May|break|setMinutes|maxlength|generalFormats|str|d2|getMinutes|getSeconds|isInteger|d1|59|true|setSeconds|getHours|setHours|NNN|getDate|Dec|Friday|Saturday|Thursday|Wednesday|Sunday|Sun|Tuesday|Monday|Tue|setDate|setMonth|||setFullYear|1234567890|Sat|||Fri|Nov|Wed|Thu|Mon|Oct|June|July|August|September|April|March|VERSION|02|January|February|October|November|Jun|Jul|Aug|Sep|Apr|Mar|December|Jan|Feb|Object|indexOf|isBefore|31|isAfter|equals|getDayAbbreviation|isValid|am|30|400|100|pm|concat|getDayName|getMonthAbbreviation|2000|
40227setMilliseconds|token2|getMonthName|70|equalsIgnoreTime'.split('|'),0,{})) 40228; 40229/*! Image Map Resizer (imageMapResizer.min.js ) - v1.0.10 - 2019-04-10 40230 * Desc: Resize HTML imageMap to scaled image. 40231 * Copyright: (c) 2019 David J. Bradshaw - [email protected] 40232 * License: MIT 40233 */ 40234 40235 40236!function(){"use strict";function r(){function e(){var r={width:u.width/u.naturalWidth,height:u.height/u.naturalHeight},a={width:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-left"),10),height:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-top"),10)};i.forEach(function(e,t){var n=0;o[t].coords=e.split(",").map(function(e){var t=1==(n=1-n)?"width":"height";return a[t]+Math.floor(Number(e)*r[t])}).join(",")})}function t(e){return e.coords.replace(/ *, */g,",").replace(/ +/g,",")}function n(){clearTimeout(d),d=setTimeout(e,250)}function r(e){return document.querySelector('img[usemap="'+e+'"]')}var a=this,o=null,i=null,u=null,d=null;"function"!=typeof a._resize?(o=a.getElementsByTagName("area"),i=Array.prototype.map.call(o,t),u=r("#"+a.name)||r(a.name),a._resize=e,u.addEventListener("load",e,!1),window.addEventListener("focus",e,!1),window.addEventListener("resize",n,!1),window.addEventListener("readystatechange",e,!1),document.addEventListener("fullscreenchange",e,!1),u.width===u.naturalWidth&&u.height===u.naturalHeight||e()):a._resize()}function e(){function t(e){e&&(!function(e){if(!e.tagName)throw new TypeError("Object is not a valid DOM element");if("MAP"!==e.tagName.toUpperCase())throw new TypeError("Expected <MAP> tag, found <"+e.tagName+">.")}(e),r.call(e),n.push(e))}var n;return function(e){switch(n=[],typeof e){case"undefined":case"string":Array.prototype.forEach.call(document.querySelectorAll(e||"map"),t);break;case"object":t(e);break;default:throw new TypeError("Unexpected data type ("+typeof e+").")}return n}}"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&"object"==typeof module.exports?module.exports=e():window.imageMapResize=e(),"jQuery"in window&&(window.jQuery.fn.imageMapResize=function(){return this.filter("map").each(r).end()})}(); 40237 40238/* 40239* jQuery timepicker addon 40240* By: Trent Richardson [http://trentrichardson.com] 40241* Version 0.9.3 40242* Last Modified: 02/05/2011 40243* 40244* Copyright 2010 Trent Richardson 40245* Dual licensed under the MIT and GPL licenses. 40246* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt 40247* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt 40248* 40249* HERES THE CSS: 40250* .ui-timepicker-div .ui-widget-header{ margin-bottom: 8px; } 40251* .ui-timepicker-div dl{ text-align: left; } 40252* .ui-timepicker-div dl dt{ height: 25px; } 40253* .ui-timepicker-div dl dd{ margin: -25px 0 10px 65px; } 40254* .ui-timepicker-div td { font-size: 90%; } 40255*/ 40256 40257 40258(function($) { 40259 40260$.extend($.ui, { timepicker: { version: "0.9.3" } }); 40261 40262/* Time picker manager. 40263 Use the singleton instance of this class, $.timepicker, to interact with the time picker. 40264 Settings for (groups of) time pickers are maintained in an instance object, 40265 allowing multiple different settings on the same page. */ 40266 40267function Timepicker() { 40268 this.regional = []; // Available regional settings, indexed by language code 40269 this.regional[''] = { // Default regional settings 40270 currentText: 'Now', 40271 closeText: 'Done', 40272 ampm: false, 40273 timeFormat: 'hh:mm tt', 40274 timeOnlyTitle: 'Choose Time', 40275 timeText: 'Time', 40276 hourText: 'Hour', 40277 minuteText: 'Minute', 40278 secondText: 'Second' 40279 }; 40280 this._defaults = { // Global defaults for all the datetime picker instances 40281 showButtonPanel: true, 40282 timeOnly: false, 40283 showHour: true, 40284 showMinute: true, 40285 showSecond: false, 40286 showTime: true, 40287 stepHour: 0.05, 40288 stepMinute: 0.05, 40289 stepSecond: 0.05, 40290 hour: 0, 40291 minute: 0, 40292 second: 0, 40293 hourMin: 0, 40294 minuteMin: 0, 40295 secondMin: 0, 40296 hourMax: 23, 40297 minuteMax: 59, 40298 secondMax: 59, 40299 minDateTime: null, 40300 maxDateTime: null, 40301 hourGrid: 0, 40302 minuteGrid: 0, 40303 secondGrid: 0, 40304 alwaysSetTime: true, 40305 separator: ' ', 40306 altFieldTimeOnly: true, 40307 showTimepicker: true 40308 }; 40309 $.extend(this._defaults, this.regional['']); 40310} 40311 40312$.extend(Timepicker.prototype, { 40313 $input: null, 40314 $altInput: null, 40315 $timeObj: null, 40316 inst: null, 40317 hour_slider: null, 40318 minute_slider: null, 40319 second_slider: null, 40320 hour: 0, 40321 minute: 0, 40322 second: 0,
40323 hourMinOriginal: null, 40324 minuteMinOriginal: null, 40325 secondMinOriginal: null, 40326 hourMaxOriginal: null, 40327 minuteMaxOriginal: null, 40328 secondMaxOriginal: null, 40329 ampm: '', 40330 formattedDate: '', 40331 formattedTime: '', 40332 formattedDateTime: '', 40333 40334 /* Override the default settings for all instances of the time picker. 40335 @param settings object - the new settings to use as defaults (anonymous object) 40336 @return the manager object */ 40337 setDefaults: function(settings) { 40338 extendRemove(this._defaults, settings || {}); 40339 return this; 40340 }, 40341 40342 //######################################################################## 40343 // Create a new Timepicker instance 40344 //######################################################################## 40345 _newInst: function($input, o) { 40346 var tp_inst = new Timepicker(), 40347 inlineSettings = {}; 40348 40349 tp_inst.hour = tp_inst._defaults.hour; 40350 tp_inst.minute = tp_inst._defaults.minute; 40351 tp_inst.second = tp_inst._defaults.second; 40352 tp_inst.ampm = ''; 40353 tp_inst.$input = $input; 40354 40355 40356 for (var attrName in this._defaults) { 40357 var attrValue = $input.attr('time:' + attrName); 40358 if (attrValue) { 40359 try { 40360 inlineSettings[attrName] = eval(attrValue); 40361 } catch (err) { 40362 inlineSettings[attrName] = attrValue; 40363 } 40364 } 40365 } 40366 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { 40367 beforeShow: function(input, dp_inst) { 40368 if ($.isFunction(o.beforeShow)) 40369 o.beforeShow(input, dp_inst, tp_inst); 40370 }, 40371 onChangeMonthYear: function(year, month, dp_inst) { 40372 // Update the time as well : this prevents the time from disappearing from the $input field. 40373 tp_inst._updateDateTime(dp_inst); 40374 if ($.isFunction(o.onChangeMonthYear)) 40375 o.onChangeMonthYear(year, month, dp_inst, tp_inst); 40376 }, 40377 onClose: function(dateText, dp_inst) { 40378 if (tp_inst.timeDefined === true && $input.val() != '') 40379 tp_inst._updateDateTime(dp_inst); 40380 if ($.isFunction(o.onClose)) 40381 o.onClose(dateText, dp_inst, tp_inst); 40382 }, 40383 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); 40384 }); 40385 40386 if (o.altField) 40387 tp_inst.$altInput = $(o.altField) 40388 .css({ cursor: 'pointer' }) 40389 .focus(function(){ $input.trigger("focus"); }); 40390 40391 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. 40392 if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) 40393 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); 40394 if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) 40395 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); 40396 if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) 40397 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); 40398 if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) 40399 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); 40400 40401 return tp_inst; 40402 }, 40403 40404 //######################################################################## 40405 // add our sliders to the calendar 40406 //######################################################################## 40407 _addTimePicker: function(dp_inst) { 40408 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? 40409 this.$input.val() + ' ' + this.$altInput.val() : 40410 this.$input.val(); 40411 40412 this.timeDefined = this._parseTime(currDT); 40413 this._limitMinMaxDateTime(dp_inst, false); 40414 this._injectTimePicker(); 40415 }, 40416 40417 //######################################################################## 40418 // parse the time string from input value or _setTime 40419 //######################################################################## 40420 _parseTime: function(timeString, withDate) { 40421 var regstr = this._defaults.timeFormat.toString() 40422 .replace(/h{1,2}/ig, '(\\d?\\d)') 40423 .replace(/m{1,2}/ig, '(\\d?\\d)') 40424 .replace(/s{1,2}/ig, '(\\d?\\d)') 40425 .replace(/t{1,2}/ig, '(am|pm|a|p)?') 40426 .replace(/\s/g, '\\s?') + '$', 40427 order = this._getFormatPositions(), 40428 treg; 40429 40430 if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); 40431 40432 if (withDate || !this._defaults.timeOnly) { 40433 // the time should come after x number of characters and a space. 40434 // x = at least the length of text specified by the date format 40435 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); 40436 regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator + regstr; 40437 } 40438
40439 treg = timeString.match(new RegExp(regstr, 'i')); 40440 40441 if (treg) { 40442 if (order.t !== -1) 40443 this.ampm = ((treg[order.t] === undefined || treg[order.t].length === 0) ? 40444 '' : 40445 (treg[order.t].charAt(0).toUpperCase() == 'A') ? 'AM' : 'PM').toUpperCase(); 40446 40447 if (order.h !== -1) { 40448 if (this.ampm == 'AM' && treg[order.h] == '12') 40449 this.hour = 0; // 12am = 0 hour 40450 else if (this.ampm == 'PM' && treg[order.h] != '12') 40451 this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 40452 else this.hour = Number(treg[order.h]); 40453 } 40454 40455 if (order.m !== -1) this.minute = Number(treg[order.m]); 40456 if (order.s !== -1) this.second = Number(treg[order.s]); 40457 40458 return true; 40459 40460 } 40461 return false; 40462 }, 40463 40464 //######################################################################## 40465 // figure out position of time elements.. cause js cant do named captures 40466 //######################################################################## 40467 _getFormatPositions: function() { 40468 var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2})/g), 40469 orders = { h: -1, m: -1, s: -1, t: -1 }; 40470 40471 if (finds) 40472 for (var i = 0; i < finds.length; i++) 40473 if (orders[finds[i].toString().charAt(0)] == -1) 40474 orders[finds[i].toString().charAt(0)] = i + 1; 40475 40476 return orders; 40477 }, 40478 40479 //######################################################################## 40480 // generate and inject html for timepicker into ui datepicker 40481 //######################################################################## 40482 _injectTimePicker: function() { 40483 var $dp = this.inst.dpDiv, 40484 o = this._defaults, 40485 tp_inst = this, 40486 // Added by Peter Medeiros: 40487 // - Figure out what the hour/minute/second max should be based on the step values. 40488 // - Example: if stepMinute is 15, then minMax is 45. 40489 hourMax = (o.hourMax - (o.hourMax % o.stepHour)).toFixed(0), 40490 minMax = (o.minuteMax - (o.minuteMax % o.stepMinute)).toFixed(0), 40491 secMax = (o.secondMax - (o.secondMax % o.stepSecond)).toFixed(0), 40492 dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); 40493 40494 // Prevent displaying twice 40495 //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) { 40496 if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) { 40497 var noDisplay = ' style="display:none;"', 40498 html = '<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' + 40499 '<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' + 40500 ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' + 40501 '<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' + 40502 ((o.showTime) ? '' : noDisplay) + '></dd>' + 40503 '<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' + 40504 ((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>', 40505 hourGridSize = 0, 40506 minuteGridSize = 0, 40507 secondGridSize = 0, 40508 size; 40509 40510 if (o.showHour && o.hourGrid > 0) { 40511 html += '<dd class="ui_tpicker_hour">' + 40512 '<div id="ui_tpicker_hour_' + dp_id + '"' + ((o.showHour) ? '' : noDisplay) + '></div>' + 40513 '<div style="padding-left: 1px"><table><tr>'; 40514 40515 for (var h = o.hourMin; h < hourMax; h += o.hourGrid) { 40516 hourGridSize++; 40517 var tmph = (o.ampm && h > 12) ? h-12 : h; 40518 if (tmph < 10) tmph = '0' + tmph; 40519 if (o.ampm) { 40520 if (h == 0) tmph = 12 +'a'; 40521 else if (h < 12) tmph += 'a'; 40522 else tmph += 'p'; 40523 } 40524 html += '<td>' + tmph + '</td>'; 40525 } 40526 40527 html += '</tr></table></div>' + 40528 '</dd>'; 40529 } else html += '<dd class="ui_tpicker_hour" id="ui_tpicker_hour_' + dp_id + '"' + 40530 ((o.showHour) ? '' : noDisplay) + '></dd>'; 40531 40532 html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' + 40533 ((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>'; 40534 40535 if (o.showMinute && o.minuteGrid > 0) { 40536 html += '<dd class="ui_tpicker_minute ui_tpicker_minute_' + o.minuteGrid + '">' + 40537 '<div id="ui_tpicker_minute_' + dp_id + '"' + 40538 ((o.showMinute) ? '' : noDisplay) + '></div>' + 40539 '<div style="padding-left: 1px"><table><tr>'; 40540 40541 for (var m = o.minuteMin; m < minMax; m += o.minuteGrid) { 40542 minuteGridSize++; 40543 html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>'; 40544 } 40545 40546 html += '</tr></table></div>' + 40547 '</dd>'; 40548 } else html += '<dd class="ui_tpicker_minute" id="ui_tpicker_minute_' + dp_id + '"' + 40549 ((o.showMinute) ? '' : noDisplay) + '></dd>'; 40550 40551 html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' + 40552 ((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>'; 40553 40554 if (o.showSecond && o.secondGrid > 0) { 40555 html += '<dd class="ui_tpicker_second ui_tpicker_second_' + o.secondGrid + '">' + 40556 '<div id="ui_tpicker_second_' + dp_id + '"' + 40557 ((o.showSecond) ? '' : noDisplay) + '></div>' + 40558 '<div style="padding-left: 1px"><table><tr>'; 40559 40560 for (var s = o.secondMin; s < secMax; s += o.secondGrid) { 40561 secondGridSize++; 40562 html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>'; 40563 } 40564 40565 html += '</tr></table></div>' + 40566 '</dd>'; 40567 } else html += '<dd class="ui_tpicker_second" id="ui_tpicker_second_' + dp_id + '"' + 40568 ((o.showSecond) ? '' : noDisplay) + '></dd>'; 40569 40570 html += '</dl></div>'; 40571 $tp = $(html); 40572 40573 // if we only want time picker... 40574 if (o.timeOnly === true) { 40575 $tp.prepend( 40576 '<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + 40577 '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + 40578 '</div>'); 40579 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); 40580 } 40581 40582 this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({ 40583 orientation: "horizontal", 40584 value: this.hour, 40585 min: o.hourMin, 40586 max: hourMax, 40587 step: o.stepHour, 40588 slide: function(event, ui) { 40589 tp_inst.hour_slider.slider( "option", "value", ui.value); 40590 tp_inst._onTimeChange(); 40591 } 40592 }); 40593 40594 // Updated by Peter Medeiros: 40595 // - Pass in Event and UI instance into slide function 40596 this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({ 40597 orientation: "horizontal", 40598 value: this.minute, 40599 min: o.minuteMin, 40600 max: minMax, 40601 step: o.stepMinute, 40602 slide: function(event, ui) { 40603 // update the global minute slider instance value with the current slider value 40604 tp_inst.minute_slider.slider( "option", "value", ui.value); 40605 tp_inst._onTimeChange(); 40606 } 40607 }); 40608 40609 this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({ 40610 orientation: "horizontal", 40611 value: this.second, 40612 min: o.secondMin, 40613 max: secMax, 40614 step: o.stepSecond, 40615 slide: function(event, ui) { 40616 tp_inst.second_slider.slider( "option", "value", ui.value); 40617 tp_inst._onTimeChange(); 40618 } 40619 }); 40620 40621 // Add grid functionality 40622 if (o.showHour && o.hourGrid > 0) { 40623 size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin); 40624 40625 $tp.find(".ui_tpicker_hour table").css({ 40626 width: size + "%", 40627 marginLeft: (size / (-2 * hourGridSize)) + "%", 40628 borderCollapse: 'collapse' 40629 }).find("td").each( function(index) { 40630 $(this).click(function() { 40631 var h = $(this).html(); 40632 if(o.ampm) { 40633 var ap = h.substring(2).toLowerCase(), 40634 aph = parseInt(h.substring(0,2)); 40635 if (ap == 'a') { 40636 if (aph == 12) h = 0; 40637 else h = aph; 40638 } else if (aph == 12) h = 12; 40639 else h = aph + 12; 40640 } 40641 tp_inst.hour_slider.slider("option", "value", h); 40642 tp_inst._onTimeChange(); 40643 }).css({ 40644 cursor: 'pointer', 40645 width: (100 / hourGridSize) + '%', 40646 textAlign: 'center', 40647 overflow: 'hidden' 40648 }); 40649 }); 40650 } 40651 40652 if (o.showMinute && o.minuteGrid > 0) { 40653 size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin); 40654 $tp.find(".ui_tpicker_minute table").css({ 40655 width: size + "%", 40656 marginLeft: (size / (-2 * minuteGridSize)) + "%", 40657 borderCollapse: 'collapse' 40658 }).find("td").each(function(index) { 40659 $(this).click(function() { 40660 tp_inst.minute_slider.slider("option", "value", $(this).html()); 40661 tp_inst._onTimeChange(); 40662 }).css({ 40663 cursor: 'pointer', 40664 width: (100 / minuteGridSize) + '%', 40665 textAlign: 'center', 40666 overflow: 'hidden' 40667 }); 40668 }); 40669 } 40670 40671 if (o.showSecond && o.secondGrid > 0) { 40672 $tp.find(".ui_tpicker_second table").css({ 40673 width: size + "%", 40674 marginLeft: (size / (-2 * secondGridSize)) + "%", 40675 borderCollapse: 'collapse' 40676 }).find("td").each(function(index) { 40677 $(this).click(function() { 40678 tp_inst.second_slider.slider("option", "value", $(this).html()); 40679 tp_inst._onTimeChange(); 40680 }).css({ 40681 cursor: 'pointer', 40682 width: (100 / secondGridSize) + '%', 40683 textAlign: 'center', 40684 overflow: 'hidden' 40685 }); 40686 }); 40687 } 40688 40689 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); 40690 if ($buttonPanel.length) $buttonPanel.before($tp); 40691 else $dp.append($tp); 40692 40693 this.$timeObj = $('#ui_tpicker_time_'+ dp_id); 40694 40695 if (this.inst !== null) { 40696 var timeDefined = this.timeDefined; 40697 this._onTimeChange(); 40698 this.timeDefined = timeDefined; 40699 } 40700 40701 //Emulate datepicker onSelect behavior. Call on slidestop. 40702 var onSelect = tp_inst._defaults['onSelect']; 40703 if (onSelect) { 40704 var inputEl = tp_inst.$input ? tp_inst.$input[0] : null; 40705 var onSelectHandler = function() { 40706 onSelect.apply(inputEl, [tp_inst.formattedDateTime, tp_inst]); // trigger custom callback*/ 40707 } 40708 this.hour_slider.bind('slidestop',onSelectHandler); 40709 this.minute_slider.bind('slidestop',onSelectHandler); 40710 this.second_slider.bind('slidestop',onSelectHandler); 40711 } 40712 } 40713 }, 40714 40715 //######################################################################## 40716 // This function tries to limit the ability to go outside the 40717 // min/max date range 40718 //######################################################################## 40719 _limitMinMaxDateTime: function(dp_inst, adjustSliders){ 40720 var o = this._defaults, 40721 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay), 40722 tp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay, this.hour, this.minute, this.second, 0); 40723 40724 if(this._defaults.minDateTime !== null && dp_date){ 40725 var minDateTime = this._defaults.minDateTime, 40726 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); 40727
40728 if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null){ 40729 this.hourMinOriginal = o.hourMin; 40730 this.minuteMinOriginal = o.minuteMin; 40731 this.secondMinOriginal = o.secondMin; 40732 } 40733 40734 if(minDateTimeDate.getTime() == dp_date.getTime()){ 40735 this._defaults.hourMin = minDateTime.getHours(); 40736 this._defaults.minuteMin = minDateTime.getMinutes(); 40737 this._defaults.secondMin = minDateTime.getSeconds(); 40738 40739 if(this.hour < this._defaults.hourMin) this.hour = this._defaults.hourMin; 40740 if(this.minute < this._defaults.minuteMin) this.minute = this._defaults.minuteMin; 40741 if(this.second < this._defaults.secondMin) this.second = this._defaults.secondMin; 40742 }else{ 40743 this._defaults.hourMin = this.hourMinOriginal; 40744 this._defaults.minuteMin = this.minuteMinOriginal; 40745 this._defaults.secondMin = this.secondMinOriginal; 40746 } 40747 } 40748 40749 if(this._defaults.maxDateTime !== null && dp_date){ 40750 var maxDateTime = this._defaults.maxDateTime, 40751 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); 40752 40753 if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){ 40754 this.hourMaxOriginal = o.hourMax; 40755 this.minuteMaxOriginal = o.minuteMax; 40756 this.secondMaxOriginal = o.secondMax; 40757 } 40758 40759 if(maxDateTimeDate.getTime() == dp_date.getTime()){ 40760 this._defaults.hourMax = maxDateTime.getHours(); 40761 this._defaults.minuteMax = maxDateTime.getMinutes(); 40762 this._defaults.secondMax = maxDateTime.getSeconds(); 40763 40764 if(this.hour > this._defaults.hourMax){ this.hour = this._defaults.hourMax; } 40765 if(this.minute > this._defaults.minuteMax) this.minute = this._defaults.minuteMax; 40766 if(this.second > this._defaults.secondMax) this.second = this._defaults.secondMax; 40767 }else{ 40768 this._defaults.hourMax = this.hourMaxOriginal; 40769 this._defaults.minuteMax = this.minuteMaxOriginal; 40770 this._defaults.secondMax = this.secondMaxOriginal; 40771 } 40772 } 40773 40774 if(adjustSliders !== undefined && adjustSliders === true){ 40775 this.hour_slider.slider("option", { min: this._defaults.hourMin, max: this._defaults.hourMax }).slider('value', this.hour); 40776 this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: this._defaults.minuteMax }).slider('value', this.minute); 40777 this.second_slider.slider("option", { min: this._defaults.secondMin, max: this._defaults.secondMax }).slider('value', this.second); 40778 } 40779 40780 }, 40781 40782 //######################################################################## 40783 // when a slider moves, set the internal time... 40784 // on time change is also called when the time is updated in the text field 40785 //######################################################################## 40786 _onTimeChange: function() { 40787 var hour = (this.hour_slider) ? this.hour_slider.slider('value') : false, 40788 minute = (this.minute_slider) ? this.minute_slider.slider('value') : false, 40789 second = (this.second_slider) ? this.second_slider.slider('value') : false; 40790 40791 if (hour !== false) hour = parseInt(hour,10); 40792 if (minute !== false) minute = parseInt(minute,10); 40793 if (second !== false) second = parseInt(second,10); 40794 40795 var ampm = (hour < 12) ? 'AM' : 'PM'; 40796 40797 // If the update was done in the input field, the input field should not be updated. 40798 // If the update was done using the sliders, update the input field. 40799 var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || (this.ampm.length > 0 && this.ampm != ampm)); 40800 40801 if (hasChanged) { 40802 40803 if (hour !== false)this.hour = hour; 40804 if (minute !== false) this.minute = minute; 40805 if (second !== false) this.second = second; 40806 } 40807 if (this._defaults.ampm) this.ampm = ampm; 40808 40809 this._formatTime(); 40810 if (this.$timeObj) this.$timeObj.text(this.formattedTime); 40811 this.timeDefined = true; 40812 if (hasChanged) this._updateDateTime(); 40813 }, 40814 40815 //######################################################################## 40816 // format the time all pretty... 40817 //######################################################################## 40818 _formatTime: function(time, format, ampm) { 40819 if (ampm == undefined) ampm = this._defaults.ampm; 40820 time = time || { hour: this.hour, minute: this.minute, second: this.second, ampm: this.ampm }; 40821 var tmptime = format || this._defaults.timeFormat.toString(); 40822 40823 if (ampm) { 40824 var hour12 = ((time.ampm == 'AM') ? (time.hour) : (time.hour % 12)); 40825 hour12 = (Number(hour12) === 0) ? 12 : hour12; 40826 tmptime = tmptime.toString() 40827 .replace(/hh/g, ((hour12 < 10) ? '0' : '') + hour12) 40828 .replace(/h/g, hour12) 40829 .replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute) 40830 .replace(/m/g, time.minute) 40831 .replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second) 40832 .replace(/s/g, time.second) 40833 .replace(/TT/g, time.ampm.toUpperCase()) 40834 .replace(/tt/g, time.ampm.toLowerCase()) 40835 .replace(/T/g, time.ampm.charAt(0).toUpperCase()) 40836 .replace(/t/g, time.ampm.charAt(0).toLowerCase()); 40837 } else { 40838 tmptime = tmptime.toString() 40839 .replace(/hh/g, ((time.hour < 10) ? '0' : '') + time.hour) 40840 .replace(/h/g, time.hour) 40841 .replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute) 40842 .replace(/m/g, time.minute) 40843 .replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second) 40844 .replace(/s/g, time.second); 40845 tmptime = $.trim(tmptime.replace(/t/gi, '')); 40846 } 40847 40848 if (arguments.length) return tmptime; 40849 else this.formattedTime = tmptime; 40850 }, 40851 40852 //######################################################################## 40853 // update our input with the new date time.. 40854 //######################################################################## 40855 _updateDateTime: function(dp_inst) { 40856 dp_inst = this.inst || dp_inst, 40857 dt = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay), 40858 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), 40859 formatCfg = $.datepicker._getFormatConfig(dp_inst),
40860 timeAvailable = dt !== null && this.timeDefined; 40861 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); 40862 var formattedDateTime = this.formattedDate; 40863 if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) 40864 return; 40865 40866 if (this._defaults.timeOnly === true) { 40867 formattedDateTime = this.formattedTime; 40868 } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { 40869 formattedDateTime += this._defaults.separator + this.formattedTime; 40870 } 40871 40872 this.formattedDateTime = formattedDateTime; 40873 40874 if(!this._defaults.showTimepicker) { 40875 this.$input.val(this.formattedDate); 40876 } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) { 40877 this.$altInput.val(this.formattedTime); 40878 this.$input.val(this.formattedDate); 40879 } else if(this.$altInput) { 40880 this.$altInput.val(formattedDateTime); 40881 this.$input.val(formattedDateTime); 40882 } else { 40883 this.$input.val(formattedDateTime); 40884 } 40885 40886 this.$input.trigger("change"); 40887 } 40888 40889}); 40890 40891$.fn.extend({ 40892 //######################################################################## 40893 // shorthand just to use timepicker.. 40894 //######################################################################## 40895 timepicker: function(o) { 40896 o = o || {}; 40897 var tmp_args = arguments; 40898 40899 if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true }); 40900 40901 return $(this).each(function() { 40902 $.fn.datetimepicker.apply($(this), tmp_args); 40903 }); 40904 }, 40905 40906 //######################################################################## 40907 // extend timepicker to datepicker 40908 //######################################################################## 40909 datetimepicker: function(o) { 40910 o = o || {}; 40911 var $input = this, 40912 tmp_args = arguments; 40913 40914 if (typeof(o) == 'string'){ 40915 if(o == 'getDate') 40916 return $.fn.datepicker.apply($(this[0]), tmp_args); 40917 else 40918 return this.each(function() { 40919 var $t = $(this); 40920 $t.datepicker.apply($t, tmp_args); 40921 }); 40922 } 40923 else 40924 return this.each(function() { 40925 var $t = $(this); 40926 $t.datepicker($.timepicker._newInst($t, o)._defaults); 40927 }); 40928 } 40929}); 40930 40931//######################################################################## 40932// the bad hack :/ override datepicker so it doesnt close on select 40933// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 40934//######################################################################## 40935$.datepicker._base_selectDate = $.datepicker._selectDate; 40936$.datepicker._selectDate = function (id, dateStr) { 40937 var inst = this._getInst($(id)[0]), 40938 tp_inst = this._get(inst, 'timepicker'); 40939 40940 if (tp_inst) { 40941 tp_inst._limitMinMaxDateTime(inst, true); 40942 inst.inline = inst.stay_open = true; 40943 //This way the onSelect handler called from calendarpicker get the full dateTime 40944 this._base_selectDate(id, dateStr + tp_inst._defaults.separator + tp_inst.formattedTime); 40945 inst.inline = inst.stay_open = false; 40946 this._notifyChange(inst); 40947 this._updateDatepicker(inst); 40948 } 40949 else this._base_selectDate(id, dateStr); 40950}; 40951 40952//############################################################################################# 40953// second bad hack :/ override datepicker so it triggers an event when changing the input field 40954// and does not redraw the datepicker on every selectDate event 40955//############################################################################################# 40956$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; 40957$.datepicker._updateDatepicker = function(inst) { 40958 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { 40959 40960 this._base_updateDatepicker(inst); 40961 40962 // Reload the time control when changing something in the input text field. 40963 var tp_inst = this._get(inst, 'timepicker'); 40964 if(tp_inst) tp_inst._addTimePicker(inst); 40965 } 40966}; 40967 40968//####################################################################################### 40969// third bad hack :/ override datepicker so it allows spaces and colan in the input field 40970//####################################################################################### 40971$.datepicker._base_doKeyPress = $.datepicker._doKeyPress; 40972$.datepicker._doKeyPress = function(event) { 40973 var inst = $.datepicker._getInst(event.target),
vendor: 1,171 bytes, lines 40974-41001
40974 tp_inst = $.datepicker._get(inst, 'timepicker'); 40975 40976 if (tp_inst) { 40977 if ($.datepicker._get(inst, 'constrainInput')) { 40978 var ampm = tp_inst._defaults.ampm, 40979 datetimeChars = tp_inst._defaults.timeFormat.toString() 40980 .replace(/[hms]/g, '') 40981 .replace(/TT/g, ampm ? 'APM' : '') 40982 .replace(/T/g, ampm ? 'AP' : '') 40983 .replace(/tt/g, ampm ? 'apm' : '') 40984 .replace(/t/g, ampm ? 'ap' : '') + 40985 " " + 40986 tp_inst._defaults.separator + 40987 $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), 40988 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); 40989 return event.ctrlKey || (chr < ' ' || !datetimeChars || datetimeChars.indexOf(chr) > -1); 40990 } 40991 } 40992 40993 return $.datepicker._base_doKeyPress(event); 40994}; 40995 40996//####################################################################################### 40997// Override key up event to sync manual input changes. 40998//####################################################################################### 40999$.datepicker._base_doKeyUp = $.datepicker._doKeyUp; 41000$.datepicker._doKeyUp = function (event) { 41001 var inst = $.datepicker._getInst(event.target),
41002 tp_inst = $.datepicker._get(inst, 'timepicker'); 41003 41004 if (tp_inst) { 41005 if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) { 41006 try { 41007 $.datepicker._updateDatepicker(inst); 41008 } 41009 catch (err) { 41010 $.datepicker.log(err); 41011 } 41012 } 41013 } 41014 41015 return $.datepicker._base_doKeyUp(event); 41016}; 41017 41018//####################################################################################### 41019// override "Today" button to also grab the time. 41020//####################################################################################### 41021$.datepicker._base_gotoToday = $.datepicker._gotoToday; 41022$.datepicker._gotoToday = function(id) { 41023 this._base_gotoToday(id); 41024 this._setTime(this._getInst($(id)[0]), new Date()); 41025}; 41026 41027//####################################################################################### 41028// Disable & enable the Time in the datetimepicker 41029//####################################################################################### 41030$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) { 41031 var inst = this._getInst(target), 41032 tp_inst = this._get(inst, 'timepicker'); 41033 if (tp_inst) { 41034 tp_inst._defaults.showTimepicker = false; 41035 tp_inst._onTimeChange(); 41036 tp_inst._updateDateTime(inst); 41037 } 41038}; 41039 41040$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) { 41041 var inst = this._getInst(target), 41042 tp_inst = this._get(inst, 'timepicker'); 41043 if (tp_inst) { 41044 tp_inst._defaults.showTimepicker = true; 41045 tp_inst._onTimeChange(); 41046 tp_inst._updateDateTime(inst); 41047 } 41048}; 41049 41050//####################################################################################### 41051// Create our own set time function 41052//####################################################################################### 41053$.datepicker._setTime = function(inst, date) { 41054 var tp_inst = this._get(inst, 'timepicker'); 41055 if (tp_inst) { 41056 var defaults = tp_inst._defaults, 41057 // calling _setTime with no date sets time to defaults 41058 hour = date ? date.getHours() : defaults.hour, 41059 minute = date ? date.getMinutes() : defaults.minute, 41060 second = date ? date.getSeconds() : defaults.second; 41061 41062 //check if within min/max times.. 41063 if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax)) { 41064 hour = defaults.hourMin; 41065 minute = defaults.minuteMin; 41066 second = defaults.secondMin; 41067 } 41068 41069 if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour); 41070 else tp_inst.hour = hour; 41071 if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute); 41072 else tp_inst.minute = minute; 41073 if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second); 41074 else tp_inst.second = second; 41075 41076 tp_inst._onTimeChange(); 41077 tp_inst._updateDateTime(inst); 41078 } 41079}; 41080 41081//####################################################################################### 41082// Create new public method to set only time, callable as $().datepicker('setTime', date) 41083//####################################################################################### 41084$.datepicker._setTimeDatepicker = function(target, date, withDate) { 41085 var inst = this._getInst(target),
41086 tp_inst = this._get(inst, 'timepicker'); 41087 41088 if (tp_inst) { 41089 this._setDateFromField(inst); 41090 var tp_date; 41091 if (date) { 41092 if (typeof date == "string") { 41093 tp_inst._parseTime(date, withDate); 41094 tp_date = new Date(); 41095 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second); 41096 } 41097 else tp_date = new Date(date.getTime()); 41098 if (tp_date.toString() == 'Invalid Date') tp_date = undefined; 41099 } 41100 this._setTime(inst, tp_date); 41101 } 41102 41103}; 41104 41105//####################################################################################### 41106// override setDate() to allow setting time too within Date object 41107//####################################################################################### 41108$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; 41109$.datepicker._setDateDatepicker = function(target, date) { 41110 var inst = this._getInst(target), 41111 tp_date = (date instanceof Date) ? new Date(date.getTime()) : date; 41112 41113 this._updateDatepicker(inst); 41114 this._base_setDateDatepicker.apply(this, arguments); 41115 this._setTimeDatepicker(target, tp_date, true); 41116}; 41117 41118//####################################################################################### 41119// override getDate() to allow getting time too within Date object 41120//####################################################################################### 41121$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; 41122$.datepicker._getDateDatepicker = function(target, noDefault) { 41123 var inst = this._getInst(target),
41124 tp_inst = this._get(inst, 'timepicker'); 41125 41126 if (tp_inst) { 41127 this._setDateFromField(inst, noDefault); 41128 var date = this._getDate(inst); 41129 if (date && tp_inst._parseTime($(target).val(), true)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second); 41130 return date; 41131 } 41132 return this._base_getDateDatepicker(target, noDefault); 41133}; 41134 41135//####################################################################################### 41136// jQuery extend now ignores nulls! 41137//####################################################################################### 41138function extendRemove(target, props) { 41139 $.extend(target, props); 41140 for (var name in props) 41141 if (props[name] === null || props[name] === undefined) 41142 target[name] = props[name]; 41143 return target; 41144} 41145 41146$.timepicker = new Timepicker(); // singleton instance 41147$.timepicker.version = "0.9.3"; 41148 41149})(jQuery); 41150/** 41151 * jQuery Cookie plugin 41152 * 41153 * Copyright (c) 2010 Klaus Hartl (stilbuero.de) 41154 * Dual licensed under the MIT and GPL licenses: 41155 * http://www.opensource.org/licenses/mit-license.php 41156 * http://www.gnu.org/licenses/gpl.html 41157 * 41158 */ 41159 41160jQuery.cookie = function (key, value, options) { 41161 41162 // key and at least value given, set cookie... 41163 if (arguments.length > 1 && String(value) !== "[object Object]") { 41164 options = jQuery.extend({}, options); 41165 41166 if (value === null || value === undefined) { 41167 options.expires = -1; 41168 } 41169 41170 if (typeof options.expires === 'number') { 41171 var days = options.expires, t = options.expires = new Date(); 41172 t.setDate(t.getDate() + days); 41173 } 41174 41175 value = String(value); 41176 41177 return (document.cookie = [ 41178 encodeURIComponent(key), '=', 41179 options.raw ? value : encodeURIComponent(value), 41180 options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 41181 options.path ? '; path=' + options.path : '', 41182 options.domain ? '; domain=' + options.domain : '', 41183 options.secure ? '; secure' : '' 41184 ].join('')); 41185 } 41186 41187 // key and possibly options given, get cookie... 41188 options = value || {}; 41189 var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; 41190 return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; 41191}; 41192/*! 41193 * jQuery Cycle Plugin (with Transition Definitions) 41194 * Examples and documentation at: http://jquery.malsup.com/cycle/ 41195 * Copyright (c) 2007-2012 M. Alsup 41196 * Version: 2.9999.81 (15-JAN-2013) 41197 * Dual licensed under the MIT and GPL licenses. 41198 * http://jquery.malsup.com/license.html 41199 * Requires: jQuery v1.7.1 or later 41200 */ 41201 41202;(function($, undefined) { 41203"use strict"; 41204 41205var ver = '2.9999.81'; 41206 41207function debug(s) { 41208 if ($.fn.cycle.debug) 41209 log(s); 41210} 41211function log() { 41212 if (window.console && console.log) 41213 console.log('[cycle] ' + Array.prototype.join.call(arguments,' ')); 41214} 41215$.expr[':'].paused = function(el) { 41216 return el.cyclePause; 41217}; 41218 41219 41220// the options arg can be... 41221// a number - indicates an immediate transition should occur to the given slide index 41222// a string - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc) 41223// an object - properties to control the slideshow 41224// 41225// the arg2 arg can be... 41226// the name of an fx (only used in conjunction with a numeric value for 'options') 41227// the value true (only used in first arg == 'resume') and indicates 41228// that the resume should occur immediately (not wait for next timeout) 41229 41230$.fn.cycle = function(options, arg2) { 41231 var o = { s: this.selector, c: this.context }; 41232 41233 // in 1.3+ we can fix mistakes with the ready state 41234 if (this.length === 0 && options != 'stop') { 41235 if (!$.isReady && o.s) { 41236 log('DOM not ready, queuing slideshow'); 41237 $(function() { 41238 $(o.s,o.c).cycle(options,arg2); 41239 }); 41240 return this; 41241 } 41242 // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready() 41243 log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)')); 41244 return this; 41245 } 41246 41247 // iterate the matched nodeset 41248 return this.each(function() { 41249 var opts = handleArguments(this, options, arg2); 41250 if (opts === false) 41251 return; 41252 41253 opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink; 41254 41255 // stop existing slideshow for this container (if there is one) 41256 if (this.cycleTimeout) 41257 clearTimeout(this.cycleTimeout); 41258 this.cycleTimeout = this.cyclePause = 0; 41259 this.cycleStop = 0; // issue #108 41260 41261 var $cont = $(this); 41262 var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children(); 41263 var els = $slides.get(); 41264 41265 if (els.length < 2) { 41266 log('terminating; too few slides: ' + els.length); 41267 return; 41268 } 41269 41270 var opts2 = buildOptions($cont, $slides, els, opts, o); 41271 if (opts2 === false) 41272 return; 41273 41274 var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards); 41275
41276 // if it's an auto slideshow, kick it off 41277 if (startTime) { 41278 startTime += (opts2.delay || 0); 41279 if (startTime < 10) 41280 startTime = 10; 41281 debug('first timeout: ' + startTime); 41282 this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime); 41283 } 41284 }); 41285}; 41286 41287function triggerPause(cont, byHover, onPager) { 41288 var opts = $(cont).data('cycle.opts'); 41289 if (!opts) 41290 return; 41291 var paused = !!cont.cyclePause; 41292 if (paused && opts.paused) 41293 opts.paused(cont, opts, byHover, onPager); 41294 else if (!paused && opts.resumed) 41295 opts.resumed(cont, opts, byHover, onPager); 41296} 41297 41298// process the args that were passed to the plugin fn 41299function handleArguments(cont, options, arg2) { 41300 if (cont.cycleStop === undefined) 41301 cont.cycleStop = 0; 41302 if (options === undefined || options === null) 41303 options = {}; 41304 if (options.constructor == String) { 41305 switch(options) { 41306 case 'destroy': 41307 case 'stop': 41308 var opts = $(cont).data('cycle.opts'); 41309 if (!opts) 41310 return false; 41311 cont.cycleStop++; // callbacks look for change 41312 if (cont.cycleTimeout) 41313 clearTimeout(cont.cycleTimeout); 41314 cont.cycleTimeout = 0; 41315 if (opts.elements) 41316 $(opts.elements).stop(); 41317 $(cont).removeData('cycle.opts'); 41318 if (options == 'destroy') 41319 destroy(cont, opts); 41320 return false; 41321 case 'toggle': 41322 cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1; 41323 checkInstantResume(cont.cyclePause, arg2, cont); 41324 triggerPause(cont); 41325 return false; 41326 case 'pause': 41327 cont.cyclePause = 1; 41328 triggerPause(cont); 41329 return false; 41330 case 'resume': 41331 cont.cyclePause = 0; 41332 checkInstantResume(false, arg2, cont); 41333 triggerPause(cont); 41334 return false; 41335 case 'prev': 41336 case 'next': 41337 opts = $(cont).data('cycle.opts'); 41338 if (!opts) { 41339 log('options not found, "prev/next" ignored'); 41340 return false; 41341 } 41342 $.fn.cycle[options](opts); 41343 return false; 41344 default: 41345 options = { fx: options }; 41346 } 41347 return options; 41348 } 41349 else if (options.constructor == Number) { 41350 // go to the requested slide 41351 var num = options; 41352 options = $(cont).data('cycle.opts'); 41353 if (!options) { 41354 log('options not found, can not advance slide'); 41355 return false; 41356 } 41357 if (num < 0 || num >= options.elements.length) { 41358 log('invalid slide index: ' + num); 41359 return false; 41360 } 41361 options.nextSlide = num; 41362 if (cont.cycleTimeout) { 41363 clearTimeout(cont.cycleTimeout); 41364 cont.cycleTimeout = 0; 41365 } 41366 if (typeof arg2 == 'string') 41367 options.oneTimeFx = arg2; 41368 go(options.elements, options, 1, num >= options.currSlide); 41369 return false; 41370 } 41371 return options; 41372 41373 function checkInstantResume(isPaused, arg2, cont) { 41374 if (!isPaused && arg2 === true) { // resume now! 41375 var options = $(cont).data('cycle.opts'); 41376 if (!options) { 41377 log('options not found, can not resume'); 41378 return false; 41379 } 41380 if (cont.cycleTimeout) { 41381 clearTimeout(cont.cycleTimeout); 41382 cont.cycleTimeout = 0; 41383 } 41384 go(options.elements, options, 1, !options.backwards); 41385 } 41386 } 41387} 41388 41389function removeFilter(el, opts) { 41390 if (!$.support.opacity && opts.cleartype && el.style.filter) { 41391 try { el.style.removeAttribute('filter'); } 41392 catch(smother) {} // handle old opera versions 41393 } 41394} 41395 41396// unbind event handlers 41397function destroy(cont, opts) { 41398 if (opts.next) 41399 $(opts.next).unbind(opts.prevNextEvent); 41400 if (opts.prev) 41401 $(opts.prev).unbind(opts.prevNextEvent); 41402 41403 if (opts.pager || opts.pagerAnchorBuilder) 41404 $.each(opts.pagerAnchors || [], function() { 41405 this.unbind().remove(); 41406 }); 41407 opts.pagerAnchors = null; 41408 $(cont).unbind('mouseenter.cycle mouseleave.cycle'); 41409 if (opts.destroy) // callback 41410 opts.destroy(opts); 41411} 41412 41413// one-time initialization 41414function buildOptions($cont, $slides, els, options, o) { 41415 var startingSlideSpecified; 41416 // support metadata plugin (v1.0 and v2.0) 41417 var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {}); 41418 var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null; 41419 if (meta) 41420 opts = $.extend(opts, meta); 41421 if (opts.autostop) 41422 opts.countdown = opts.autostopCount || els.length; 41423 41424 var cont = $cont[0]; 41425 $cont.data('cycle.opts', opts); 41426 opts.$cont = $cont; 41427 opts.stopCount = cont.cycleStop; 41428 opts.elements = els; 41429 opts.before = opts.before ? [opts.before] : []; 41430 opts.after = opts.after ? [opts.after] : []; 41431 41432 // push some after callbacks 41433 if (!$.support.opacity && opts.cleartype) 41434 opts.after.push(function() { removeFilter(this, opts); }); 41435 if (opts.continuous) 41436 opts.after.push(function() { go(els,opts,0,!opts.backwards); }); 41437 41438 saveOriginalOpts(opts); 41439 41440 // clearType corrections 41441 if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg) 41442 clearTypeFix($slides); 41443 41444 // container requires non-static position so that slides can be position within 41445 if ($cont.css('position') == 'static') 41446 $cont.css('position', 'relative'); 41447 if (opts.width) 41448 $cont.width(opts.width); 41449 if (opts.height && opts.height != 'auto') 41450 $cont.height(opts.height); 41451 41452 if (opts.startingSlide !== undefined) { 41453 opts.startingSlide = parseInt(opts.startingSlide,10); 41454 if (opts.startingSlide >= els.length || opts.startSlide < 0) 41455 opts.startingSlide = 0; // catch bogus input 41456 else 41457 startingSlideSpecified = true; 41458 } 41459 else if (opts.backwards) 41460 opts.startingSlide = els.length - 1; 41461 else 41462 opts.startingSlide = 0; 41463 41464 // if random, mix up the slide array 41465 if (opts.random) { 41466 opts.randomMap = []; 41467 for (var i = 0; i < els.length; i++) 41468 opts.randomMap.push(i); 41469 opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); 41470 if (startingSlideSpecified) { 41471 // try to find the specified starting slide and if found set start slide index in the map accordingly 41472 for ( var cnt = 0; cnt < els.length; cnt++ ) { 41473 if ( opts.startingSlide == opts.randomMap[cnt] ) { 41474 opts.randomIndex = cnt; 41475 } 41476 } 41477 } 41478 else { 41479 opts.randomIndex = 1; 41480 opts.startingSlide = opts.randomMap[1]; 41481 } 41482 } 41483 else if (opts.startingSlide >= els.length) 41484 opts.startingSlide = 0; // catch bogus input 41485 opts.currSlide = opts.startingSlide || 0; 41486 var first = opts.startingSlide; 41487 41488 // set position and zIndex on all the slides
41489 $slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) { 41490 var z; 41491 if (opts.backwards) 41492 z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i; 41493 else 41494 z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i; 41495 $(this).css('z-index', z); 41496 }); 41497 41498 // make sure first slide is visible 41499 $(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case 41500 removeFilter(els[first], opts); 41501 41502 // stretch slides 41503 if (opts.fit) { 41504 if (!opts.aspect) { 41505 if (opts.width) 41506 $slides.width(opts.width); 41507 if (opts.height && opts.height != 'auto') 41508 $slides.height(opts.height); 41509 } else { 41510 $slides.each(function(){ 41511 var $slide = $(this); 41512 var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect; 41513 if( opts.width && $slide.width() != opts.width ) { 41514 $slide.width( opts.width ); 41515 $slide.height( opts.width / ratio ); 41516 } 41517 41518 if( opts.height && $slide.height() < opts.height ) { 41519 $slide.height( opts.height ); 41520 $slide.width( opts.height * ratio ); 41521 } 41522 }); 41523 } 41524 } 41525 41526 if (opts.center && ((!opts.fit) || opts.aspect)) { 41527 $slides.each(function(){ 41528 var $slide = $(this); 41529 $slide.css({ 41530 "margin-left": opts.width ? 41531 ((opts.width - $slide.width()) / 2) + "px" : 41532 0, 41533 "margin-top": opts.height ? 41534 ((opts.height - $slide.height()) / 2) + "px" : 41535 0 41536 }); 41537 }); 41538 } 41539 41540 if (opts.center && !opts.fit && !opts.slideResize) { 41541 $slides.each(function(){ 41542 var $slide = $(this); 41543 $slide.css({ 41544 "margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0, 41545 "margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0 41546 }); 41547 }); 41548 } 41549 41550 // stretch container 41551 var reshape = (opts.containerResize || opts.containerResizeHeight) && !$cont.innerHeight(); 41552 if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9 41553 var maxw = 0, maxh = 0; 41554 for(var j=0; j < els.length; j++) { 41555 var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight(); 41556 if (!w) w = e.offsetWidth || e.width || $e.attr('width'); 41557 if (!h) h = e.offsetHeight || e.height || $e.attr('height'); 41558 maxw = w > maxw ? w : maxw; 41559 maxh = h > maxh ? h : maxh; 41560 } 41561 if (opts.containerResize && maxw > 0 && maxh > 0) 41562 $cont.css({width:maxw+'px',height:maxh+'px'}); 41563 if (opts.containerResizeHeight && maxh > 0) 41564 $cont.css({height:maxh+'px'}); 41565 } 41566 41567 var pauseFlag = false; // https://github.com/malsup/cycle/issues/44 41568 if (opts.pause) 41569 $cont.bind('mouseenter.cycle', function(){ 41570 pauseFlag = true; 41571 this.cyclePause++; 41572 triggerPause(cont, true); 41573 }).bind('mouseleave.cycle', function(){ 41574 if (pauseFlag) 41575 this.cyclePause--; 41576 triggerPause(cont, true); 41577 }); 41578 41579 if (supportMultiTransitions(opts) === false) 41580 return false; 41581 41582 // apparently a lot of people use image slideshows without height/width attributes on the images. 41583 // Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that. 41584 var requeue = false; 41585 options.requeueAttempts = options.requeueAttempts || 0; 41586 $slides.each(function() { 41587 // try to get height/width of each slide 41588 var $el = $(this); 41589 this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0); 41590 this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0); 41591 41592 if ( $el.is('img') ) { 41593 var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete); 41594 // don't requeue for images that are still loading but have a valid size 41595 if (loading) { 41596 if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever 41597 log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH); 41598 setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout); 41599 requeue = true; 41600 return false; // break each loop 41601 } 41602 else { 41603 log('could not determine size of image: '+this.src, this.cycleW, this.cycleH); 41604 } 41605 } 41606 } 41607 return true; 41608 }); 41609 41610 if (requeue) 41611 return false;
41612 41613 opts.cssBefore = opts.cssBefore || {}; 41614 opts.cssAfter = opts.cssAfter || {}; 41615 opts.cssFirst = opts.cssFirst || {}; 41616 opts.animIn = opts.animIn || {}; 41617 opts.animOut = opts.animOut || {}; 41618 41619 $slides.not(':eq('+first+')').css(opts.cssBefore); 41620 $($slides[first]).css(opts.cssFirst); 41621 41622 if (opts.timeout) { 41623 opts.timeout = parseInt(opts.timeout,10); 41624 // ensure that timeout and speed settings are sane 41625 if (opts.speed.constructor == String) 41626 opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10); 41627 if (!opts.sync) 41628 opts.speed = opts.speed / 2; 41629 41630 var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250; 41631 while((opts.timeout - opts.speed) < buffer) // sanitize timeout 41632 opts.timeout += opts.speed; 41633 } 41634 if (opts.easing) 41635 opts.easeIn = opts.easeOut = opts.easing; 41636 if (!opts.speedIn) 41637 opts.speedIn = opts.speed; 41638 if (!opts.speedOut) 41639 opts.speedOut = opts.speed; 41640 41641 opts.slideCount = els.length; 41642 opts.currSlide = opts.lastSlide = first; 41643 if (opts.random) { 41644 if (++opts.randomIndex == els.length) 41645 opts.randomIndex = 0; 41646 opts.nextSlide = opts.randomMap[opts.randomIndex]; 41647 } 41648 else if (opts.backwards) 41649 opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1; 41650 else 41651 opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1; 41652 41653 // run transition init fn 41654 if (!opts.multiFx) { 41655 var init = $.fn.cycle.transitions[opts.fx]; 41656 if ($.isFunction(init)) 41657 init($cont, $slides, opts); 41658 else if (opts.fx != 'custom' && !opts.multiFx) { 41659 log('unknown transition: ' + opts.fx,'; slideshow terminating'); 41660 return false; 41661 } 41662 } 41663 41664 // fire artificial events 41665 var e0 = $slides[first]; 41666 if (!opts.skipInitializationCallbacks) { 41667 if (opts.before.length) 41668 opts.before[0].apply(e0, [e0, e0, opts, true]); 41669 if (opts.after.length) 41670 opts.after[0].apply(e0, [e0, e0, opts, true]); 41671 } 41672 if (opts.next) 41673 $(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);}); 41674 if (opts.prev) 41675 $(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);}); 41676 if (opts.pager || opts.pagerAnchorBuilder) 41677 buildPager(els,opts); 41678 41679 exposeAddSlide(opts, els); 41680 41681 return opts; 41682} 41683 41684// save off original opts so we can restore after clearing state 41685function saveOriginalOpts(opts) { 41686 opts.original = { before: [], after: [] }; 41687 opts.original.cssBefore = $.extend({}, opts.cssBefore); 41688 opts.original.cssAfter = $.extend({}, opts.cssAfter); 41689 opts.original.animIn = $.extend({}, opts.animIn); 41690 opts.original.animOut = $.extend({}, opts.animOut); 41691 $.each(opts.before, function() { opts.original.before.push(this); }); 41692 $.each(opts.after, function() { opts.original.after.push(this); }); 41693} 41694 41695function supportMultiTransitions(opts) { 41696 var i, tx, txs = $.fn.cycle.transitions; 41697 // look for multiple effects 41698 if (opts.fx.indexOf(',') > 0) { 41699 opts.multiFx = true; 41700 opts.fxs = opts.fx.replace(/\s*/g,'').split(','); 41701 // discard any bogus effect names 41702 for (i=0; i < opts.fxs.length; i++) { 41703 var fx = opts.fxs[i]; 41704 tx = txs[fx]; 41705 if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) { 41706 log('discarding unknown transition: ',fx); 41707 opts.fxs.splice(i,1); 41708 i--; 41709 } 41710 } 41711 // if we have an empty list then we threw everything away! 41712 if (!opts.fxs.length) { 41713 log('No valid transitions named; slideshow terminating.'); 41714 return false; 41715 } 41716 } 41717 else if (opts.fx == 'all') { // auto-gen the list of transitions 41718 opts.multiFx = true; 41719 opts.fxs = []; 41720 for (var p in txs) { 41721 if (txs.hasOwnProperty(p)) { 41722 tx = txs[p]; 41723 if (txs.hasOwnProperty(p) && $.isFunction(tx)) 41724 opts.fxs.push(p); 41725 } 41726 } 41727 } 41728 if (opts.multiFx && opts.randomizeEffects) { 41729 // munge the fxs array to make effect selection random 41730 var r1 = Math.floor(Math.random() * 20) + 30; 41731 for (i = 0; i < r1; i++) { 41732 var r2 = Math.floor(Math.random() * opts.fxs.length); 41733 opts.fxs.push(opts.fxs.splice(r2,1)[0]); 41734 } 41735 debug('randomized fx sequence: ',opts.fxs); 41736 } 41737 return true; 41738} 41739 41740// provide a mechanism for adding slides after the slideshow has started 41741function exposeAddSlide(opts, els) { 41742 opts.addSlide = function(newSlide, prepend) {
41743 var $s = $(newSlide), s = $s[0]; 41744 if (!opts.autostopCount) 41745 opts.countdown++; 41746 els[prepend?'unshift':'push'](s); 41747 if (opts.els) 41748 opts.els[prepend?'unshift':'push'](s); // shuffle needs this 41749 opts.slideCount = els.length; 41750 41751 // add the slide to the random map and resort 41752 if (opts.random) { 41753 opts.randomMap.push(opts.slideCount-1); 41754 opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); 41755 } 41756 41757 $s.css('position','absolute'); 41758 $s[prepend?'prependTo':'appendTo'](opts.$cont); 41759 41760 if (prepend) { 41761 opts.currSlide++; 41762 opts.nextSlide++; 41763 } 41764 41765 if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg) 41766 clearTypeFix($s); 41767 41768 if (opts.fit && opts.width) 41769 $s.width(opts.width); 41770 if (opts.fit && opts.height && opts.height != 'auto') 41771 $s.height(opts.height); 41772 s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height(); 41773 s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width(); 41774 41775 $s.css(opts.cssBefore); 41776 41777 if (opts.pager || opts.pagerAnchorBuilder) 41778 $.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts); 41779 41780 if ($.isFunction(opts.onAddSlide)) 41781 opts.onAddSlide($s); 41782 else 41783 $s.hide(); // default behavior 41784 }; 41785} 41786 41787// reset internal state; we do this on every pass in order to support multiple effects 41788$.fn.cycle.resetState = function(opts, fx) { 41789 fx = fx || opts.fx; 41790 opts.before = []; opts.after = []; 41791 opts.cssBefore = $.extend({}, opts.original.cssBefore); 41792 opts.cssAfter = $.extend({}, opts.original.cssAfter); 41793 opts.animIn = $.extend({}, opts.original.animIn); 41794 opts.animOut = $.extend({}, opts.original.animOut); 41795 opts.fxFn = null; 41796 $.each(opts.original.before, function() { opts.before.push(this); }); 41797 $.each(opts.original.after, function() { opts.after.push(this); }); 41798 41799 // re-init 41800 var init = $.fn.cycle.transitions[fx]; 41801 if ($.isFunction(init)) 41802 init(opts.$cont, $(opts.elements), opts); 41803}; 41804 41805// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt 41806function go(els, opts, manual, fwd) { 41807 var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide]; 41808 41809 // opts.busy is true if we're in the middle of an animation 41810 if (manual && opts.busy && opts.manualTrump) { 41811 // let manual transitions requests trump active ones 41812 debug('manualTrump in go(), stopping active transition'); 41813 $(els).stop(true,true); 41814 opts.busy = 0; 41815 clearTimeout(p.cycleTimeout); 41816 } 41817 41818 // don't begin another timeout-based transition if there is one active 41819 if (opts.busy) { 41820 debug('transition active, ignoring new tx request'); 41821 return; 41822 } 41823 41824 41825 // stop cycling if we have an outstanding stop request 41826 if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual) 41827 return; 41828 41829 // check to see if we should stop cycling based on autostop options 41830 if (!manual && !p.cyclePause && !opts.bounce && 41831 ((opts.autostop && (--opts.countdown <= 0)) || 41832 (opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) { 41833 if (opts.end) 41834 opts.end(opts); 41835 return; 41836 } 41837 41838 // if slideshow is paused, only transition on a manual trigger 41839 var changed = false; 41840 if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) { 41841 changed = true; 41842 var fx = opts.fx; 41843 // keep trying to get the slide size if we don't have it yet 41844 curr.cycleH = curr.cycleH || $(curr).height(); 41845 curr.cycleW = curr.cycleW || $(curr).width(); 41846 next.cycleH = next.cycleH || $(next).height(); 41847 next.cycleW = next.cycleW || $(next).width(); 41848 41849 // support multiple transition types 41850 if (opts.multiFx) { 41851 if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length)) 41852 opts.lastFx = 0; 41853 else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0)) 41854 opts.lastFx = opts.fxs.length - 1; 41855 fx = opts.fxs[opts.lastFx]; 41856 } 41857 41858 // one-time fx overrides apply to: $('div').cycle(3,'zoom'); 41859 if (opts.oneTimeFx) { 41860 fx = opts.oneTimeFx; 41861 opts.oneTimeFx = null; 41862 } 41863 41864 $.fn.cycle.resetState(opts, fx); 41865 41866 // run the before callbacks 41867 if (opts.before.length) 41868 $.each(opts.before, function(i,o) { 41869 if (p.cycleStop != opts.stopCount) return; 41870 o.apply(next, [curr, next, opts, fwd]); 41871 }); 41872 41873 // stage the after callacks 41874 var after = function() { 41875 opts.busy = 0; 41876 $.each(opts.after, function(i,o) { 41877 if (p.cycleStop != opts.stopCount) return; 41878 o.apply(next, [curr, next, opts, fwd]); 41879 }); 41880 if (!p.cycleStop) { 41881 // queue next transition 41882 queueNext(); 41883 } 41884 }; 41885 41886 debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide); 41887 41888 // get ready to perform the transition 41889 opts.busy = 1; 41890 if (opts.fxFn) // fx function provided? 41891 opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent); 41892 else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ? 41893 $.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent); 41894 else 41895 $.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent); 41896 } 41897 else { 41898 queueNext(); 41899 } 41900 41901 if (changed || opts.nextSlide == opts.currSlide) { 41902 // calculate the next slide 41903 var roll; 41904 opts.lastSlide = opts.currSlide; 41905 if (opts.random) { 41906 opts.currSlide = opts.nextSlide; 41907 if (++opts.randomIndex == els.length) { 41908 opts.randomIndex = 0; 41909 opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); 41910 } 41911 opts.nextSlide = opts.randomMap[opts.randomIndex]; 41912 if (opts.nextSlide == opts.currSlide) 41913 opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1; 41914 } 41915 else if (opts.backwards) { 41916 roll = (opts.nextSlide - 1) < 0; 41917 if (roll && opts.bounce) { 41918 opts.backwards = !opts.backwards; 41919 opts.nextSlide = 1; 41920 opts.currSlide = 0; 41921 } 41922 else { 41923 opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1; 41924 opts.currSlide = roll ? 0 : opts.nextSlide+1; 41925 } 41926 } 41927 else { // sequence 41928 roll = (opts.nextSlide + 1) == els.length; 41929 if (roll && opts.bounce) { 41930 opts.backwards = !opts.backwards; 41931 opts.nextSlide = els.length-2; 41932 opts.currSlide = els.length-1; 41933 } 41934 else { 41935 opts.nextSlide = roll ? 0 : opts.nextSlide+1; 41936 opts.currSlide = roll ? els.length-1 : opts.nextSlide-1; 41937 } 41938 } 41939 } 41940 if (changed && opts.pager) 41941 opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass); 41942 41943 function queueNext() { 41944 // stage the next transition 41945 var ms = 0, timeout = opts.timeout; 41946 if (opts.timeout && !opts.continuous) { 41947 ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd); 41948 if (opts.fx == 'shuffle') 41949 ms -= opts.speedOut; 41950 } 41951 else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic 41952 ms = 10; 41953 if (ms > 0) 41954 p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms); 41955 } 41956} 41957 41958// invoked after transition 41959$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) { 41960 $(pager).each(function() { 41961 $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName); 41962 }); 41963}; 41964 41965// calculate timeout value for current transition 41966function getTimeout(curr, next, opts, fwd) { 41967 if (opts.timeoutFn) { 41968 // call user provided calc fn 41969 var t = opts.timeoutFn.call(curr,curr,next,opts,fwd); 41970 while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout 41971 t += opts.speed;
41972 debug('calculated timeout: ' + t + '; speed: ' + opts.speed); 41973 if (t !== false) 41974 return t; 41975 } 41976 return opts.timeout; 41977} 41978 41979// expose next/prev function, caller must pass in state 41980$.fn.cycle.next = function(opts) { advance(opts,1); }; 41981$.fn.cycle.prev = function(opts) { advance(opts,0);}; 41982 41983// advance slide forward or back 41984function advance(opts, moveForward) { 41985 var val = moveForward ? 1 : -1; 41986 var els = opts.elements; 41987 var p = opts.$cont[0], timeout = p.cycleTimeout; 41988 if (timeout) { 41989 clearTimeout(timeout); 41990 p.cycleTimeout = 0; 41991 } 41992 if (opts.random && val < 0) { 41993 // move back to the previously display slide 41994 opts.randomIndex--; 41995 if (--opts.randomIndex == -2) 41996 opts.randomIndex = els.length-2; 41997 else if (opts.randomIndex == -1) 41998 opts.randomIndex = els.length-1; 41999 opts.nextSlide = opts.randomMap[opts.randomIndex]; 42000 } 42001 else if (opts.random) { 42002 opts.nextSlide = opts.randomMap[opts.randomIndex]; 42003 } 42004 else { 42005 opts.nextSlide = opts.currSlide + val; 42006 if (opts.nextSlide < 0) { 42007 if (opts.nowrap) return false; 42008 opts.nextSlide = els.length - 1; 42009 } 42010 else if (opts.nextSlide >= els.length) { 42011 if (opts.nowrap) return false; 42012 opts.nextSlide = 0; 42013 } 42014 } 42015 42016 var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated 42017 if ($.isFunction(cb)) 42018 cb(val > 0, opts.nextSlide, els[opts.nextSlide]); 42019 go(els, opts, 1, moveForward); 42020 return false; 42021} 42022 42023function buildPager(els, opts) { 42024 var $p = $(opts.pager); 42025 $.each(els, function(i,o) { 42026 $.fn.cycle.createPagerAnchor(i,o,$p,els,opts); 42027 }); 42028 opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass); 42029} 42030 42031$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) { 42032 var a; 42033 if ($.isFunction(opts.pagerAnchorBuilder)) { 42034 a = opts.pagerAnchorBuilder(i,el); 42035 debug('pagerAnchorBuilder('+i+', el) returned: ' + a); 42036 } 42037 else 42038 a = '<a href="#">'+(i+1)+'</a>'; 42039 42040 if (!a) 42041 return; 42042 var $a = $(a); 42043 // don't reparent if anchor is in the dom 42044 if ($a.parents('body').length === 0) { 42045 var arr = []; 42046 if ($p.length > 1) { 42047 $p.each(function() { 42048 var $clone = $a.clone(true); 42049 $(this).append($clone); 42050 arr.push($clone[0]); 42051 }); 42052 $a = $(arr); 42053 } 42054 else { 42055 $a.appendTo($p); 42056 } 42057 } 42058 42059 opts.pagerAnchors = opts.pagerAnchors || []; 42060 opts.pagerAnchors.push($a); 42061 42062 var pagerFn = function(e) { 42063 e.preventDefault(); 42064 opts.nextSlide = i; 42065 var p = opts.$cont[0], timeout = p.cycleTimeout; 42066 if (timeout) { 42067 clearTimeout(timeout); 42068 p.cycleTimeout = 0; 42069 } 42070 var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated 42071 if ($.isFunction(cb)) 42072 cb(opts.nextSlide, els[opts.nextSlide]); 42073 go(els,opts,1,opts.currSlide < i); // trigger the trans 42074// return false; // <== allow bubble 42075 }; 42076 42077 if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) { 42078 $a.hover(pagerFn, function(){/* no-op */} ); 42079 } 42080 else { 42081 $a.bind(opts.pagerEvent, pagerFn); 42082 } 42083 42084 if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble) 42085 $a.bind('click.cycle', function(){return false;}); // suppress click 42086 42087 var cont = opts.$cont[0]; 42088 var pauseFlag = false; // https://github.com/malsup/cycle/issues/44 42089 if (opts.pauseOnPagerHover) { 42090 $a.hover( 42091 function() { 42092 pauseFlag = true; 42093 cont.cyclePause++; 42094 triggerPause(cont,true,true); 42095 }, function() { 42096 if (pauseFlag) 42097 cont.cyclePause--; 42098 triggerPause(cont,true,true); 42099 } 42100 ); 42101 } 42102}; 42103 42104// helper fn to calculate the number of slides between the current and the next 42105$.fn.cycle.hopsFromLast = function(opts, fwd) { 42106 var hops, l = opts.lastSlide, c = opts.currSlide; 42107 if (fwd) 42108 hops = c > l ? c - l : opts.slideCount - l; 42109 else 42110 hops = c < l ? l - c : l + opts.slideCount - c; 42111 return hops; 42112}; 42113 42114// fix clearType problems in ie6 by setting an explicit bg color 42115// (otherwise text slides look horrible during a fade transition) 42116function clearTypeFix($slides) { 42117 debug('applying clearType background-color hack'); 42118 function hex(s) { 42119 s = parseInt(s,10).toString(16); 42120 return s.length < 2 ? '0'+s : s; 42121 } 42122 function getBg(e) { 42123 for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) { 42124 var v = $.css(e,'background-color'); 42125 if (v && v.indexOf('rgb') >= 0 ) { 42126 var rgb = v.match(/\d+/g); 42127 return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]); 42128 } 42129 if (v && v != 'transparent') 42130 return v; 42131 } 42132 return '#ffffff'; 42133 } 42134 $slides.each(function() { $(this).css('background-color', getBg(this)); }); 42135} 42136 42137// reset common props before the next transition 42138$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) { 42139 $(opts.elements).not(curr).hide(); 42140 if (typeof opts.cssBefore.opacity == 'undefined') 42141 opts.cssBefore.opacity = 1; 42142 opts.cssBefore.display = 'block'; 42143 if (opts.slideResize && w !== false && next.cycleW > 0) 42144 opts.cssBefore.width = next.cycleW; 42145 if (opts.slideResize && h !== false && next.cycleH > 0) 42146 opts.cssBefore.height = next.cycleH; 42147 opts.cssAfter = opts.cssAfter || {}; 42148 opts.cssAfter.display = 'none'; 42149 $(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0)); 42150 $(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1)); 42151}; 42152 42153// the actual fn for effecting a transition 42154$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) { 42155 var $l = $(curr), $n = $(next); 42156 var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut; 42157 $n.css(opts.cssBefore); 42158 if (speedOverride) { 42159 if (typeof speedOverride == 'number') 42160 speedIn = speedOut = speedOverride; 42161 else 42162 speedIn = speedOut = 1; 42163 easeIn = easeOut = null; 42164 } 42165 var fn = function() { 42166 $n.animate(opts.animIn, speedIn, easeIn, function() { 42167 cb(); 42168 }); 42169 }; 42170 $l.animate(opts.animOut, speedOut, easeOut, function() { 42171 $l.css(opts.cssAfter); 42172 if (!opts.sync) 42173 fn(); 42174 }); 42175 if (opts.sync) fn(); 42176}; 42177 42178// transition definitions - only fade is defined here, transition pack defines the rest 42179$.fn.cycle.transitions = { 42180 fade: function($cont, $slides, opts) { 42181 $slides.not(':eq('+opts.currSlide+')').css('opacity',0); 42182 opts.before.push(function(curr,next,opts) { 42183 $.fn.cycle.commonReset(curr,next,opts); 42184 opts.cssBefore.opacity = 0; 42185 }); 42186 opts.animIn = { opacity: 1 }; 42187 opts.animOut = { opacity: 0 }; 42188 opts.cssBefore = { top: 0, left: 0 }; 42189 } 42190}; 42191 42192$.fn.cycle.ver = function() { return ver; }; 42193 42194// override these globally if you like (they are all optional) 42195$.fn.cycle.defaults = {
42196 activePagerClass: 'activeSlide', // class name used for the active pager link 42197 after: null, // transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag) 42198 allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling 42199 animIn: null, // properties that define how the slide animates in 42200 animOut: null, // properties that define how the slide animates out 42201 aspect: false, // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option) 42202 autostop: 0, // true to end slideshow after X transitions (where X == slide count) 42203 autostopCount: 0, // number of transitions (optionally used with autostop to define X) 42204 backwards: false, // true to start slideshow at last slide and move backwards through the stack 42205 before: null, // transition callback (scope set to element to be shown): function(currSlideElement, nextSlideElement, options, forwardFlag) 42206 center: null, // set to true to have cycle add top/left margin to each slide (use with width and height options) 42207 cleartype: !$.support.opacity, // true if clearType corrections should be applied (for IE) 42208 cleartypeNoBg: false, // set to true to disable extra cleartype fixing (leave false to force background color setting on slides) 42209 containerResize: 1, // resize container to fit largest slide 42210 containerResizeHeight: 0, // resize containers height to fit the largest slide but leave the width dynamic 42211 continuous: 0, // true to start next transition immediately after current one completes 42212 cssAfter: null, // properties that defined the state of the slide after transitioning out 42213 cssBefore: null, // properties that define the initial state of the slide before transitioning in 42214 delay: 0, // additional delay (in ms) for first transition (hint: can be negative) 42215 easeIn: null, // easing for "in" transition 42216 easeOut: null, // easing for "out" transition 42217 easing: null, // easing method for both in and out transitions 42218 end: null, // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options) 42219 fastOnEvent: 0, // force fast transitions when triggered manually (via pager or prev/next); value == time in ms 42220 fit: 0, // force slides to fit container 42221 fx: 'fade', // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle') 42222 fxFn: null, // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag) 42223 height: 'auto', // container height (if the 'fit' option is true, the slides will be set to this height as well) 42224 manualTrump: true, // causes manual transition to stop an active transition instead of being ignored 42225 metaAttr: 'cycle', // data- attribute that holds the option data for the slideshow 42226 next: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide 42227 nowrap: 0, // true to prevent slideshow from wrapping 42228 onPagerEvent: null, // callback fn for pager events: function(zeroBasedSlideIndex, slideElement) 42229 onPrevNextEvent: null, // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement) 42230 pager: null, // element, jQuery object, or jQuery selector string for the element to use as pager container 42231 pagerAnchorBuilder: null, // callback fn for building anchor links: function(index, DOMelement) 42232 pagerEvent: 'click.cycle', // name of event which drives the pager navigation 42233 pause: 0, // true to enable "pause on hover" 42234 pauseOnPagerHover: 0, // true to pause when hovering over pager link 42235 prev: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide 42236 prevNextEvent: 'click.cycle',// event which drives the manual transition to the previous or next slide 42237 random: 0, // true for random, false for sequence (not applicable to shuffle fx) 42238 randomizeEffects: 1, // valid when multiple effects are used; true to make the effect sequence random 42239 requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded 42240 requeueTimeout: 250, // ms delay for requeue 42241 rev: 0, // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle) 42242 shuffle: null, // coords for shuffle animation, ex: { top:15, left: 200 } 42243 skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition 42244 slideExpr: null, // expression for selecting slides (if something other than all children is required) 42245 slideResize: 1, // force slide width/height to fixed size before every transition 42246 speed: 1000, // speed of the transition (any valid fx speed value) 42247 speedIn: null, // speed of the 'in' transition 42248 speedOut: null, // speed of the 'out' transition 42249 startingSlide: undefined,// zero-based index of the first slide to be displayed 42250 sync: 1, // true if in/out transitions should occur simultaneously 42251 timeout: 4000, // milliseconds between slide transitions (0 to disable auto advance) 42252 timeoutFn: null, // callback for determining per-slide timeout value: function(currSlideElement, nextSlideElement, options, forwardFlag) 42253 updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style) 42254 width: null // container width (if the 'fit' option is true, the slides will be set to this width as well) 42255}; 42256 42257}
42257)(jQuery); 42258 42259 42260/*! 42261 * jQuery Cycle Plugin Transition Definitions 42262 * This script is a plugin for the jQuery Cycle Plugin 42263 * Examples and documentation at: http://malsup.com/jquery/cycle/ 42264 * Copyright (c) 2007-2010 M. Alsup 42265 * Version: 2.73 42266 * Dual licensed under the MIT and GPL licenses: 42267 * http://www.opensource.org/licenses/mit-license.php 42268 * http://www.gnu.org/licenses/gpl.html 42269 */ 42270(function($) { 42271"use strict"; 42272 42273// 42274// These functions define slide initialization and properties for the named 42275// transitions. To save file size feel free to remove any of these that you 42276// don't need. 42277// 42278$.fn.cycle.transitions.none = function($cont, $slides, opts) { 42279 opts.fxFn = function(curr,next,opts,after){ 42280 $(next).show(); 42281 $(curr).hide(); 42282 after(); 42283 }; 42284}; 42285 42286// not a cross-fade, fadeout only fades out the top slide 42287$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) { 42288 $slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 }); 42289 opts.before.push(function(curr,next,opts,w,h,rev) { 42290 $(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0)); 42291 $(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1)); 42292 }); 42293 opts.animIn.opacity = 1; 42294 opts.animOut.opacity = 0; 42295 opts.cssBefore.opacity = 1; 42296 opts.cssBefore.display = 'block'; 42297 opts.cssAfter.zIndex = 0; 42298}; 42299 42300// scrollUp/Down/Left/Right 42301$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) { 42302 $cont.css('overflow','hidden'); 42303 opts.before.push($.fn.cycle.commonReset); 42304 var h = $cont.height(); 42305 opts.cssBefore.top = h; 42306 opts.cssBefore.left = 0; 42307 opts.cssFirst.top = 0; 42308 opts.animIn.top = 0; 42309 opts.animOut.top = -h; 42310}; 42311$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) { 42312 $cont.css('overflow','hidden'); 42313 opts.before.push($.fn.cycle.commonReset); 42314 var h = $cont.height(); 42315 opts.cssFirst.top = 0; 42316 opts.cssBefore.top = -h; 42317 opts.cssBefore.left = 0; 42318 opts.animIn.top = 0; 42319 opts.animOut.top = h; 42320}; 42321$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) { 42322 $cont.css('overflow','hidden'); 42323 opts.before.push($.fn.cycle.commonReset); 42324 var w = $cont.width(); 42325 opts.cssFirst.left = 0; 42326 opts.cssBefore.left = w; 42327 opts.cssBefore.top = 0; 42328 opts.animIn.left = 0; 42329 opts.animOut.left = 0-w; 42330}; 42331$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) { 42332 $cont.css('overflow','hidden'); 42333 opts.before.push($.fn.cycle.commonReset); 42334 var w = $cont.width(); 42335 opts.cssFirst.left = 0; 42336 opts.cssBefore.left = -w; 42337 opts.cssBefore.top = 0; 42338 opts.animIn.left = 0; 42339 opts.animOut.left = w; 42340}; 42341$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) { 42342 $cont.css('overflow','hidden').width(); 42343 opts.before.push(function(curr, next, opts, fwd) { 42344 if (opts.rev) 42345 fwd = !fwd; 42346 $.fn.cycle.commonReset(curr,next,opts); 42347 opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW); 42348 opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW; 42349 }); 42350 opts.cssFirst.left = 0; 42351 opts.cssBefore.top = 0; 42352 opts.animIn.left = 0; 42353 opts.animOut.top = 0; 42354}; 42355$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) { 42356 $cont.css('overflow','hidden'); 42357 opts.before.push(function(curr, next, opts, fwd) { 42358 if (opts.rev) 42359 fwd = !fwd; 42360 $.fn.cycle.commonReset(curr,next,opts); 42361 opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1); 42362 opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH; 42363 }); 42364 opts.cssFirst.top = 0; 42365 opts.cssBefore.left = 0; 42366 opts.animIn.top = 0; 42367 opts.animOut.left = 0; 42368}; 42369 42370// slideX/slideY 42371$.fn.cycle.transitions.slideX = function($cont, $slides, opts) { 42372 opts.before.push(function(curr, next, opts) { 42373 $(opts.elements).not(curr).hide(); 42374 $.fn.cycle.commonReset(curr,next,opts,false,true); 42375 opts.animIn.width = next.cycleW; 42376 }); 42377 opts.cssBefore.left = 0; 42378 opts.cssBefore.top = 0; 42379 opts.cssBefore.width = 0; 42380 opts.animIn.width = 'show'; 42381 opts.animOut.width = 0; 42382}; 42383$.fn.cycle.transitions.slideY = function($cont, $slides, opts) { 42384 opts.before.push(function(curr, next, opts) { 42385 $(opts.elements).not(curr).hide(); 42386 $.fn.cycle.commonReset(curr,next,opts,true,false); 42387 opts.animIn.height = next.cycleH; 42388 }); 42389 opts.cssBefore.left = 0; 42390 opts.cssBefore.top = 0; 42391 opts.cssBefore.height = 0; 42392 opts.animIn.height = 'show'; 42393 opts.animOut.height = 0; 42394}; 42395 42396// shuffle 42397$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) { 42398 var i, w = $cont.css('overflow', 'visible').width(); 42399 $slides.css({left: 0, top: 0}); 42400 opts.before.push(function(curr,next,opts) { 42401 $.fn.cycle.commonReset(curr,next,opts,true,true,true); 42402 }); 42403 // only adjust speed once! 42404 if (!opts.speedAdjusted) { 42405 opts.speed = opts.speed / 2; // shuffle has 2 transitions 42406 opts.speedAdjusted = true; 42407 } 42408 opts.random = 0; 42409 opts.shuffle = opts.shuffle || {left:-w, top:15}; 42410 opts.els = []; 42411 for (i=0; i < $slides.length; i++) 42412 opts.els.push($slides[i]); 42413 42414 for (i=0; i < opts.currSlide; i++) 42415 opts.els.push(opts.els.shift()); 42416 42417 // custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!) 42418 opts.fxFn = function(curr, next, opts, cb, fwd) { 42419 if (opts.rev) 42420 fwd = !fwd; 42421 var $el = fwd ? $(curr) : $(next); 42422 $(next).css(opts.cssBefore); 42423 var count = opts.slideCount; 42424 $el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() { 42425 var hops = $.fn.cycle.hopsFromLast(opts, fwd); 42426 for (var k=0; k < hops; k++) { 42427 if (fwd) 42428 opts.els.push(opts.els.shift()); 42429 else 42430 opts.els.unshift(opts.els.pop()); 42431 } 42432 if (fwd) { 42433 for (var i=0, len=opts.els.length; i < len; i++) 42434 $(opts.els[i]).css('z-index', len-i+count); 42435 } 42436 else { 42437 var z = $(curr).css('z-index'); 42438 $el.css('z-index', parseInt(z,10)+1+count); 42439 } 42440 $el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
42441 $(fwd ? this : curr).hide(); 42442 if (cb) cb(); 42443 }); 42444 }); 42445 }; 42446 $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 }); 42447}; 42448 42449// turnUp/Down/Left/Right 42450$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) { 42451 opts.before.push(function(curr, next, opts) { 42452 $.fn.cycle.commonReset(curr,next,opts,true,false); 42453 opts.cssBefore.top = next.cycleH; 42454 opts.animIn.height = next.cycleH; 42455 opts.animOut.width = next.cycleW; 42456 }); 42457 opts.cssFirst.top = 0; 42458 opts.cssBefore.left = 0; 42459 opts.cssBefore.height = 0; 42460 opts.animIn.top = 0; 42461 opts.animOut.height = 0; 42462}; 42463$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) { 42464 opts.before.push(function(curr, next, opts) { 42465 $.fn.cycle.commonReset(curr,next,opts,true,false); 42466 opts.animIn.height = next.cycleH; 42467 opts.animOut.top = curr.cycleH; 42468 }); 42469 opts.cssFirst.top = 0; 42470 opts.cssBefore.left = 0; 42471 opts.cssBefore.top = 0; 42472 opts.cssBefore.height = 0; 42473 opts.animOut.height = 0; 42474}; 42475$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) { 42476 opts.before.push(function(curr, next, opts) { 42477 $.fn.cycle.commonReset(curr,next,opts,false,true); 42478 opts.cssBefore.left = next.cycleW; 42479 opts.animIn.width = next.cycleW; 42480 }); 42481 opts.cssBefore.top = 0; 42482 opts.cssBefore.width = 0; 42483 opts.animIn.left = 0; 42484 opts.animOut.width = 0; 42485}; 42486$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) { 42487 opts.before.push(function(curr, next, opts) { 42488 $.fn.cycle.commonReset(curr,next,opts,false,true); 42489 opts.animIn.width = next.cycleW; 42490 opts.animOut.left = curr.cycleW; 42491 }); 42492 $.extend(opts.cssBefore, { top: 0, left: 0, width: 0 }); 42493 opts.animIn.left = 0; 42494 opts.animOut.width = 0; 42495}; 42496 42497// zoom 42498$.fn.cycle.transitions.zoom = function($cont, $slides, opts) { 42499 opts.before.push(function(curr, next, opts) { 42500 $.fn.cycle.commonReset(curr,next,opts,false,false,true); 42501 opts.cssBefore.top = next.cycleH/2; 42502 opts.cssBefore.left = next.cycleW/2; 42503 $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH }); 42504 $.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 }); 42505 }); 42506 opts.cssFirst.top = 0; 42507 opts.cssFirst.left = 0; 42508 opts.cssBefore.width = 0; 42509 opts.cssBefore.height = 0; 42510}; 42511 42512// fadeZoom 42513$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) { 42514 opts.before.push(function(curr, next, opts) { 42515 $.fn.cycle.commonReset(curr,next,opts,false,false); 42516 opts.cssBefore.left = next.cycleW/2; 42517 opts.cssBefore.top = next.cycleH/2; 42518 $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH }); 42519 }); 42520 opts.cssBefore.width = 0; 42521 opts.cssBefore.height = 0; 42522 opts.animOut.opacity = 0; 42523}; 42524 42525// blindX 42526$.fn.cycle.transitions.blindX = function($cont, $slides, opts) { 42527 var w = $cont.css('overflow','hidden').width(); 42528 opts.before.push(function(curr, next, opts) { 42529 $.fn.cycle.commonReset(curr,next,opts); 42530 opts.animIn.width = next.cycleW; 42531 opts.animOut.left = curr.cycleW; 42532 }); 42533 opts.cssBefore.left = w; 42534 opts.cssBefore.top = 0; 42535 opts.animIn.left = 0; 42536 opts.animOut.left = w; 42537}; 42538// blindY 42539$.fn.cycle.transitions.blindY = function($cont, $slides, opts) { 42540 var h = $cont.css('overflow','hidden').height(); 42541 opts.before.push(function(curr, next, opts) { 42542 $.fn.cycle.commonReset(curr,next,opts); 42543 opts.animIn.height = next.cycleH; 42544 opts.animOut.top = curr.cycleH; 42545 }); 42546 opts.cssBefore.top = h; 42547 opts.cssBefore.left = 0; 42548 opts.animIn.top = 0; 42549 opts.animOut.top = h; 42550}; 42551// blindZ 42552$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) { 42553 var h = $cont.css('overflow','hidden').height(); 42554 var w = $cont.width(); 42555 opts.before.push(function(curr, next, opts) { 42556 $.fn.cycle.commonReset(curr,next,opts); 42557 opts.animIn.height = next.cycleH; 42558 opts.animOut.top = curr.cycleH; 42559 }); 42560 opts.cssBefore.top = h; 42561 opts.cssBefore.left = w; 42562 opts.animIn.top = 0; 42563 opts.animIn.left = 0; 42564 opts.animOut.top = h; 42565 opts.animOut.left = w; 42566}; 42567 42568// growX - grow horizontally from centered 0 width 42569$.fn.cycle.transitions.growX = function($cont, $slides, opts) { 42570 opts.before.push(function(curr, next, opts) { 42571 $.fn.cycle.commonReset(curr,next,opts,false,true); 42572 opts.cssBefore.left = this.cycleW/2; 42573 opts.animIn.left = 0; 42574 opts.animIn.width = this.cycleW; 42575 opts.animOut.left = 0; 42576 }); 42577 opts.cssBefore.top = 0; 42578 opts.cssBefore.width = 0; 42579}; 42580// growY - grow vertically from centered 0 height 42581$.fn.cycle.transitions.growY = function($cont, $slides, opts) { 42582 opts.before.push(function(curr, next, opts) { 42583 $.fn.cycle.commonReset(curr,next,opts,true,false); 42584 opts.cssBefore.top = this.cycleH/2; 42585 opts.animIn.top = 0; 42586 opts.animIn.height = this.cycleH; 42587 opts.animOut.top = 0; 42588 }); 42589 opts.cssBefore.height = 0; 42590 opts.cssBefore.left = 0; 42591}; 42592 42593// curtainX - squeeze in both edges horizontally 42594$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) { 42595 opts.before.push(function(curr, next, opts) { 42596 $.fn.cycle.commonReset(curr,next,opts,false,true,true); 42597 opts.cssBefore.left = next.cycleW/2; 42598 opts.animIn.left = 0; 42599 opts.animIn.width = this.cycleW; 42600 opts.animOut.left = curr.cycleW/2; 42601 opts.animOut.width = 0; 42602 }); 42603 opts.cssBefore.top = 0; 42604 opts.cssBefore.width = 0; 42605}; 42606// curtainY - squeeze in both edges vertically 42607$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) { 42608 opts.before.push(function(curr, next, opts) { 42609 $.fn.cycle.commonReset(curr,next,opts,true,false,true); 42610 opts.cssBefore.top = next.cycleH/2; 42611 opts.animIn.top = 0; 42612 opts.animIn.height = next.cycleH; 42613 opts.animOut.top = curr.cycleH/2; 42614 opts.animOut.height = 0; 42615 }); 42616 opts.cssBefore.height = 0; 42617 opts.cssBefore.left = 0; 42618}; 42619 42620// cover - curr slide covered by next slide
42621$.fn.cycle.transitions.cover = function($cont, $slides, opts) { 42622 var d = opts.direction || 'left'; 42623 var w = $cont.css('overflow','hidden').width(); 42624 var h = $cont.height(); 42625 opts.before.push(function(curr, next, opts) { 42626 $.fn.cycle.commonReset(curr,next,opts); 42627 opts.cssAfter.display = ''; 42628 if (d == 'right') 42629 opts.cssBefore.left = -w; 42630 else if (d == 'up') 42631 opts.cssBefore.top = h; 42632 else if (d == 'down') 42633 opts.cssBefore.top = -h; 42634 else 42635 opts.cssBefore.left = w; 42636 }); 42637 opts.animIn.left = 0; 42638 opts.animIn.top = 0; 42639 opts.cssBefore.top = 0; 42640 opts.cssBefore.left = 0; 42641}; 42642 42643// uncover - curr slide moves off next slide 42644$.fn.cycle.transitions.uncover = function($cont, $slides, opts) { 42645 var d = opts.direction || 'left'; 42646 var w = $cont.css('overflow','hidden').width(); 42647 var h = $cont.height(); 42648 opts.before.push(function(curr, next, opts) { 42649 $.fn.cycle.commonReset(curr,next,opts,true,true,true); 42650 if (d == 'right') 42651 opts.animOut.left = w; 42652 else if (d == 'up') 42653 opts.animOut.top = -h; 42654 else if (d == 'down') 42655 opts.animOut.top = h; 42656 else 42657 opts.animOut.left = -w; 42658 }); 42659 opts.animIn.left = 0; 42660 opts.animIn.top = 0; 42661 opts.cssBefore.top = 0; 42662 opts.cssBefore.left = 0; 42663}; 42664 42665// toss - move top slide and fade away 42666$.fn.cycle.transitions.toss = function($cont, $slides, opts) { 42667 var w = $cont.css('overflow','visible').width(); 42668 var h = $cont.height(); 42669 opts.before.push(function(curr, next, opts) { 42670 $.fn.cycle.commonReset(curr,next,opts,true,true,true); 42671 // provide default toss settings if animOut not provided 42672 if (!opts.animOut.left && !opts.animOut.top) 42673 $.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 }); 42674 else 42675 opts.animOut.opacity = 0; 42676 }); 42677 opts.cssBefore.left = 0; 42678 opts.cssBefore.top = 0; 42679 opts.animIn.left = 0; 42680}; 42681 42682// wipe - clip animation 42683$.fn.cycle.transitions.wipe = function($cont, $slides, opts) { 42684 var w = $cont.css('overflow','hidden').width(); 42685 var h = $cont.height(); 42686 opts.cssBefore = opts.cssBefore || {}; 42687 var clip; 42688 if (opts.clip) { 42689 if (/l2r/.test(opts.clip)) 42690 clip = 'rect(0px 0px '+h+'px 0px)'; 42691 else if (/r2l/.test(opts.clip)) 42692 clip = 'rect(0px '+w+'px '+h+'px '+w+'px)'; 42693 else if (/t2b/.test(opts.clip)) 42694 clip = 'rect(0px '+w+'px 0px 0px)'; 42695 else if (/b2t/.test(opts.clip)) 42696 clip = 'rect('+h+'px '+w+'px '+h+'px 0px)'; 42697 else if (/zoom/.test(opts.clip)) { 42698 var top = parseInt(h/2,10); 42699 var left = parseInt(w/2,10); 42700 clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)'; 42701 } 42702 } 42703 42704 opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)'; 42705 42706 var d = opts.cssBefore.clip.match(/(\d+)/g); 42707 var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10); 42708 42709 opts.before.push(function(curr, next, opts) { 42710 if (curr == next) return; 42711 var $curr = $(curr), $next = $(next); 42712 $.fn.cycle.commonReset(curr,next,opts,true,true,false); 42713 opts.cssAfter.display = 'block'; 42714 42715 var step = 1, count = parseInt((opts.speedIn / 13),10) - 1; 42716 (function f() { 42717 var tt = t ? t - parseInt(step * (t/count),10) : 0; 42718 var ll = l ? l - parseInt(step * (l/count),10) : 0; 42719 var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h; 42720 var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w; 42721 $next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' }); 42722 (step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none'); 42723 })(); 42724 }); 42725 $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 }); 42726 opts.animIn = { left: 0 }; 42727 opts.animOut = { left: 0 }; 42728}; 42729 42730})(jQuery); 42731/* 42732 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 42733 * 42734 * Uses the built in easing capabilities added In jQuery 1.1 42735 * to offer multiple easing options 42736 * 42737 * TERMS OF USE - jQuery Easing 42738 * 42739 * Open source under the BSD License. 42740 * 42741 * Copyright © 2008 George McGinley Smith 42742 * All rights reserved. 42743 * 42744 * Redistribution and use in source and binary forms, with or without modification, 42745 * are permitted provided that the following conditions are met: 42746 * 42747 * Redistributions of source code must retain the above copyright notice, this list of 42748 * conditions and the following disclaimer. 42749 * Redistributions in binary form must reproduce the above copyright notice, this list 42750 * of conditions and the following disclaimer in the documentation and/or other materials 42751 * provided with the distribution. 42752 * 42753 * Neither the name of the author nor the names of contributors may be used to endorse 42754 * or promote products derived from this software without specific prior written permission. 42755 * 42756 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 42757 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 42758 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 42759 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,091 bytes, lines 42760-42905
42760 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 42761 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 42762 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42763 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 42764 * OF THE POSSIBILITY OF SUCH DAMAGE. 42765 * 42766*/ 42767 42768// t: current time, b: begInnIng value, c: change In value, d: duration 42769jQuery.easing['jswing'] = jQuery.easing['swing']; 42770 42771jQuery.extend( jQuery.easing, 42772{ 42773 def: 'easeOutQuad', 42774 swing: function (x, t, b, c, d) { 42775 //alert(jQuery.easing.default); 42776 return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 42777 }, 42778 easeInQuad: function (x, t, b, c, d) { 42779 return c*(t/=d)*t + b; 42780 }, 42781 easeOutQuad: function (x, t, b, c, d) { 42782 return -c *(t/=d)*(t-2) + b; 42783 }, 42784 easeInOutQuad: function (x, t, b, c, d) { 42785 if ((t/=d/2) < 1) return c/2*t*t + b; 42786 return -c/2 * ((--t)*(t-2) - 1) + b; 42787 }, 42788 easeInCubic: function (x, t, b, c, d) { 42789 return c*(t/=d)*t*t + b; 42790 }, 42791 easeOutCubic: function (x, t, b, c, d) { 42792 return c*((t=t/d-1)*t*t + 1) + b; 42793 }, 42794 easeInOutCubic: function (x, t, b, c, d) { 42795 if ((t/=d/2) < 1) return c/2*t*t*t + b; 42796 return c/2*((t-=2)*t*t + 2) + b; 42797 }, 42798 easeInQuart: function (x, t, b, c, d) { 42799 return c*(t/=d)*t*t*t + b; 42800 }, 42801 easeOutQuart: function (x, t, b, c, d) { 42802 return -c * ((t=t/d-1)*t*t*t - 1) + b; 42803 }, 42804 easeInOutQuart: function (x, t, b, c, d) { 42805 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 42806 return -c/2 * ((t-=2)*t*t*t - 2) + b; 42807 }, 42808 easeInQuint: function (x, t, b, c, d) { 42809 return c*(t/=d)*t*t*t*t + b; 42810 }, 42811 easeOutQuint: function (x, t, b, c, d) { 42812 return c*((t=t/d-1)*t*t*t*t + 1) + b; 42813 }, 42814 easeInOutQuint: function (x, t, b, c, d) { 42815 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 42816 return c/2*((t-=2)*t*t*t*t + 2) + b; 42817 }, 42818 easeInSine: function (x, t, b, c, d) { 42819 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 42820 }, 42821 easeOutSine: function (x, t, b, c, d) { 42822 return c * Math.sin(t/d * (Math.PI/2)) + b; 42823 }, 42824 easeInOutSine: function (x, t, b, c, d) { 42825 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 42826 }, 42827 easeInExpo: function (x, t, b, c, d) { 42828 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 42829 }, 42830 easeOutExpo: function (x, t, b, c, d) { 42831 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 42832 }, 42833 easeInOutExpo: function (x, t, b, c, d) { 42834 if (t==0) return b; 42835 if (t==d) return b+c; 42836 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 42837 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 42838 }, 42839 easeInCirc: function (x, t, b, c, d) { 42840 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 42841 }, 42842 easeOutCirc: function (x, t, b, c, d) { 42843 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 42844 }, 42845 easeInOutCirc: function (x, t, b, c, d) { 42846 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 42847 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 42848 }, 42849 easeInElastic: function (x, t, b, c, d) { 42850 var s=1.70158;var p=0;var a=c; 42851 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 42852 if (a < Math.abs(c)) { a=c; var s=p/4; } 42853 else var s = p/(2*Math.PI) * Math.asin (c/a); 42854 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 42855 }, 42856 easeOutElastic: function (x, t, b, c, d) { 42857 var s=1.70158;var p=0;var a=c; 42858 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 42859 if (a < Math.abs(c)) { a=c; var s=p/4; } 42860 else var s = p/(2*Math.PI) * Math.asin (c/a); 42861 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 42862 }, 42863 easeInOutElastic: function (x, t, b, c, d) { 42864 var s=1.70158;var p=0;var a=c; 42865 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 42866 if (a < Math.abs(c)) { a=c; var s=p/4; } 42867 else var s = p/(2*Math.PI) * Math.asin (c/a); 42868 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 42869 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 42870 }, 42871 easeInBack: function (x, t, b, c, d, s) { 42872 if (s == undefined) s = 1.70158; 42873 return c*(t/=d)*t*((s+1)*t - s) + b; 42874 }, 42875 easeOutBack: function (x, t, b, c, d, s) { 42876 if (s == undefined) s = 1.70158; 42877 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 42878 }, 42879 easeInOutBack: function (x, t, b, c, d, s) { 42880 if (s == undefined) s = 1.70158; 42881 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 42882 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 42883 }, 42884 easeInBounce: function (x, t, b, c, d) { 42885 return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 42886 }, 42887 easeOutBounce: function (x, t, b, c, d) { 42888 if ((t/=d) < (1/2.75)) { 42889 return c*(7.5625*t*t) + b; 42890 } else if (t < (2/2.75)) { 42891 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 42892 } else if (t < (2.5/2.75)) { 42893 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 42894 } else { 42895 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 42896 } 42897 }, 42898 easeInOutBounce: function (x, t, b, c, d) { 42899 if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 42900 return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 42901 } 42902}); 42903 42904/* 42905 *
42906 * TERMS OF USE - EASING EQUATIONS 42907 * 42908 * Open source under the BSD License. 42909 * 42910 * Copyright © 2001 Robert Penner 42911 * All rights reserved. 42912 * 42913 * Redistribution and use in source and binary forms, with or without modification, 42914 * are permitted provided that the following conditions are met: 42915 * 42916 * Redistributions of source code must retain the above copyright notice, this list of 42917 * conditions and the following disclaimer. 42918 * Redistributions in binary form must reproduce the above copyright notice, this list 42919 * of conditions and the following disclaimer in the documentation and/or other materials 42920 * provided with the distribution. 42921 * 42922 * Neither the name of the author nor the names of contributors may be used to endorse 42923 * or promote products derived from this software without specific prior written permission. 42924 * 42925 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 42926 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 42927 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 42928 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 42929 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 42930 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 42931 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42932 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 42933 * OF THE POSSIBILITY OF SUCH DAMAGE. 42934 * 42935 */ 42936; 42937(function(d){d.formatCurrency={};d.formatCurrency.regions=[];d.formatCurrency.regions[""]={symbol:"$",positiveFormat:"%s%n",negativeFormat:"(%s%n)",decimalSymbol
42937:".",digitGroupSymbol:",",groupDigits:true}; 42938d.fn.formatCurrency=function(e,f){if(arguments.length==1&&typeof e!=="string"){f=e;e=false}var g={name:"formatCurrency",colorize:false,region:"",global:true,roundToDecimalPlace:2,eventOnDecimalsEntered:false}; 42939g=d.extend(g,d.formatCurrency.regions[""]);f=d.extend(g,f);if(f.region.length>0){f=d.extend(f,b(f.region))}f.regex=a(f);return this.each(function(){$this=d(this); 42940var o="0";o=$this[$this.is("input, select, textarea")?"val":"html"]();if(o.search("\\(")>=0){o="-"+o}if(o===""||(o==="-"&&f.roundToDecimalPlace===-1)){return 42941}if(isNaN(o)){o=o.replace(f.regex,"");if(o===""||(o==="-"&&f.roundToDecimalPlace===-1)){return}if(f.decimalSymbol!="."){o=o.replace(f.decimalSymbol,".") 42942}if(isNaN(o)){o="0"}}var m=String(o).split(".");var r=(o==Math.abs(o));var l=(m.length>1);var k=(l?m[1].toString():"0");var j=k;o=Math.abs(m[0]); 42943o=isNaN(o)?0:o;if(f.roundToDecimalPlace>=0){k=parseFloat("1."+k);k=k.toFixed(f.roundToDecimalPlace);if(k.substring(0,1)=="2"){o=Number(o)+1}k=k.substring(2) 42944}o=String(o);if(f.groupDigits){for(var n=0;n<Math.floor((o.length-(1+n))/3);n++){o=o.substring(0,o.length-(4*n+3))+f.digitGroupSymbol+o.substring(o.length-(4*n+3)) 42945}}if((l&&f.roundToDecimalPlace==-1)||f.roundToDecimalPlace>0){o+=f.decimalSymbol+k}var q=r?f.positiveFormat:f.negativeFormat;var h=q.replace(/%s/g,f.symbol); 42946h=h.replace(/%n/g,o);var p=d([]);if(!e){p=$this}else{p=d(e)}p[p.is("input, select, textarea")?"val":"html"](h);if(l&&f.eventOnDecimalsEntered&&j.length>f.roundToDecimalPlace){p.trigger("decimalsEntered",j) 42947}if(f.colorize){p.css("color",r?"black":"red")}})};d.fn.toNumber=function(e){var f=d.extend({name:"toNumber",region:"",global:true},d.formatCurrency.regions[""]); 42948e=jQuery.extend(f,e);if(e.region.length>0){e=d.extend(e,b(e.region))}e.regex=a(e);return this.each(function(){var g=d(this).is("input, select, textarea")?"val":"html"; 42949d(this)[g](d(this)[g]().replace("(","(-").replace(e.regex,""))})};d.fn.asNumber=function(f){var g=d.extend({name:"asNumber",region:"",parse:true,parseType:"Float",global:true},d.formatCurrency.regions[""]); 42950f=jQuery.extend(g,f);if(f.region.length>0){f=d.extend(f,b(f.region))}f.regex=a(f);f.parseType=c(f.parseType);var h=d(this).is("input, select, textarea")?"val":"html"; 42951var e=d(this)[h]();e=e?e:"";e=e.replace("(","(-");e=e.replace(f.regex,"");if(!f.parse){return e}if(e.length==0){e="0"}if(f.decimalSymbol!="."){e=e.replace(f.decimalSymbol,".") 42952}return window["parse"+f.parseType](e)};function b(g){var f=d.formatCurrency.regions[g];if(f){return f}else{if(/(\w+)-(\w+)/g.test(g)){var e=g.replace(/(\w+)-(\w+)/g,"$1"); 42953return d.formatCurrency.regions[e]}}return null}function c(e){switch(e.toLowerCase()){case"int":return"Int";case"float":return"Float";default:throw"invalid parseType" 42954}}function a(e){if(e.symbol===""){return new RegExp("[^\\d"+e.decimalSymbol+"-]","g")}else{var f=e.symbol.replace("$","\\$").replace(".","\\."); 42955return new RegExp(f+"|[^\\d"+e.decimalSymbol+"-]","g")}}})(jQuery); 42956/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net) 42957 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 42958 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 42959 * 42960 * Version: 1.0.3 42961 * Requires jQuery 1.1.3+ 42962 * Docs: http://docs.jquery.com/Plugins/livequery 42963 */ 42964 42965 42966(function($) { 42967 42968$.extend($.fn, { 42969 livequery: function(type, fn, fn2) { 42970 var self = this, q; 42971 42972 // Handle different call patterns 42973 if ($.isFunction(type)) 42974 fn2 = fn, fn = type, type = undefined; 42975 42976 // See if Live Query already exists 42977 $.each( $.livequery.queries, function(i, query) { 42978 if ( self.selector == query.selector && self.context == query.context && 42979 type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) ) 42980 // Found the query, exit the each loop 42981 return (q = query) && false; 42982 }); 42983 42984 // Create new Live Query if it wasn't found 42985 q = q || new $.livequery(this.selector, this.context, type, fn, fn2); 42986 42987 // Make sure it is running 42988 q.stopped = false; 42989 42990 // Run it immediately for the first time 42991 q.run(); 42992 42993 // Contnue the chain 42994 return this; 42995 }, 42996 42997 expire: function(type, fn, fn2) { 42998 var self = this; 42999
43000 // Handle different call patterns 43001 if ($.isFunction(type)) 43002 fn2 = fn, fn = type, type = undefined; 43003 43004 // Find the Live Query based on arguments and stop it 43005 $.each( $.livequery.queries, function(i, query) { 43006 if ( self.selector == query.selector && self.context == query.context && 43007 (!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped ) 43008 $.livequery.stop(query.id); 43009 }); 43010 43011 // Continue the chain 43012 return this; 43013 } 43014}); 43015 43016$.livequery = function(selector, context, type, fn, fn2) { 43017 this.selector = selector; 43018 this.context = context || document; 43019 this.type = type; 43020 this.fn = fn; 43021 this.fn2 = fn2; 43022 this.elements = []; 43023 this.stopped = false; 43024 43025 // The id is the index of the Live Query in $.livequery.queries 43026 this.id = $.livequery.queries.push(this)-1; 43027 43028 // Mark the functions for matching later on 43029 fn.$lqguid = fn.$lqguid || $.livequery.guid++; 43030 if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++; 43031 43032 // Return the Live Query 43033 return this; 43034}; 43035 43036$.livequery.prototype = { 43037 stop: function() { 43038 var query = this; 43039
43040 if ( this.type ) 43041 // Unbind all bound events 43042 this.elements.unbind(this.type, this.fn); 43043 else if (this.fn2) 43044 // Call the second function for all matched elements 43045 this.elements.each(function(i, el) { 43046 query.fn2.apply(el); 43047 }); 43048 43049 // Clear out matched elements 43050 this.elements = []; 43051 43052 // Stop the Live Query from running until restarted 43053 this.stopped = true; 43054 }, 43055 43056 run: function() { 43057 // Short-circuit if stopped 43058 if ( this.stopped ) return; 43059 var query = this; 43060 43061 var oEls = this.elements, 43062 els = $(this.selector, this.context), 43063 nEls = els.not(oEls); 43064 43065 // Set elements to the latest set of matched elements 43066 this.elements = els; 43067 43068 if (this.type) { 43069 // Bind events to newly matched elements 43070 nEls.bind(this.type, this.fn); 43071 43072 // Unbind events to elements no longer matched 43073 if (oEls.length > 0) 43074 $.each(oEls, function(i, el) { 43075 if ( $.inArray(el, els) < 0 ) 43076 $.event.remove(el, query.type, query.fn); 43077 }); 43078 } 43079 else { 43080 // Call the first function for newly matched elements 43081 nEls.each(function() { 43082 query.fn.apply(this); 43083 }); 43084 43085 // Call the second function for elements no longer matched 43086 if ( this.fn2 && oEls.length > 0 ) 43087 $.each(oEls, function(i, el) { 43088 if ( $.inArray(el, els) < 0 ) 43089 query.fn2.apply(el); 43090 }); 43091 } 43092 } 43093}; 43094 43095$.extend($.livequery, { 43096 guid: 0, 43097 queries: [], 43098 queue: [], 43099 running: false, 43100 timeout: null, 43101 43102 checkQueue: function() { 43103 if ( $.livequery.running && $.livequery.queue.length ) { 43104 var length = $.livequery.queue.length; 43105 // Run each Live Query currently in the queue 43106 while ( length-- ) 43107 $.livequery.queries[ $.livequery.queue.shift() ].run(); 43108 } 43109 }, 43110 43111 pause: function() { 43112 // Don't run anymore Live Queries until restarted 43113 $.livequery.running = false; 43114 }, 43115 43116 play: function() { 43117 // Restart Live Queries 43118 $.livequery.running = true; 43119 // Request a run of the Live Queries 43120 $.livequery.run(); 43121 }, 43122 43123 registerPlugin: function() { 43124 $.each( arguments, function(i,n) { 43125 // Short-circuit if the method doesn't exist 43126 if (!$.fn[n]) return; 43127 43128 // Save a reference to the original method 43129 var old = $.fn[n]; 43130 43131 // Create a new method 43132 $.fn[n] = function() { 43133 // Call the original method 43134 var r = old.apply(this, arguments); 43135 43136 // Request a run of the Live Queries 43137 $.livequery.run(); 43138 43139 // Return the original methods result 43140 return r; 43141 } 43142 }); 43143 }, 43144 43145 run: function(id) { 43146 if (id != undefined) { 43147 // Put the particular Live Query in the queue if it doesn't already exist 43148 if ( $.inArray(id, $.livequery.queue) < 0 ) 43149 $.livequery.queue.push( id ); 43150 } 43151 else 43152 // Put each Live Query in the queue if it doesn't already exist 43153 $.each( $.livequery.queries, function(id) { 43154 if ( $.inArray(id, $.livequery.queue) < 0 ) 43155 $.livequery.queue.push( id ); 43156 }); 43157 43158 // Clear timeout if it already exists 43159 if ($.livequery.timeout) clearTimeout($.livequery.timeout); 43160 // Create a timeout to check the queue and actually run the Live Queries 43161 $.livequery.timeout = setTimeout($.livequery.checkQueue, 20); 43162 }, 43163 43164 stop: function(id) { 43165 if (id != undefined) 43166 // Stop are particular Live Query 43167 $.livequery.queries[ id ].stop(); 43168 else 43169 // Stop all Live Queries 43170 $.each( $.livequery.queries, function(id) { 43171 $.livequery.queries[ id ].stop(); 43172 }); 43173 } 43174}); 43175 43176// Register core DOM manipulation methods 43177$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove'); 43178 43179// Run Live Queries when the Document is ready 43180$(function() { $.livequery.play(); }); 43181 43182 43183// Save a reference to the original init method 43184var init = $.prototype.init; 43185 43186// Create a new init method that exposes two new properties: selector and context 43187$.prototype.init = function(a,c) { 43188 // Call the original init and save the result 43189 var r = init.apply(this, arguments); 43190 43191 // Copy over properties if they exist already 43192 if (a && a.selector) 43193 r.context = a.context, r.selector = a.selector; 43194 43195 // Set properties 43196 if ( typeof a == 'string' ) 43197 r.context = c || document, r.selector = a; 43198 43199 // Return the result 43200 return r; 43201}; 43202 43203// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091) 43204$.prototype.init.prototype = $.prototype; 43205 43206})(jQuery); 43207/** 43208 * jQuery.LocalScroll - Animated scrolling navigation, using anchors. 43209 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com 43210 * Dual licensed under MIT and GPL. 43211 * Date: 3/11/2009 43212 * @author Ariel Flesler 43213 * @version 1.2.7 43214 **/ 43215 43216;(function($){var l=location.href.replace(/#.*/,'');var g=$.localScroll=function(a){$('body').localScroll(a)};g.defaults={duration:1e3,axis:'y',event:'click',stop:true,target:window,reset:true};
43216g.hash=function(a){if(location.hash){a=$.extend({},g.defaults,a);a.hash=false;if(a.reset){var e=a.duration;delete a.duration;$(a.target).scrollTo(0,a);a.duration=e}i(0,location,a)}};$.fn.localScroll=function(b){b=$.extend({},g.defaults,b);return b.lazy?this.bind(b.event,function(a){var e=$([a.target,a.target.parentNode]).filter(d)[0];if(e)i(a,e,b)}):this.find('a,area').filter(d).bind(b.event,function(a){i(a,this,b)}).end().end();function d(){return!!this.href&&!!this.hash&&this.href.replace(this.hash,'')==l&&(!b.filter||$(this).is(b.filter))}};function i(a,e,b){var d=e.hash.slice(1),f=document.getElementById(d)||document.getElementsByName(d)[0];if(!f)return;if(a)a.preventDefault();var h=$(b.target);if(b.lock&&h.is(':animated')||b.onBefore&&b.onBefore.call(b,a,f,h)===false)return;if(b.stop)h.stop(true);if(b.hash){var j=f.id==d?'id':'name',k=$('<a> </a>').attr(j,d).css({position:'absolute',top:$(window).scrollTop(),left:$(window).scrollLeft()});f[j]='';$('body').prepend(k);location=e.hash;k.remove();f[j]=d}h.scrollTo(f,b).trigger('notify.serialScroll',[f])}})(jQuery); 43217/* 43218 Masked Input plugin for jQuery 43219 Copyright (c) 2007-2013 Josh Bush (digitalbush.com) 43220 Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) 43221 Version: 1.3.1 43222*/ 43223 43224(function($) { 43225 function getPasteEvent() { 43226 var el = document.createElement('input'), 43227 name = 'onpaste'; 43228 el.setAttribute(name, ''); 43229 return (typeof el[name] === 'function')?'paste':'input'; 43230} 43231 43232var pasteEventName = getPasteEvent() + ".mask", 43233 ua = navigator.userAgent, 43234 iPhone = /iphone/i.test(ua), 43235 android=/android/i.test(ua), 43236 caretTimeoutId; 43237 43238$.mask = { 43239 //Predefined character definitions 43240 definitions: { 43241 '9': "[0-9]", 43242 'a': "[A-Za-z]", 43243 '*': "[A-Za-z0-9]" 43244 }, 43245 dataName: "rawMaskFn", 43246 placeholder: '_' 43247}; 43248 43249$.fn.extend({ 43250 //Helper Function for Caret positioning 43251 caret: function(begin, end) { 43252 var range; 43253 43254 if (this.length === 0 || this.is(":hidden")) { 43255 return; 43256 } 43257 43258 if (typeof begin == 'number') { 43259 end = (typeof end === 'number') ? end : begin; 43260 return this.each(function() { 43261 if (this.setSelectionRange) { 43262 this.setSelectionRange(begin, end); 43263 } else if (this.createTextRange) { 43264 range = this.createTextRange(); 43265 range.collapse(true); 43266 range.moveEnd('character', end); 43267 range.moveStart('character', begin); 43268 range.select(); 43269 } 43270 }); 43271 } else { 43272 if (this[0].setSelectionRange) { 43273 begin = this[0].selectionStart; 43274 end = this[0].selectionEnd; 43275 } else if (document.selection && document.selection.createRange) { 43276 range = document.selection.createRange(); 43277 begin = 0 - range.duplicate().moveStart('character', -100000); 43278 end = begin + range.text.length; 43279 } 43280 return { begin: begin, end: end }; 43281 } 43282 }, 43283 unmask: function() { 43284 return this.trigger("unmask"); 43285 }, 43286 mask: function(mask, settings) { 43287 var input, 43288 defs, 43289 tests, 43290 partialPosition, 43291 firstNonMaskPos, 43292 len; 43293 43294 if (!mask && this.length > 0) { 43295 input = $(this[0]); 43296 return input.data($.mask.dataName)(); 43297 } 43298 settings = $.extend({ 43299 placeholder: $.mask.placeholder, // Load default placeholder 43300 completed: null 43301 }, settings); 43302 43303 43304 defs = $.mask.definitions; 43305 tests = []; 43306 partialPosition = len = mask.length; 43307 firstNonMaskPos = null; 43308 43309 $.each(mask.split(""), function(i, c) { 43310 if (c == '?') { 43311 len--; 43312 partialPosition = i; 43313 } else if (defs[c]) { 43314 tests.push(new RegExp(defs[c])); 43315 if (firstNonMaskPos === null) { 43316 firstNonMaskPos = tests.length - 1; 43317 } 43318 } else { 43319 tests.push(null); 43320 } 43321 }); 43322 43323 return this.trigger("unmask").each(function() { 43324 var input = $(this), 43325 buffer = $.map( 43326 mask.split(""), 43327 function(c, i) { 43328 if (c != '?') { 43329 return defs[c] ? settings.placeholder : c; 43330 } 43331 }), 43332 focusText = input.val(); 43333 43334 function seekNext(pos) { 43335 while (++pos < len && !tests[pos]); 43336 return pos; 43337 } 43338 43339 function seekPrev(pos) { 43340 while (--pos >= 0 && !tests[pos]); 43341 return pos; 43342 } 43343 43344 function shiftL(begin,end) { 43345 var i, 43346 j; 43347 43348 if (begin<0) { 43349 return; 43350 } 43351 43352 for (i = begin, j = seekNext(end); i < len; i++) { 43353 if (tests[i]) { 43354 if (j < len && tests[i].test(buffer[j])) { 43355 buffer[i] = buffer[j]; 43356 buffer[j] = settings.placeholder; 43357 } else { 43358 break; 43359 } 43360 43361 j = seekNext(j); 43362 } 43363 } 43364 writeBuffer(); 43365 input.caret(Math.max(firstNonMaskPos, begin)); 43366 } 43367 43368 function shiftR(pos) { 43369 var i, 43370 c, 43371 j, 43372 t; 43373 43374 for (i = pos, c = settings.placeholder; i < len; i++) { 43375 if (tests[i]) { 43376 j = seekNext(i); 43377 t = buffer[i]; 43378 buffer[i] = c; 43379 if (j < len && tests[j].test(t)) { 43380 c = t; 43381 } else { 43382 break; 43383 } 43384 } 43385 } 43386 } 43387 43388 function keydownEvent(e) { 43389 var k = e.which, 43390 pos, 43391 begin, 43392 end; 43393 43394 //backspace, delete, and escape get special treatment 43395 if (k === 8 || k === 46 || (iPhone && k === 127)) { 43396 pos = input.caret(); 43397 begin = pos.begin; 43398 end = pos.end; 43399 43400 if (end - begin === 0) { 43401 begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
43402 end=k===46?seekNext(end):end; 43403 } 43404 clearBuffer(begin, end); 43405 shiftL(begin, end - 1); 43406 43407 e.preventDefault(); 43408 } else if (k == 27) {//escape 43409 input.val(focusText); 43410 input.caret(0, checkVal()); 43411 e.preventDefault(); 43412 } 43413 } 43414 43415 function keypressEvent(e) { 43416 var k = e.which, 43417 pos = input.caret(), 43418 p, 43419 c, 43420 next; 43421 43422 if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore 43423 return; 43424 } else if (k) { 43425 if (pos.end - pos.begin !== 0){ 43426 clearBuffer(pos.begin, pos.end); 43427 shiftL(pos.begin, pos.end-1); 43428 } 43429 43430 p = seekNext(pos.begin - 1); 43431 if (p < len) { 43432 c = String.fromCharCode(k); 43433 if (tests[p].test(c)) { 43434 shiftR(p); 43435 43436 buffer[p] = c; 43437 writeBuffer(); 43438 next = seekNext(p); 43439 43440 if(android){ 43441 setTimeout($.proxy($.fn.caret,input,next),0); 43442 }else{ 43443 input.caret(next); 43444 } 43445 43446 if (settings.completed && next >= len) { 43447 settings.completed.call(input); 43448 } 43449 } 43450 } 43451 e.preventDefault(); 43452 } 43453 } 43454 43455 function clearBuffer(start, end) { 43456 var i; 43457 for (i = start; i < end && i < len; i++) { 43458 if (tests[i]) { 43459 buffer[i] = settings.placeholder; 43460 } 43461 } 43462 } 43463 43464 function writeBuffer() { input.val(buffer.join('')); } 43465 43466 function checkVal(allow) { 43467 //try to place characters where they belong 43468 var test = input.val(), 43469 lastMatch = -1, 43470 i, 43471 c; 43472 43473 for (i = 0, pos = 0; i < len; i++) { 43474 if (tests[i]) { 43475 buffer[i] = settings.placeholder; 43476 while (pos++ < test.length) { 43477 c = test.charAt(pos - 1); 43478 if (tests[i].test(c)) { 43479 buffer[i] = c; 43480 lastMatch = i; 43481 break; 43482 } 43483 } 43484 if (pos > test.length) { 43485 break; 43486 } 43487 } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) { 43488 pos++; 43489 lastMatch = i; 43490 } 43491 } 43492 if (allow) { 43493 writeBuffer(); 43494 } else if (lastMatch + 1 < partialPosition) { 43495 input.val(""); 43496 clearBuffer(0, len); 43497 } else { 43498 writeBuffer(); 43499 input.val(input.val().substring(0, lastMatch + 1)); 43500 } 43501 return (partialPosition ? i : firstNonMaskPos); 43502 } 43503 43504 input.data($.mask.dataName,function(){ 43505 return $.map(buffer, function(c, i) { 43506 return tests[i]&&c!=settings.placeholder ? c : null; 43507 }).join(''); 43508 }); 43509 43510 if (!input.attr("readonly")) 43511 input 43512 .one("unmask", function() { 43513 input 43514 .unbind(".mask") 43515 .removeData($.mask.dataName); 43516 }) 43517 .bind("focus.mask", function() { 43518 clearTimeout(caretTimeoutId); 43519 var pos, 43520 moveCaret; 43521 43522 focusText = input.val(); 43523 pos = checkVal(); 43524 43525 caretTimeoutId = setTimeout(function(){ 43526 writeBuffer(); 43527 if (pos == mask.length) { 43528 input.caret(0, pos); 43529 } else { 43530 input.caret(pos); 43531 } 43532 }, 10); 43533 }) 43534 .bind("blur.mask", function() { 43535 checkVal(); 43536 if (input.val() != focusText) 43537 input.change(); 43538 }) 43539 .bind("keydown.mask", keydownEvent) 43540 .bind("keypress.mask", keypressEvent) 43541 .bind(pasteEventName, function() { 43542 setTimeout(function() { 43543 var pos=checkVal(true); 43544 input.caret(pos); 43545 if (settings.completed && pos == input.val().length) 43546 settings.completed.call(input); 43547 }, 0); 43548 }); 43549 checkVal(); //Perform initial check for existing values 43550 }); 43551 } 43552}); 43553 43554 43555})(jQuery); 43556/** 43557 * Copyright (c) 2007-2012 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com 43558 * Dual licensed under MIT and GPL. 43559 * @author Ariel Flesler 43560 * @version 1.4.3.1 43561 */ 43562 43563;(function($){var h=$.scrollTo=function(a,b,c){$(window).scrollTo(a,b,c)};h.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1,limit:true};h.window=function(a){return $(window)._scrollable()};$.fn._scrollable=function(){return this.map(function(){var a=this,isWin=!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!isWin)return a;var b=(a.contentWindow||a).document||a.ownerDocument||a;return/webkit/i.test(navigator.userAgent)||b.compatMode=='BackCompat'?b.body:b.documentElement})};$.fn.scrollTo=function(e,f,g){if(typeof f=='object'){g=f;f=0}if(typeof g=='function')g={onAfter:g};if(e=='max')e=9e9;g=$.extend({},h.defaults,g);f=f||g.duration;g.queue=g.queue&&g.axis.length>1;if(g.queue)f/=2;g.offset=both(g.offset);g.over=both(g.over);return this._scrollable().each(function(){if(e==null)return;var d=this,$elem=$(d),targ=e,toff,attr={},win=$elem.is('html,body');switch(typeof targ){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=$(targ,this);if(!targ.length)return;case'object':if(targ.is||targ.style)toff=(targ=$(targ)).offset()}$.each(g.axis.split(''),function(i,a){var b=a=='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,old=d[key],max=h.max(d,a);if(toff){attr[key]=toff[pos]+(win?0:old-$elem.offset()[pos]);if(g.margin){attr[key]-=parseInt(targ.css('margin'+b))||0;attr[key]-=parseInt(targ.css('border'+b+'Width'))||0}attr[key]+=g.offset[pos]||0;if(g.over[pos])attr[key]+=targ[a=='x'?'width':'height']()*g.over[pos]}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)=='%'?parseFloat(c)/100*max:c}if(g.limit&&/^\d+$/.test(attr[key]))attr[key]=attr[key]<=0?0:Math.min(attr[key],max);if(!i&&g.queue){if(old!=attr[key])animate(g.onAfterFirst);delete attr[key]}});animate(g.onAfter);function animate(a){$elem.animate(attr,f,g.easing,a&&function(){a.call(this,e,g)})}}).end()};h.max=function(a,b){var c=b=='x'?'Width':'Height',scroll='scroll'+c;if(!$(a).is('html,body'))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,html=a.ownerDocument.documentElement,body=a.ownerDocument.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery); 43564/*! 43565 * jQuery Transit - CSS3 transitions and transformations 43566 * (c) 2011-2012 Rico Sta. Cruz <[email protected]> 43567 * MIT Licensed. 43568 * 43569 * http://ricostacruz.com/jquery.transit 43570 * http://github.com/rstacruz/jquery.transit 43571 */ 43572 43573(function(k){k.transit={version:"0.9.9",propertyMap:{marginLeft:"margin",marginRight:"margin",marginBottom:"margin",marginTop:"margin",paddingLeft:"padding",paddingRight:"padding",paddingBottom:"padding",paddingTop:"padding"},enabled:true,useTransitionEnd:false};var d=document.createElement("div");var q={};function b(v){if(v in d.style){return v}var u=["Moz","Webkit","O","ms"];var r=v.charAt(0).toUpperCase()+v.substr(1);if(v in d.style){return v}for(var t=0;t<u.length;++t){var s=u[t]+r;if(s in d.style){return s}}}function e(){d.style[q.transform]="";d.style[q.transform]="rotateY(90deg)";return d.style[q.transform]!==""}var a=navigator.userAgent.toLowerCase().indexOf("chrome")>-1;q.transition=b("transition");q.transitionDelay=b("transitionDelay");q.transform=b("transform");q.transformOrigin=b("transformOrigin");q.transform3d=e();var i={transition:"transitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",WebkitTransition:"webkitTransitionEnd",msTransition:"MSTransitionEnd"};var f=q.transitionEnd=i[q.transition]||null;for(var p in q){if(q.hasOwnProperty(p)&&typeof k.support[p]==="undefined"){k.support[p]=q[p]}}d=null;k.cssEase={_default:"ease","in":"ease-in",out:"ease-out","in-out":"ease-in-out",snap:"cubic-bezier(0,1,.5,1)",easeOutCubic:"cubic-bezier(.215,.61,.355,1)",easeInOutCubic:"cubic-bezier(.645,.045,.355,1)",easeInCirc:"cubic-bezier(.6,.04,.98,.335)",easeOutCirc:"cubic-bezier(.075,.82,.165,1)",easeInOutCirc:"cubic-bezier(.785,.135,.15,.86)",easeInExpo:"cubic-bezier(.95,.05,.795,.035)",easeOutExpo:"cubic-bezier(.19,1,.22,1)",easeInOutExpo:"cubic-bezier(1,0,0,1)",easeInQuad:"cubic-bezier(.55,.085,.68,.53)",easeOutQuad:"cubic-bezier(.25,.46,.45,.94)",easeInOutQuad:"cubic-bezier(.455,.03,.515,.955)",easeInQuart:"cubic-bezier(.895,.03,.685,.22)",easeOutQuart:"cubic-bezier(.165,.84,.44,1)",easeInOutQuart:"cubic-bezier(.77,0,.175,1
43573)",easeInQuint:"cubic-bezier(.755,.05,.855,.06)",easeOutQuint:"cubic-bezier(.23,1,.32,1)",easeInOutQuint:"cubic-bezier(.86,0,.07,1)",easeInSine:"cubic-bezier(.47,0,.745,.715)",easeOutSine:"cubic-bezier(.39,.575,.565,1)",easeInOutSine:"cubic-bezier(.445,.05,.55,.95)",easeInBack:"cubic-bezier(.6,-.28,.735,.045)",easeOutBack:"cubic-bezier(.175, .885,.32,1.275)",easeInOutBack:"cubic-bezier(.68,-.55,.265,1.55)"};k.cssHooks["transit:transform"]={get:function(r){return k(r).data("transform")||new j()},set:function(s,r){var t=r;if(!(t instanceof j)){t=new j(t)}if(q.transform==="WebkitTransform"&&!a){s.style[q.transform]=t.toString(true)}else{s.style[q.transform]=t.toString()}k(s).data("transform",t)}};k.cssHooks.transform={set:k.cssHooks["transit:transform"].set};if(k.fn.jquery<"1.8"){k.cssHooks.transformOrigin={get:function(r){return r.style[q.transformOrigin]},set:function(r,s){r.style[q.transformOrigin]=s}};k.cssHooks.transition={get:function(r){return r.style[q.transition]},set:function(r,s){r.style[q.transition]=s}}}n("scale");n("translate");n("rotate");n("rotateX");n("rotateY");n("rotate3d");n("perspective");n("skewX");n("skewY");n("x",true);n("y",true);function j(r){if(typeof r==="string"){this.parse(r)}return this}j.prototype={setFromString:function(t,s){var r=(typeof s==="string")?s.split(","):(s.constructor===Array)?s:[s];r.unshift(t);j.prototype.set.apply(this,r)},set:function(s){var r=Array.prototype.slice.apply(arguments,[1]);if(this.setter[s]){this.setter[s].apply(this,r)}else{this[s]=r.join(",")}},get:function(r){if(this.getter[r]){return this.getter[r].apply(this)}else{return this[r]||0}},setter:{rotate:function(r){this.rotate=o(r,"deg")},rotateX:function(r){this.rotateX=o(r,"deg")},rotateY:function(r){this.rotateY=o(r,"deg")},scale:function(r,s){if(s===undefined){s=r}this.scale=r+","+s},skewX:function(r){this.skewX=o(r,"deg")},skewY:function(r){this.skewY=o(r,"deg")},perspective:function(r){this.perspective=o(r,"px")},x:function(r){this.set("translate",r,null)},y:function(r){this.set("translate",null,r)},translate:function(r,s){if(this._translateX===undefined){this._translateX=0}if(this._translateY===undefined){this._translateY=0}if(r!==null&&r!==undefined){this._translateX=o(r,"px")}if(s!==null&&s!==undefined){this._translateY=o(s,"px")}
43573this.translate=this._translateX+","+this._translateY}},getter:{x:function(){return this._translateX||0},y:function(){return this._translateY||0},scale:function(){var r=(this.scale||"1,1").split(",");if(r[0]){r[0]=parseFloat(r[0])}if(r[1]){r[1]=parseFloat(r[1])}return(r[0]===r[1])?r[0]:r},rotate3d:function(){var t=(this.rotate3d||"0,0,0,0deg").split(",");for(var r=0;r<=3;++r){if(t[r]){t[r]=parseFloat(t[r])}}if(t[3]){t[3]=o(t[3],"deg")}return t}},parse:function(s){var r=this;s.replace(/([a-zA-Z0-9]+)\((.*?)\)/g,function(t,v,u){r.setFromString(v,u)})},toString:function(t){var s=[];for(var r in this){if(this.hasOwnProperty(r)){if((!q.transform3d)&&((r==="rotateX")||(r==="rotateY")||(r==="perspective")||(r==="transformOrigin"))){continue}if(r[0]!=="_"){if(t&&(r==="scale")){s.push(r+"3d("+this[r]+",1)")}else{if(t&&(r==="translate")){s.push(r+"3d("+this[r]+",0)")}else{s.push(r+"("+this[r]+")")}}}}}return s.join(" ")}};function m(s,r,t){if(r===true){s.queue(t)}else{if(r){s.queue(r,t)}else{t()}}}function h(s){var r=[];k.each(s,function(t){t=k.camelCase(t);t=k.transit.propertyMap[t]||k.cssProps[t]||t;t=c(t);if(k.inArray(t,r)===-1){r.push(t)}});return r}function g(s,v,x,r){var t=h(s);if(k.cssEase[x]){x=k.cssEase[x]}var w=""+l(v)+" "+x;if(parseInt(r,10)>0){w+=" "+l(r)}var u=[];k.each(t,function(z,y){u.push(y+" "+w)});return u.join(", ")}k.fn.transition=k.fn.transit=function(z,s,y,C){var D=this;var u=0;var w=true;if(typeof s==="function"){C=s;s=undefined}if(typeof y==="function"){C=y;y=undefined}if(typeof z.easing!=="undefined"){y=z.easing;delete z.easing}if(typeof z.duration!=="undefined"){s=z.duration;delete z.duration}if(typeof z.complete!=="undefined"){C=z.complete;delete z.complete}if(typeof z.queue!=="undefined"){w=z.queue;delete z.queue}if(typeof z.delay!=="undefined"){u=z.delay;delete z.delay}if(typeof s==="undefined"){s=k.fx.speeds._default}if(typeof y==="undefined"){y=k.cssEase._default}s=l(s);var E=g(z,s,y,u);var B=k.transit.enabled&&q.transition;var t=B?(parseInt(s,10)+parseInt(u,10)):0;if(t===0){var A=function(F){D.css(z);if(C){C.apply(D)}if(F){F()}};m(D,w,A);return D}var x={};var r=function(H){var G=false;var F=function(){if(G){D.unbind(f,F)}if(t>0){D.each(function(){this.style[q.transition]=(x[this]||null)})}if(typeof C==="function"){C.apply(D)}if(typeof H==="function"){H()}};if((t>0)&&(f)&&(k.transit.useTransitionEnd)){G=true;D.bind(f,F)}else{window.setTimeout(F,t)}D.each(function(){if(t>0){this.style[q.transition]=E}k(this).css(z)})};var v=function(F){this.offsetWidth;r(F)};m(D,w,v);return this};function n(s,r){if(!r){k.cssNumber[s]=true}k.transit.propertyMap[s]=q.transform;k.cssHooks[s]={get:function(v){var u=k(v).css("transit:transform");return u.get(s)},set:function(v,w){var u=k(v).css("transit:transform");u.setFromString(s,w);k(v).css({"transit:transform":u})}}}function c(r){return r.replace(/([A-Z])/g,function(s){return"-"+s.toLowerCase()})}function o(s,r){if((typeof s==="string")&&(!s.match(/^[\-0-9\.]+$/))){return s}else{return""+s+r}}function l(s){var r=s;if(k.fx.speeds[r]){r=k.fx.speeds[r]}return o(r,"ms")}k.transit.getTransitionValue=g})(jQuery); 43574// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator 43575// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 43576// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) 43577jQuery.validator.addMethod("creditcardtypes", function(value, element, param) { 43578 if (/[^0-9\-]+/.test(value)) { 43579 return false; 43580 } 43581 43582 value = value.replace(/\D/g, ""); 43583 43584 var validTypes = 0x0000; 43585 43586 if (param.mastercard) { 43587 validTypes |= 0x0001; 43588 } 43589 if (param.visa) { 43590 validTypes |= 0x0002; 43591 } 43592 if (param.amex) { 43593 validTypes |= 0x0004; 43594 } 43595 if (param.dinersclub) { 43596 validTypes |= 0x0008; 43597 } 43598 if (param.enroute) { 43599 validTypes |= 0x0010; 43600 } 43601 if (param.discover) { 43602 validTypes |= 0x0020; 43603 } 43604 if (param.jcb) { 43605 validTypes |= 0x0040; 43606 } 43607 if (param.unknown) { 43608 validTypes |= 0x0080; 43609 } 43610 if (param.all) { 43611 validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; 43612 } 43613 if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard 43614 return value.length === 16; 43615 } 43616 if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa 43617 return value.length === 16; 43618 } 43619 if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex 43620 return value.length === 15; 43621 } 43622 if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub 43623 return value.length === 14; 43624 } 43625 if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute 43626 return value.length === 15; 43627 } 43628 if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover 43629 return value.length === 16; 43630 } 43631 if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb 43632 return value.length === 16; 43633 } 43634 if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb 43635 return value.length === 15; 43636 } 43637 if (validTypes & 0x0080) { //unknown 43638 return true; 43639 } 43640 return false;
43641}, "Please enter a valid credit card number."); 43642 43643jQuery.validator.addMethod("creditcardexpirymonth", function(value, element, param) { 43644 var today = new Date(); 43645 var month = today.getMonth() + 1; 43646 var year = today.getFullYear() - 2000; 43647 43648 var input_month = parseInt( $("#cc_expiry_month").val(), 10); 43649 var input_year = parseInt( $("#cc_expiry_year").val(), 10); 43650 43651 return (input_month >= month && input_year >= year) || input_year > year; 43652 43653}, "Please enter a valid expiry month."); 43654 43655jQuery.validator.addMethod("creditcardexpiryyear", function(value, element, param) { 43656 var today = new Date(); 43657 var year = today.getFullYear() - 2000; 43658 43659 var input_year = parseInt( $("#cc_expiry_year").val(), 10); 43660 43661 // trigger evaluation of the month field so we can check if 43662 // combination of month and year is valid. this has to run assync so it doesn't 43663 // crashes the validator ability to check all fields 43664 setTimeout(function(){ $(".complete_checkout").validate().element('#cc_expiry_month'); }, 1000); 43665 43666 return input_year >= year; 43667 43668}, "Please enter a valid expiry year."); 43669/* 43670 The MIT License (MIT) 43671 Copyright (c) 2014 Dirk Groenen 43672 Permission is hereby granted, free of charge, to any person obtaining a copy of 43673 this software and associated documentation files (the "Software"), to deal in 43674 the Software without restriction, including without limitation the rights to 43675 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 43676 the Software, and to permit persons to whom the Software is furnished to do so, 43677 subject to the following conditions: 43678 The above copyright notice and this permission notice shall be included in all 43679 copies or substantial portions of the Software. 43680*/ 43681 43682 43683(function($){ 43684 $.fn.viewportChecker = function(useroptions){ 43685 // Define options and extend with user 43686 var options = { 43687 classToAdd: 'visible', 43688 classToRemove : 'invisible', 43689 classToAddForFullView : 'full-visible', 43690 removeClassAfterAnimation: false, 43691 offset: 100, 43692 repeat: false, 43693 invertBottomOffset: true, 43694 callbackFunction: function(elem, action){}, 43695 scrollHorizontal: false, 43696 scrollBox: window 43697 }; 43698 $.extend(options, useroptions); 43699 43700 // Cache the given element and height of the browser 43701 var $elem = this, 43702 boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()}; 43703 43704 /* 43705 * Main method that checks the elements and adds or removes the class(es) 43706 */ 43707 this.checkElements = function(){ 43708 var viewportStart, viewportEnd; 43709 43710 // Set some vars to check with 43711 if (!options.scrollHorizontal){ 43712 viewportStart = Math.max( 43713 $('html').scrollTop(), 43714 $('body').scrollTop(), 43715 $(window).scrollTop() 43716 ); 43717 viewportEnd = (viewportStart + boxSize.height); 43718 } 43719 else{ 43720 viewportStart = Math.max( 43721 $('html').scrollLeft(), 43722 $('body').scrollLeft(), 43723 $(window).scrollLeft() 43724 ); 43725 viewportEnd = (viewportStart + boxSize.width); 43726 } 43727 43728 // Loop through all given dom elements 43729 $elem.each(function(){ 43730 var $obj = $(this), 43731 objOptions = {}, 43732 attrOptions = {}; 43733 43734 // Get any individual attribution data 43735 if ($obj.data('vp-add-class')) 43736 attrOptions.classToAdd = $obj.data('vp-add-class'); 43737 if ($obj.data('vp-remove-class')) 43738 attrOptions.classToRemove = $obj.data('vp-remove-class'); 43739 if ($obj.data('vp-add-class-full-view')) 43740 attrOptions.classToAddForFullView = $obj.data('vp-add-class-full-view'); 43741 if ($obj.data('vp-keep-add-class')) 43742 attrOptions.removeClassAfterAnimation = $obj.data('vp-remove-after-animation'); 43743 if ($obj.data('vp-offset')) 43744 attrOptions.offset = $obj.data('vp-offset'); 43745 if ($obj.data('vp-repeat')) 43746 attrOptions.repeat = $obj.data('vp-repeat'); 43747 if ($obj.data('vp-scrollHorizontal')) 43748 attrOptions.scrollHorizontal = $obj.data('vp-scrollHorizontal'); 43749 if ($obj.data('vp-invertBottomOffset')) 43750 attrOptions.scrollHorizontal = $obj.data('vp-invertBottomOffset'); 43751 43752 // Extend objOptions with data attributes and default options 43753 $.extend(objOptions, options); 43754 $.extend(objOptions, attrOptions); 43755 43756 // If class already exists; quit 43757 if ($obj.data('vp-animated') && !objOptions.repeat){ 43758 return; 43759 } 43760 43761 // Check if the offset is percentage based 43762 if (String(objOptions.offset).indexOf("%") > 0) 43763 objOptions.offset = (parseInt(objOptions.offset) / 100) * boxSize.height; 43764 43765 // Get the raw start and end positions 43766 var rawStart = (!objOptions.scrollHorizontal) ? $obj.offset().top : $obj.offset().left, 43767 rawEnd = (!objOptions.scrollHorizontal) ? rawStart + $obj.height() : rawStart + $obj.width(); 43768 43769 // Add the defined offset 43770 var elemStart = Math.round( rawStart ) + objOptions.offset, 43771 elemEnd = (!objOptions.scrollHorizontal) ? elemStart + $obj.height() : elemStart + $obj.width(); 43772 43773 if (objOptions.invertBottomOffset) 43774 elemEnd -= (objOptions.offset * 2); 43775 43776 // Add class if in viewport 43777 if ((elemStart < viewportEnd) && (elemEnd > viewportStart)){ 43778 43779 // Remove class 43780 $obj.removeClass(objOptions.classToRemove); 43781 $obj.addClass(objOptions.classToAdd); 43782 43783 // Do the callback function. Callback wil send the jQuery object as parameter 43784 objOptions.callbackFunction($obj, "add"); 43785 43786 // Check if full element is in view 43787 if (rawEnd <= viewportEnd && rawStart >= viewportStart) 43788 $obj.addClass(objOptions.classToAddForFullView); 43789 else 43790 $obj.removeClass(objOptions.classToAddForFullView); 43791 43792 // Set element as already animated 43793 $obj.data('vp-animated', true); 43794 43795 if (objOptions.removeClassAfterAnimation) { 43796 $obj.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){ 43797 $obj.removeClass(objOptions.classToAdd); 43798 }); 43799 } 43800 43801 // Remove class if not in viewport and repeat is true 43802 } else if ($obj.hasClass(objOptions.classToAdd) && (objOptions.repeat)){ 43803 $obj.removeClass(objOptions.classToAdd + " " + objOptions.classToAddForFullView); 43804 43805 // Do the callback function. 43806 objOptions.callbackFunction($obj, "remove"); 43807 43808 // Remove already-animated-flag 43809 $obj.data('vp-animated', false); 43810 } 43811 }); 43812 43813 }; 43814 43815 /** 43816 * Binding the correct event listener is still a tricky thing. 43817 * People have expierenced sloppy scrolling when both scroll and touch 43818 * events are added, but to make sure devices with both scroll and touch 43819 * are handles too we always have to add the window.scroll event 43820 *
43821 * @see https://github.com/dirkgroenen/jQuery-viewport-checker/issues/25 43822 * @see https://github.com/dirkgroenen/jQuery-viewport-checker/issues/27 43823 */ 43824 43825 // Select the correct events 43826 if( 'ontouchstart' in window || 'onmsgesturechange' in window ){ 43827 // Device with touchscreen 43828 $(document).bind("touchmove MSPointerMove pointermove", this.checkElements); 43829 } 43830 43831 // Always load on window load 43832 $(options.scrollBox).bind("load scroll", this.checkElements); 43833 43834 // On resize change the height var 43835 $(window).resize(function(e){ 43836 boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()}; 43837 $elem.checkElements(); 43838 }); 43839 43840 // trigger inital check if elements already visible 43841 this.checkElements(); 43842 43843 // Default jquery plugin behaviour 43844 return this; 43845 }; 43846})(jQuery); 43847/* 43848 json2.js 43849 2011-10-19 43850 43851 Public Domain. 43852 43853 NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 43854 43855 See http://www.JSON.org/js.html 43856 43857 43858 This code should be minified before deployment. 43859 See http://javascript.crockford.com/jsmin.html 43860 43861 USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO 43862 NOT CONTROL. 43863 43864 43865 This file creates a global JSON object containing two methods: stringify 43866 and parse. 43867 43868 JSON.stringify(value, replacer, space) 43869 value any JavaScript value, usually an object or array. 43870 43871 replacer an optional parameter that determines how object 43872 values are stringified for objects. It can be a 43873 function or an array of strings. 43874 43875 space an optional parameter that specifies the indentation 43876 of nested structures. If it is omitted, the text will 43877 be packed without extra whitespace. If it is a number, 43878 it will specify the number of spaces to indent at each 43879 level. If it is a string (such as '\t' or ' '), 43880 it contains the characters used to indent at each level. 43881 43882 This method produces a JSON text from a JavaScript value. 43883 43884 When an object value is found, if the object contains a toJSON 43885 method, its toJSON method will be called and the result will be 43886 stringified. A toJSON method does not serialize: it returns the 43887 value represented by the name/value pair that should be serialized, 43888 or undefined if nothing should be serialized. The toJSON method 43889 will be passed the key associated with the value, and this will be 43890 bound to the value 43891 43892 For example, this would serialize Dates as ISO strings. 43893 43894 Date.prototype.toJSON = function (key) { 43895 function f(n) { 43896 // Format integers to have at least two digits. 43897 return n < 10 ? '0' + n : n; 43898 } 43899 43900 return this.getUTCFullYear() + '-' + 43901 f(this.getUTCMonth() + 1) + '-' + 43902 f(this.getUTCDate()) + 'T' + 43903 f(this.getUTCHours()) + ':' + 43904 f(this.getUTCMinutes()) + ':' + 43905 f(this.getUTCSeconds()) + 'Z'; 43906 }; 43907 43908 You can provide an optional replacer method. It will be passed the 43909 key and value of each member, with this bound to the containing 43910 object. The value that is returned from your method will be 43911 serialized. If your method returns undefined, then the member will 43912 be excluded from the serialization. 43913 43914 If the replacer parameter is an array of strings, then it will be 43915 used to select the members to be serialized. It filters the results 43916 such that only members with keys listed in the replacer array are 43917 stringified. 43918 43919 Values that do not have JSON representations, such as undefined or 43920 functions, will not be serialized. Such values in objects will be 43921 dropped;
43921 in arrays they will be replaced with null. You can use 43922 a replacer function to replace those with JSON values. 43923 JSON.stringify(undefined) returns undefined. 43924 43925 The optional space parameter produces a stringification of the 43926 value that is filled with line breaks and indentation to make it 43927 easier to read. 43928 43929 If the space parameter is a non-empty string, then that string will 43930 be used for indentation. If the space parameter is a number, then 43931 the indentation will be that many spaces. 43932 43933 Example: 43934 43935 text = JSON.stringify(['e', {pluribus: 'unum'}]); 43936 // text is '["e",{"pluribus":"unum"}]' 43937 43938 43939 text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); 43940 // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' 43941 43942 text = JSON.stringify([new Date()], function (key, value) { 43943 return this[key] instanceof Date ? 43944 'Date(' + this[key] + ')' : value; 43945 }); 43946 // text is '["Date(---current time---)"]' 43947 43948 43949 JSON.parse(text, reviver) 43950 This method parses a JSON text to produce an object or array. 43951 It can throw a SyntaxError exception. 43952 43953 The optional reviver parameter is a function that can filter and 43954 transform the results. It receives each of the keys and values, 43955 and its return value is used instead of the original value. 43956 If it returns what it received, then the structure is not modified. 43957 If it returns undefined then the member is deleted. 43958 43959 Example: 43960 43961 // Parse the text. Values that look like ISO date strings will 43962 // be converted to Date objects. 43963 43964 myData = JSON.parse(text, function (key, value) { 43965 var a; 43966 if (typeof value === 'string') { 43967 a = 43968/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 43969 if (a) { 43970 return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], 43971 +a[5], +a[6])); 43972 } 43973 } 43974 return value; 43975 }); 43976 43977 myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { 43978 var d; 43979 if (typeof value === 'string' && 43980 value.slice(0, 5) === 'Date(' && 43981 value.slice(-1) === ')') { 43982 d = new Date(value.slice(5, -1)); 43983 if (d) { 43984 return d; 43985 } 43986 } 43987 return value; 43988 }); 43989 43990 43991 This is a reference implementation. You are free to copy, modify, or 43992 redistribute. 43993*/ 43994 43995/*jslint evil: true, regexp: true */ 43996 43997/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, 43998 call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, 43999 getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, 44000 lastIndex, length, parse, prototype, push, replace, slice, stringify, 44001 test, toJSON, toString, valueOf 44002*/ 44003 44004 44005// Create a JSON object only if one does not already exist. We create the 44006// methods in a closure to avoid creating global variables. 44007 44008var JSON; 44009if (!JSON) { 44010 JSON = {}; 44011} 44012 44013(function () { 44014 'use strict'; 44015 44016 function f(n) { 44017 // Format integers to have at least two digits. 44018 return n < 10 ? '0' + n : n; 44019 } 44020 44021 if (typeof Date.prototype.toJSON !== 'function') { 44022 44023 Date.prototype.toJSON = function (key) { 44024 44025 return isFinite(this.valueOf()) 44026 ? this.getUTCFullYear() + '-' + 44027 f(this.getUTCMonth() + 1) + '-' + 44028 f(this.getUTCDate()) + 'T' + 44029 f(this.getUTCHours()) + ':' + 44030 f(this.getUTCMinutes()) + ':' + 44031 f(this.getUTCSeconds()) + 'Z' 44032 : null; 44033 }; 44034 44035 String.prototype.toJSON = 44036 Number.prototype.toJSON = 44037 Boolean.prototype.toJSON = function (key
vendor: 10,100 bytes, lines 44037-44333
44037) { 44038 return this.valueOf(); 44039 }; 44040 } 44041 44042 var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 44043 escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 44044 gap, 44045 indent, 44046 meta = { // table of character substitutions 44047 '\b': '\\b', 44048 '\t': '\\t', 44049 '\n': '\\n', 44050 '\f': '\\f', 44051 '\r': '\\r', 44052 '"' : '\\"', 44053 '\\': '\\\\' 44054 }, 44055 rep; 44056 44057 44058 function quote(string) { 44059 44060// If the string contains no control characters, no quote characters, and no 44061// backslash characters, then we can safely slap some quotes around it. 44062// Otherwise we must also replace the offending characters with safe escape 44063// sequences. 44064 44065 escapable.lastIndex = 0; 44066 return escapable.test(string) ? '"' + string.replace(escapable, function (a) { 44067 var c = meta[a]; 44068 return typeof c === 'string' 44069 ? c 44070 : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 44071 }) + '"' : '"' + string + '"'; 44072 } 44073 44074 44075 function str(key, holder) { 44076 44077// Produce a string from holder[key]. 44078 44079 var i, // The loop counter. 44080 k, // The member key. 44081 v, // The member value. 44082 length, 44083 mind = gap, 44084 partial, 44085 value = holder[key]; 44086 44087// If the value has a toJSON method, call it to obtain a replacement value. 44088 44089 if (value && typeof value === 'object' && 44090 typeof value.toJSON === 'function') { 44091 value = value.toJSON(key); 44092 } 44093 44094// If we were called with a replacer function, then call the replacer to 44095// obtain a replacement value. 44096 44097 if (typeof rep === 'function') { 44098 value = rep.call(holder, key, value); 44099 } 44100 44101// What happens next depends on the value's type. 44102 44103 switch (typeof value) { 44104 case 'string': 44105 return quote(value); 44106 44107 case 'number': 44108 44109// JSON numbers must be finite. Encode non-finite numbers as null. 44110 44111 return isFinite(value) ? String(value) : 'null'; 44112 44113 case 'boolean': 44114 case 'null': 44115 44116// If the value is a boolean or null, convert it to a string. Note: 44117// typeof null does not produce 'null'. The case is included here in 44118// the remote chance that this gets fixed someday. 44119 44120 return String(value); 44121 44122// If the type is 'object', we might be dealing with an object or an array or 44123// null. 44124 44125 case 'object': 44126 44127// Due to a specification blunder in ECMAScript, typeof null is 'object', 44128// so watch out for that case. 44129 44130 if (!value) { 44131 return 'null'; 44132 } 44133 44134// Make an array to hold the partial results of stringifying this object value. 44135 44136 gap += indent; 44137 partial = []; 44138 44139// Is the value an array? 44140 44141 if (Object.prototype.toString.apply(value) === '[object Array]') { 44142 44143// The value is an array. Stringify every element. Use null as a placeholder 44144// for non-JSON values. 44145 44146 length = value.length; 44147 for (i = 0; i < length; i += 1) { 44148 partial[i] = str(i, value) || 'null'; 44149 } 44150 44151// Join all of the elements together, separated with commas, and wrap them in 44152// brackets. 44153 44154 v = partial.length === 0 44155 ? '[]' 44156 : gap 44157 ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' 44158 : '[' + partial.join(',') + ']'; 44159 gap = mind; 44160 return v; 44161 } 44162 44163// If the replacer is an array, use it to select the members to be stringified. 44164 44165 if (rep && typeof rep === 'object') { 44166 length = rep.length; 44167 for (i = 0; i < length; i += 1) { 44168 if (typeof rep[i] === 'string') { 44169 k = rep[i]; 44170 v = str(k, value); 44171 if (v) { 44172 partial.push(quote(k) + (gap ? ': ' : ':') + v); 44173 } 44174 } 44175 } 44176 } else { 44177 44178// Otherwise, iterate through all of the keys in the object. 44179 44180 for (k in value) { 44181 if (Object.prototype.hasOwnProperty.call(value, k)) { 44182 v = str(k, value); 44183 if (v) { 44184 partial.push(quote(k) + (gap ? ': ' : ':') + v); 44185 } 44186 } 44187 } 44188 } 44189 44190// Join all of the member texts together, separated with commas, 44191// and wrap them in braces. 44192 44193 v = partial.length === 0 44194 ? '{}' 44195 : gap 44196 ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' 44197 : '{' + partial.join(',') + '}'; 44198 gap = mind; 44199 return v; 44200 } 44201 } 44202 44203// If the JSON object does not yet have a stringify method, give it one. 44204 44205 if (typeof JSON.stringify !== 'function') { 44206 JSON.stringify = function (value, replacer, space) { 44207 44208// The stringify method takes a value and an optional replacer, and an optional 44209// space parameter, and returns a JSON text. The replacer can be a function 44210// that can replace values, or an array of strings that will select the keys. 44211// A default replacer method can be provided. Use of the space parameter can 44212// produce text that is more easily readable. 44213 44214 var i; 44215 gap = ''; 44216 indent = ''; 44217 44218// If the space parameter is a number, make an indent string containing that 44219// many spaces. 44220 44221 if (typeof space === 'number') { 44222 for (i = 0; i < space; i += 1) { 44223 indent += ' '; 44224 } 44225 44226// If the space parameter is a string, it will be used as the indent string. 44227 44228 } else if (typeof space === 'string') { 44229 indent = space; 44230 } 44231 44232// If there is a replacer, it must be a function or an array. 44233// Otherwise, throw an error. 44234 44235 rep = replacer; 44236 if (replacer && typeof replacer !== 'function' && 44237 (typeof replacer !== 'object' || 44238 typeof replacer.length !== 'number')) { 44239 throw new Error('JSON.stringify'); 44240 } 44241 44242// Make a fake root object containing our value under the key of ''. 44243// Return the result of stringifying the value. 44244 44245 return str('', {'': value}); 44246 }; 44247 } 44248 44249 44250// If the JSON object does not yet have a parse method, give it one. 44251 44252 if (typeof JSON.parse !== 'function') { 44253 JSON.parse = function (text, reviver) { 44254 44255// The parse method takes a text and an optional reviver function, and returns 44256// a JavaScript value if the text is a valid JSON text. 44257 44258 var j; 44259 44260 function walk(holder, key) { 44261 44262// The walk method is used to recursively walk the resulting structure so 44263// that modifications can be made. 44264 44265 var k, v, value = holder[key]; 44266 if (value && typeof value === 'object') { 44267 for (k in value) { 44268 if (Object.prototype.hasOwnProperty.call(value, k)) { 44269 v = walk(value, k); 44270 if (v !== undefined) { 44271 value[k] = v; 44272 } else { 44273 delete value[k]; 44274 } 44275 } 44276 } 44277 } 44278 return reviver.call(holder, key, value); 44279 } 44280 44281 44282// Parsing happens in four stages. In the first stage, we replace certain 44283// Unicode characters with escape sequences. JavaScript handles many characters 44284// incorrectly, either silently deleting them, or treating them as line endings. 44285 44286 text = String(text); 44287 cx.lastIndex = 0; 44288 if (cx.test(text)) { 44289 text = text.replace(cx, function (a) { 44290 return '\\u' + 44291 ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 44292 }); 44293 } 44294 44295// In the second stage, we run the text against regular expressions that look 44296// for non-JSON patterns. We are especially concerned with '()' and 'new' 44297// because they can cause invocation, and '=' because it can cause mutation. 44298// But just to be safe, we want to reject all unexpected forms. 44299 44300// We split the second stage into 4 regexp operations in order to work around 44301// crippling inefficiencies in IE's and Safari's regexp engines. First we 44302// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 44303// replace all simple value tokens with ']' characters. Third, we delete all 44304// open brackets that follow a colon or comma or that begin the text. Finally, 44305// we look to see that the remaining characters are only whitespace or ']' or 44306// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 44307 44308 if (/^[\],:{}\s]*$/ 44309 .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') 44310 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 44311 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 44312 44313// In the third stage we use the eval function to compile the text into a 44314// JavaScript structure. The '{' operator is subject to a syntactic ambiguity 44315// in JavaScript: it can begin a block or an object literal. We wrap the text 44316// in parens to eliminate the ambiguity. 44317 44318 j = eval('(' + text + ')'); 44319 44320// In the optional fourth stage, we recursively walk the new structure, passing 44321// each name/value pair to a reviver function for possible transformation. 44322 44323 return typeof reviver === 'function' 44324 ? walk({'': j}, '') 44325 : j; 44326 } 44327 44328// If the text is not JSON parseable, then a SyntaxError is thrown. 44329 44330 throw new SyntaxError('JSON.parse'); 44331 }; 44332 } 44333}());
vendor: 5,235 bytes, lines 44334-44337
44334/*! modernizr 3.3.1 (Custom Build) | MIT * 44335 * https://modernizr.com/download/?-applicationcache-backgroundsize-borderimage-boxshadow-canvas-canvastext-cssanimations-csscalc-csscolumns-cssreflections-csstransforms-csstransforms3d-csstransitions-flexbox-flexboxlegacy-fontface-generatedcontent-geolocation-hashchange-history-hsla-indexeddb-inlinesvg-input-inputtypes-localstorage-multiplebgs-objectfit-opacity-postmessage-rgba-sessionstorage-smil-svg-svgclippaths-textshadow-touchevents-video-webgl-websockets-websqldatabase-webworkers-domprefixes-hasevent-mq-prefixes-setclasses-shiv-testallprops-testprop-teststyles !*/ 44336 44337 !function(e,t,n){function r(e,t){return typeof e===t}function a(){var e,t,n,a,o,i,s;for(var c in b)if(b.hasOwnProperty(c)){if(e=[],t=b[c],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(a=r(t.fn,"function")?t.fn():t.fn,o=0;o<e.length;o++)i=e[o],s=i.split("."),1===s.length?Modernizr[s[0]]=a:(!Modernizr[s[0]]||Modernizr[s[0]]instanceof Boolean||(Modernizr[s[0]]=new Boolean(Modernizr[s[0]])),Modernizr[s[0]][s[1]]=a),y.push((a?"":"no-")+s.join("-"))}}function o(e){var t=C.className,n=Modernizr._config.classPrefix||"";if(E&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),E?C.className.baseVal=t:C.className=t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):E?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function s(e,t){return!!~(""+e).indexOf(t)}function c(){var e=t.body;return e||(e=i(E?"svg":"body"),e.fake=!0),e}function l(e,n,r,a){var o,s,l,d,u="modernizr",f=i("div"),p=c();if(parseInt(r,10))for(;r--;)l=i("div"),l.id=a?a[r]:u+(r+1),f.appendChild(l);return o=i("style"),o.type="text/css",o.id="s"+u,(p.fake?p:f).appendChild(o),p.appendChild(f),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(t.createTextNode(e)),f.id=u,p.fake&&(p.style.background="",p.style.overflow="hidden",d=C.style.overflow,C.style.overflow="hidden",C.appendChild(p)),s=n(f,e),p.fake?(p.parentNode.removeChild(p),C.style.overflow=d,C.offsetHeight):f.parentNode.removeChild(f),!!s}function d(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function u(e,t){return function(){return e.apply(t,arguments)}}function f(e,t,n){var a;for(var o in e)if(e[o]in t)return n===!1?e[o]:(a=t[e[o]],r(a,"function")?u(a,n||t):a);return!1}function p(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function m(t,r){var a=t.length;if("CSS"in e&&"supports"in e.CSS){for(;a--;)if(e.CSS.supports(p(t[a]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var o=[];a--;)o.push("("+p(t[a])+":"+r+")");return o=o.join(" or "),l("@supports ("+o+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return n}function h(e,t,a,o){function c(){u&&(delete V.style,delete V.modElem)}if(o=r(o,"undefined")?!1:o,!r(a,"undefined")){var l=m(e,a);if(!r(l,"undefined"))return l}for(var u,f,p,h,g,v=["modernizr","tspan","samp"];!V.style&&v.length;)u=!0,V.modElem=i(v.shift()),V.style=V.modElem.style;for(p=e.length,f=0;p>f;f++)if(h=e[f],g=V.style[h],s(h,"-")&&(h=d(h)),V.style[h]!==n){if(o||r(a,"undefined"))return c(),"pfx"==t?h:!0;try{V.style[h]=a}catch(y){}if(V.style[h]!=g)return c(),"pfx"==t?h:!0}return c(),!1}function g(e,t,n,a,o){var i=e.charAt(0).toUpperCase()+e.slice(1),s=(e+" "+B.join(i+" ")+i).split(" ");return r(t,"string")||r(t,"undefined")?h(s,t,a,o):(s=(e+" "+_.join(i+" ")+i).split(" "),f(s,t,n))}function v(e,t,r){return g(e,n,n,t,r)}var y=[],b=[],x={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){b.push({name:e,fn:t,options:n})},addAsyncTest:function(e){b.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=x,Modernizr=new Modernizr,Modernizr.addTest("applicationcache","applicationCache"in e),Modernizr.addTest("geolocation","geolocation"in navigator),Modernizr.addTest("history",function(){var t=navigator.userAgent;return-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone")?e.history&&"pushState"in e.history:!1}),Modernizr.addTest("postmessage","postMessage"in e),Modernizr.addTest("svg",!!t.createElementNS&&!!t.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect);var T=!1;try{T="WebSocket"in e&&2===e.WebSocket.CLOSING}catch(w){}Modernizr.addTest("websockets",T),Modernizr.addTest("localstorage",function(){var e="modernizr";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(t){return!1}}),Modernizr.addTest("sessionstorage",function(){var e="modernizr";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(t){return!1}}),Modernizr.addTest("websqldatabase","openDatabase"in e),Modernizr.addTest("webworkers","Worker"
44337in e);var S=x._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];x._prefixes=S;var C=t.documentElement,E="svg"===C.nodeName.toLowerCase();E||!function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function a(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,l(t)}function o(e){var t=y[e[g]];return t||(t={},v++,e[g]=v,y[v]=t),t}function i(e,n,r){if(n||(n=t),u)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():h.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function s(e,n){if(e||(e=t),u)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,s=r(),c=s.length;c>i;i++)a.createElement(s[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function l(e){e||(e=t);var r=o(e);return!b.shivCSS||d||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),u||c(e,r),e}var d,u,f="3.7.3",p=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,h=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",v=0,y={};!function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,u=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){d=!0,u=!0}}();var b={elements:p.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:f,shivCSS:p.shivCSS!==!1,supportsUnknownElements:u,shivMethods:p.shivMethods!==!1,type:"default",shivDocument:l,createElement:i,createDocumentFragment:s,addElements:a};e.html5=b,l(t),"object"==typeof module&&module.exports&&(module.exports=b)}("undefined"!=typeof e?e:this,t);var k="Moz O ms Webkit",_=x._config.usePrefixes?k.toLowerCase().split(" "):[];x._domPrefixes=_;var z=function(){function e(e,t){var a;return e?(t&&"string"!=typeof t||(t=i(t||"div")),e="on"+e,a=e in t,!a&&r&&(t.setAttribute||(t=i("div")),t.setAttribute(e,""),a="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),a):!1}var r=!("onblur"in t.documentElement);return e}();x.hasEvent=z,Modernizr.addTest("hashchange",function(){return z("hashchange",e)===!1?!1:t.documentMode===n||t.documentMode>7}),Modernizr.addTest("canvas",function(){var e=i("canvas");return!(!e.getContext||!e.getContext("2d"))}),Modernizr.addTest("canvastext",function(){return Modernizr.canvas===!1?!1:"function"==typeof i("canvas").getContext("2d").fillText}),Modernizr.addTest("video",function(){var e=i("video"),t=!1;try{(t=!!e.canPlayType)&&(t=new Boolean(t),t.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),t.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),t.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""),t.vp9=e.canPlayType('video/webm; codecs="vp9"').replace(/^no$/,""),t.hls=e.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/,""))}catch(n){}return t}),Modernizr.addTest("webgl",function(){var t=i("canvas"),n="probablySupportsContext"in t?"probablySupportsContext":"supportsContext";return n in t?t[n]("webgl")||t[n]("experimental-webgl"):"WebGLRenderingContext"in e}),Modernizr.addTest("csscalc",function(){var e="width:",t="calc(10px);",n=i("a");return n.style.cssText=e+S.join(t+e),!!n.style.length}),Modernizr.addTest("multiplebgs",function(){var e=i("a").style;return e.cssText="background:url(https://),url(https://),red url(https://)",/(url\s*\(.*?){3}/.test(e.background)}),Modernizr.addTest("opacity",function(){var e=i("a").style;return e.cssText=S.join("opacity:.55;"),/^0.55$/.test(e.opacity)}),Modernizr.addTest("rgba",function(){var e=i("a").style;return e.cssText="background-color:rgba(150,255,150,.5)",(""+e.backgroundColor).indexOf("rgba")>-1}),Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="<svg/>
vendor: 7,488 bytes, lines 44337-44355
44337","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)});var N=i("input"),P="autocomplete autofocus list placeholder max min multiple pattern required step".split(" "),R={};Modernizr.input=function(t){for(var n=0,r=t.length;r>n;n++)R[t[n]]=!!(t[n]in N);return R.list&&(R.list=!(!i("datalist")||!e.HTMLDataListElement)),R}(P);var A="search tel url email datetime date month week time datetime-local number range color".split(" "),j={};Modernizr.inputtypes=function(e){for(var r,a,o,i=e.length,s="1)",c=0;i>c;c++)N.setAttribute("type",r=e[c]),o="text"!==N.type&&"style"in N,o&&(N.value=s,N.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(r)&&N.style.WebkitAppearance!==n?(C.appendChild(N),a=t.defaultView,o=a.getComputedStyle&&"textfield"!==a.getComputedStyle(N,null).WebkitAppearance&&0!==N.offsetHeight,C.removeChild(N)):/^(search|tel)$/.test(r)||(o=/^(url|email)$/.test(r)?N.checkValidity&&N.checkValidity()===!1:N.value!=s)),j[e[c]]=!!o;return j}(A),Modernizr.addTest("hsla",function(){var e=i("a").style;return e.cssText="background-color:hsla(120,40%,100%,.5)",s(e.backgroundColor,"rgba")||s(e.backgroundColor,"hsla")});var M="CSS"in e&&"supports"in e.CSS,L="supportsCSS"in e;Modernizr.addTest("supports",M||L);var $={}.toString;Modernizr.addTest("svgclippaths",function(){return!!t.createElementNS&&/SVGClipPath/.test($.call(t.createElementNS("http://www.w3.org/2000/svg","clipPath")))}),Modernizr.addTest("smil",function(){return!!t.createElementNS&&/SVGAnimate/.test($.call(t.createElementNS("http://www.w3.org/2000/svg","animate")))});var F=function(){var t=e.matchMedia||e.msMatchMedia;return t?function(e){var n=t(e);return n&&n.matches||!1}:function(t){var n=!1;return l("@media "+t+" { #modernizr { position: absolute; } }",function(t){n="absolute"==(e.getComputedStyle?e.getComputedStyle(t,null):t.currentStyle).position}),n}}();x.mq=F;var O=x.testStyles=l;Modernizr.addTest("touchevents",function(){var n;if("ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch)n=!0;else{var r=["@media (",S.join("touch-enabled),("),"heartz",")","{#modernizr{top:9px;position:absolute}}"].join("");O(r,function(e){n=9===e.offsetTop})}return n});var D=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,a=533>t&&e.match(/android/gi);return n||a||r}();D?Modernizr.addTest("fontface",!1):O('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),a=r.sheet||r.styleSheet,o=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"",i=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);Modernizr.addTest("fontface",i)}),O('#modernizr{font:0/0 a}#modernizr:after{content:":)";visibility:hidden;font:7px/1 a}',function(e){Modernizr.addTest("generatedcontent",e.offsetHeight>=7)});var B=x._config.usePrefixes?k.split(" "):[];x._cssomPrefixes=B;var I=function(t){var r,a=S.length,o=e.CSSRule;if("undefined"==typeof o)return n;if(!t)return!1;if(t=t.replace(/^@/,""),r=t.replace(/-/g,"_").toUpperCase()+"_RULE",r in o)return"@"+t;for(var i=0;a>i;i++){var s=S[i],c=s.toUpperCase()+"_"+r;if(c in o)return"@-"+s.toLowerCase()+"-"+t}return!1};x.atRule=I;var W={elem:i("modernizr")};Modernizr._q.push(function(){delete W.elem});var V={style:W.elem.style};Modernizr._q.unshift(function(){delete V.style});var q=x.testProp=function(e,t,r){return h([e],n,t,r)};Modernizr.addTest("textshadow",q("textShadow","1px 1px")),x.testAllProps=g,x.testAllProps=v,Modernizr.addTest("cssanimations",v("animationName","a",!0)),Modernizr.addTest("backgroundsize",v("backgroundSize","100%",!0)),Modernizr.addTest("borderimage",v("borderImage","url() 1",!0)),Modernizr.addTest("boxshadow",v("boxShadow","1px 1px",!0)),function(){Modernizr.addTest("csscolumns",function(){var e=!1,t=v("columnCount");try{(e=!!t)&&(e=new Boolean(e))}catch(n){}return e});for(var e,t,n=["Width","Span","Fill","Gap","Rule","RuleColor","RuleStyle","RuleWidth","BreakBefore","BreakAfter","BreakInside"],r=0;r<n.length;r++)e=n[r].toLowerCase(),t=v("column"+n[r]),("breakbefore"===e||"breakafter"===e||"breakinside"==e)&&(t=t||v(n[r])),Modernizr.addTest("csscolumns."+e,t)}(),Modernizr.addTest("flexbox",v("flexBasis","1px",!0)),Modernizr.addTest("flexboxlegacy",v("boxDirection","reverse",!0)),Modernizr.addTest("cssreflections",v("boxReflect","above",!0)),Modernizr.addTest("csstransforms",function(){return-1===navigator.userAgent.indexOf("Android 2.")&&v("transform","scale(1)",!0)}),Modernizr.addTest("csstransforms3d",function(){var e=!!v("perspective","1px",!0),t=Modernizr._config.usePrefixes;if(e&&(!t||"webkitPerspective"in C.style)){var n,r="#modernizr{width:0;height:0}";Modernizr.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",O(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),Modernizr.addTest("csstransitions",v("transition","all",!0));var H,U=x.prefixed=function(e,t,n){return 0===e.indexOf("@")?I(e):(-1!=e.indexOf("-")&&(e=d(e)),t?g(e,t,n):g(e,"pfx"))};try{H=U("indexedDB",e)}catch(w){}Modernizr.addTest("indexeddb",!!H),H&&Modernizr.addTest("indexeddb.deletedatabase","deleteDatabase"in H),Modernizr.addTest("objectfit",!!U("objectFit"),{aliases:["object-fit"]}),a(),o(y),delete x.addTest,delete x.addAsyncTest;for(var G=0;G<Modernizr._q.length;G++)Modernizr._q[G]();e.Modernizr=Modernizr}(window,document); 44338/* 44339 _ _ _ _ 44340 ___| (_) ___| | __ (_)___ 44341/ __| | |/ __| |/ / | / __| 44342\__ \ | | (__| < _ | \__ \ 44343|___/_|_|\___|_|\_(_)/ |___/ 44344 |__/ 44345 44346 Version: 1.8.1 44347 Author: Ken Wheeler 44348 Website: http://kenwheeler.github.io 44349 Docs: http://kenwheeler.github.io/slick 44350 Repo: http://github.com/kenwheeler/slick 44351 Issues: http://github.com/kenwheeler/slick/issues 44352 44353 */ 44354 44355!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,
vendor: 6,594 bytes, line 44355
44355sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.o
vendor: 3,442 bytes, line 44355
44355ptions.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.
44355slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:
44355parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"}
44355,e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0}
vendor: 5,619 bytes, line 44355
44355,100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};
44355!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}
44355):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+
44355o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")}
44355,e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}}); 44356// WebcamJS v1.0.24 44357// Webcam library for capturing JPEG/PNG images in JavaScript 44358// Attempts getUserMedia, falls back to Flash 44359// Author: Joseph Huckaby: http://github.com/jhuckaby 44360// Based on JPEGCam: http://code.google.com/p/jpegcam/ 44361// Copyright (c) 2012 - 2017 Joseph Huckaby 44362// Licensed under the MIT License 44363 44364(function(window) { 44365var _userMedia; 44366 44367// declare error types 44368 44369// inheritance pattern here: 44370// https://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript 44371function FlashError() { 44372 var temp = Error.apply(this, arguments); 44373 temp.name = this.name = "FlashError"; 44374 this.stack = temp.stack; 44375 this.message = temp.message; 44376} 44377 44378function WebcamError() { 44379 var temp = Error.apply(this, arguments); 44380 temp.name = this.name = "WebcamError"; 44381 this.stack = temp.stack; 44382 this.message = temp.message; 44383} 44384 44385IntermediateInheritor = function() {}; 44386IntermediateInheritor.prototype = Error.prototype; 44387 44388FlashError.prototype = new IntermediateInheritor(); 44389WebcamError.prototype = new IntermediateInheritor(); 44390 44391var Webcam = { 44392 version: '1.0.24', 44393 44394 // globals 44395 protocol: location.protocol.match(/https/i) ? 'https' : 'http', 44396 loaded: false, // true when webcam movie finishes loading 44397 live: false, // true when webcam is initialized and ready to snap 44398 userMedia: true, // true when getUserMedia is supported natively 44399 44400 iOS: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream, 44401 44402 params: { 44403 width: 0, 44404 height: 0, 44405 dest_width: 0, // size of captured image 44406 dest_height: 0, // these default to width/height 44407 image_format: 'jpeg', // image format (may be jpeg or png) 44408 jpeg_quality: 90, // jpeg image quality from 0 (worst) to 100 (best) 44409 enable_flash: true, // enable flash fallback, 44410 force_flash: false, // force flash mode, 44411 flip_horiz: false, // flip image horiz (mirror mode) 44412 fps: 30, // camera frames per second 44413 upload_name: 'webcam', // name of file in upload post data 44414 constraints: null, // custom user media constraints, 44415 swfURL: '', // URI to webcam.swf movie (defaults to the js location) 44416 flashNotDetectedText: 'ERROR: No Adobe Flash Player detected. Webcam.js relies on Flash for browsers that do not support getUserMedia (like yours).', 44417 noInterfaceFoundText: 'No supported webcam interface found.', 44418 unfreeze_snap: true, // Whether to unfreeze the camera after snap (defaults to true) 44419 iosPlaceholderText: 'Click here to open camera.', 44420 user_callback: null, // callback function for snapshot (used if no user_callback parameter given to snap function) 44421 user_canvas: null // user provided canvas for snapshot (used if no user_canvas parameter given to snap function) 44422 }, 44423 44424 errors: { 44425 FlashError: FlashError, 44426 WebcamError: WebcamError 44427 }, 44428 44429 hooks: {}, // callback hook functions 44430 44431 init: function() { 44432 // initialize, check for getUserMedia support 44433 var self = this; 44434
vendor: 6,990 bytes, lines 44435-44631
44435 // Setup getUserMedia, with polyfill for older browsers 44436 // Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia 44437 this.mediaDevices = (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ? 44438 navigator.mediaDevices : ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? { 44439 getUserMedia: function(c) { 44440 return new Promise(function(y, n) { 44441 (navigator.mozGetUserMedia || 44442 navigator.webkitGetUserMedia).call(navigator, c, y, n); 44443 }); 44444 } 44445 } : null); 44446 44447 window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; 44448 this.userMedia = this.userMedia && !!this.mediaDevices && !!window.URL; 44449 44450 if (this.iOS) { 44451 this.userMedia = null; 44452 } 44453 44454 // Older versions of firefox (< 21) apparently claim support but user media does not actually work 44455 if (navigator.userAgent.match(/Firefox\D+(\d+)/)) { 44456 if (parseInt(RegExp.$1, 10) < 21) this.userMedia = null; 44457 } 44458 44459 // Make sure media stream is closed when navigating away from page 44460 if (this.userMedia) { 44461 window.addEventListener( 'beforeunload', function(event) { 44462 self.reset(); 44463 } ); 44464 } 44465 }, 44466 44467 exifOrientation: function(binFile) { 44468 // extract orientation information from the image provided by iOS 44469 // algorithm based on exif-js 44470 var dataView = new DataView(binFile); 44471 if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 44472 console.log('Not a valid JPEG file'); 44473 return 0; 44474 } 44475 var offset = 2; 44476 var marker = null; 44477 while (offset < binFile.byteLength) { 44478 // find 0xFFE1 (225 marker) 44479 if (dataView.getUint8(offset) != 0xFF) { 44480 console.log('Not a valid marker at offset ' + offset + ', found: ' + dataView.getUint8(offset)); 44481 return 0; 44482 } 44483 marker = dataView.getUint8(offset + 1); 44484 if (marker == 225) { 44485 offset += 4; 44486 var str = ""; 44487 for (n = 0; n < 4; n++) { 44488 str += String.fromCharCode(dataView.getUint8(offset+n)); 44489 } 44490 if (str != 'Exif') { 44491 console.log('Not valid EXIF data found'); 44492 return 0; 44493 } 44494 44495 offset += 6; // tiffOffset 44496 var bigEnd = null; 44497 44498 // test for TIFF validity and endianness 44499 if (dataView.getUint16(offset) == 0x4949) { 44500 bigEnd = false; 44501 } else if (dataView.getUint16(offset) == 0x4D4D) { 44502 bigEnd = true; 44503 } else { 44504 console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); 44505 return 0; 44506 } 44507 44508 if (dataView.getUint16(offset+2, !bigEnd) != 0x002A) { 44509 console.log("Not valid TIFF data! (no 0x002A)"); 44510 return 0; 44511 } 44512 44513 var firstIFDOffset = dataView.getUint32(offset+4, !bigEnd); 44514 if (firstIFDOffset < 0x00000008) { 44515 console.log("Not valid TIFF data! (First offset less than 8)", dataView.getUint32(offset+4, !bigEnd)); 44516 return 0; 44517 } 44518 44519 // extract orientation data 44520 var dataStart = offset + firstIFDOffset; 44521 var entries = dataView.getUint16(dataStart, !bigEnd); 44522 for (var i=0; i<entries; i++) { 44523 var entryOffset = dataStart + i*12 + 2; 44524 if (dataView.getUint16(entryOffset, !bigEnd) == 0x0112) { 44525 var valueType = dataView.getUint16(entryOffset+2, !bigEnd); 44526 var numValues = dataView.getUint32(entryOffset+4, !bigEnd); 44527 if (valueType != 3 && numValues != 1) { 44528 console.log('Invalid EXIF orientation value type ('+valueType+') or count ('+numValues+')'); 44529 return 0; 44530 } 44531 var value = dataView.getUint16(entryOffset + 8, !bigEnd); 44532 if (value < 1 || value > 8) { 44533 console.log('Invalid EXIF orientation value ('+value+')'); 44534 return 0; 44535 } 44536 return value; 44537 } 44538 } 44539 } else { 44540 offset += 2+dataView.getUint16(offset+2); 44541 } 44542 } 44543 return 0; 44544 }, 44545 44546 fixOrientation: function(origObjURL, orientation, targetImg) { 44547 // fix image orientation based on exif orientation data 44548 // exif orientation information 44549 // http://www.impulseadventure.com/photo/exif-orientation.html 44550 // link source wikipedia (https://en.wikipedia.org/wiki/Exif#cite_note-20) 44551 var img = new Image(); 44552 img.addEventListener('load', function(event) { 44553 var canvas = document.createElement('canvas'); 44554 var ctx = canvas.getContext('2d'); 44555 44556 // switch width height if orientation needed 44557 if (orientation < 5) { 44558 canvas.width = img.width; 44559 canvas.height = img.height; 44560 } else { 44561 canvas.width = img.height; 44562 canvas.height = img.width; 44563 } 44564 44565 // transform (rotate) image - see link at beginning this method 44566 switch (orientation) { 44567 case 2: ctx.transform(-1, 0, 0, 1, img.width, 0); break; 44568 case 3: ctx.transform(-1, 0, 0, -1, img.width, img.height); break; 44569 case 4: ctx.transform(1, 0, 0, -1, 0, img.height); break; 44570 case 5: ctx.transform(0, 1, 1, 0, 0, 0); break; 44571 case 6: ctx.transform(0, 1, -1, 0, img.height , 0); break; 44572 case 7: ctx.transform(0, -1, -1, 0, img.height, img.width); break; 44573 case 8: ctx.transform(0, -1, 1, 0, 0, img.width); break; 44574 } 44575 44576 ctx.drawImage(img, 0, 0); 44577 // pass rotated image data to the target image container 44578 targetImg.src = canvas.toDataURL(); 44579 }, false); 44580 // start transformation by load event 44581 img.src = origObjURL; 44582 }, 44583 44584 attach: function(elem) { 44585 // create webcam preview and attach to DOM element 44586 // pass in actual DOM reference, ID, or CSS selector 44587 if (typeof(elem) == 'string') { 44588 elem = document.getElementById(elem) || document.querySelector(elem); 44589 } 44590 if (!elem) { 44591 return this.dispatch('error', new WebcamError("Could not locate DOM element to attach to.")); 44592 } 44593 this.container = elem; 44594 elem.innerHTML = ''; // start with empty element 44595 44596 // insert "peg" so we can insert our preview canvas adjacent to it later on 44597 var peg = document.createElement('div'); 44598 elem.appendChild( peg ); 44599 this.peg = peg; 44600 44601 // set width/height if not already set 44602 if (!this.params.width) this.params.width = elem.offsetWidth; 44603 if (!this.params.height) this.params.height = elem.offsetHeight; 44604 44605 // make sure we have a nonzero width and height at this point 44606 if (!this.params.width || !this.params.height) { 44607 return this.dispatch('error', new WebcamError("No width and/or height for webcam. Please call set() first, or attach to a visible element.")); 44608 } 44609 44610 // set defaults for dest_width / dest_height if not set 44611 if (!this.params.dest_width) this.params.dest_width = this.params.width; 44612 if (!this.params.dest_height) this.params.dest_height = this.params.height; 44613 44614 this.userMedia = _userMedia === undefined ? this.userMedia : _userMedia; 44615 // if force_flash is set, disable userMedia 44616 if (this.params.force_flash) { 44617 _userMedia = this.userMedia; 44618 this.userMedia = null; 44619 } 44620 44621 // check for default fps 44622 if (typeof this.params.fps !== "number") this.params.fps = 30; 44623 44624 // adjust scale if dest_width or dest_height is different 44625 var scaleX = this.params.width / this.params.dest_width; 44626 var scaleY = this.params.height / this.params.dest_height; 44627 44628 if (this.userMedia) { 44629 // setup webcam video container 44630 var video = document.createElement('video'); 44631 video.setAttribute('autoplay', 'autoplay
vendor: 26,369 bytes, lines 44631-45406
44631'); 44632 video.style.width = '' + this.params.dest_width + 'px'; 44633 video.style.height = '' + this.params.dest_height + 'px'; 44634 44635 if ((scaleX != 1.0) || (scaleY != 1.0)) { 44636 elem.style.overflow = 'hidden'; 44637 video.style.webkitTransformOrigin = '0px 0px'; 44638 video.style.mozTransformOrigin = '0px 0px'; 44639 video.style.msTransformOrigin = '0px 0px'; 44640 video.style.oTransformOrigin = '0px 0px'; 44641 video.style.transformOrigin = '0px 0px'; 44642 video.style.webkitTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 44643 video.style.mozTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 44644 video.style.msTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 44645 video.style.oTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 44646 video.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 44647 } 44648 44649 // add video element to dom 44650 elem.appendChild( video ); 44651 this.video = video; 44652 44653 // ask user for access to their camera 44654 var self = this; 44655 this.mediaDevices.getUserMedia({ 44656 "audio": false, 44657 "video": this.params.constraints || { 44658 mandatory: { 44659 minWidth: this.params.dest_width, 44660 minHeight: this.params.dest_height 44661 } 44662 } 44663 }) 44664 .then( function(stream) { 44665 // got access, attach stream to video 44666 video.onloadedmetadata = function(e) { 44667 self.stream = stream; 44668 self.loaded = true; 44669 self.live = true; 44670 self.dispatch('load'); 44671 self.dispatch('live'); 44672 self.flip(); 44673 }; 44674 // as window.URL.createObjectURL() is deprecated, adding a check so that it works in Safari. 44675 // older browsers may not have srcObject 44676 if ("srcObject" in video) { 44677 video.srcObject = stream; 44678 } 44679 else { 44680 // using URL.createObjectURL() as fallback for old browsers 44681 video.src = window.URL.createObjectURL(stream); 44682 } 44683 }) 44684 .catch( function(err) { 44685 // JH 2016-07-31 Instead of dispatching error, now falling back to Flash if userMedia fails (thx @john2014) 44686 // JH 2016-08-07 But only if flash is actually installed -- if not, dispatch error here and now. 44687 if (self.params.enable_flash && self.detectFlash()) { 44688 setTimeout( function() { self.params.force_flash = 1; self.attach(elem); }, 1 ); 44689 } 44690 else { 44691 self.dispatch('error', err); 44692 } 44693 }); 44694 } 44695 else if (this.iOS) { 44696 // prepare HTML elements 44697 var div = document.createElement('div'); 44698 div.id = this.container.id+'-ios_div'; 44699 div.className = 'webcamjs-ios-placeholder'; 44700 div.style.width = '' + this.params.width + 'px'; 44701 div.style.height = '' + this.params.height + 'px'; 44702 div.style.textAlign = 'center'; 44703 div.style.display = 'table-cell'; 44704 div.style.verticalAlign = 'middle'; 44705 div.style.backgroundRepeat = 'no-repeat'; 44706 div.style.backgroundSize = 'contain'; 44707 div.style.backgroundPosition = 'center'; 44708 var span = document.createElement('span'); 44709 span.className = 'webcamjs-ios-text'; 44710 span.innerHTML = this.params.iosPlaceholderText; 44711 div.appendChild(span); 44712 var img = document.createElement('img'); 44713 img.id = this.container.id+'-ios_img'; 44714 img.style.width = '' + this.params.dest_width + 'px'; 44715 img.style.height = '' + this.params.dest_height + 'px'; 44716 img.style.display = 'none'; 44717 div.appendChild(img); 44718 var input = document.createElement('input'); 44719 input.id = this.container.id+'-ios_input'; 44720 input.setAttribute('type', 'file'); 44721 input.setAttribute('accept', 'image/*'); 44722 input.setAttribute('capture', 'camera'); 44723 44724 var self = this; 44725 var params = this.params; 44726 // add input listener to load the selected image 44727 input.addEventListener('change', function(event) { 44728 if (event.target.files.length > 0 && event.target.files[0].type.indexOf('image/') == 0) { 44729 var objURL = URL.createObjectURL(event.target.files[0]); 44730 44731 // load image with auto scale and crop 44732 var image = new Image(); 44733 image.addEventListener('load', function(event) { 44734 var canvas = document.createElement('canvas'); 44735 canvas.width = params.dest_width; 44736 canvas.height = params.dest_height; 44737 var ctx = canvas.getContext('2d'); 44738 44739 // crop and scale image for final size 44740 ratio = Math.min(image.width / params.dest_width, image.height / params.dest_height); 44741 var sw = params.dest_width * ratio; 44742 var sh = params.dest_height * ratio; 44743 var sx = (image.width - sw) / 2; 44744 var sy = (image.height - sh) / 2; 44745 ctx.drawImage(image, sx, sy, sw, sh, 0, 0, params.dest_width, params.dest_height); 44746 44747 var dataURL = canvas.toDataURL(); 44748 img.src = dataURL; 44749 div.style.backgroundImage = "url('"+dataURL+"')"; 44750 }, false); 44751 44752 // read EXIF data 44753 var fileReader = new FileReader(); 44754 fileReader.addEventListener('load', function(e) { 44755 var orientation = self.exifOrientation(e.target.result); 44756 if (orientation > 1) { 44757 // image need to rotate (see comments on fixOrientation method for more information) 44758 // transform image and load to image object 44759 self.fixOrientation(objURL, orientation, image); 44760 } else { 44761 // load image data to image object 44762 image.src = objURL; 44763 } 44764 }, false); 44765 44766 // Convert image data to blob format 44767 var http = new XMLHttpRequest(); 44768 http.open("GET", objURL, true); 44769 http.responseType = "blob"; 44770 http.onload = function(e) { 44771 if (this.status == 200 || this.status === 0) { 44772 fileReader.readAsArrayBuffer(this.response); 44773 } 44774 }; 44775 http.send(); 44776 44777 } 44778 }, false); 44779 input.style.display = 'none'; 44780 elem.appendChild(input); 44781 // make div clickable for open camera interface 44782 div.addEventListener('click', function(event) { 44783 if (params.user_callback) { 44784 // global user_callback defined - create the snapshot 44785 self.snap(params.user_callback, params.user_canvas); 44786 } else { 44787 // no global callback definied for snapshot, load image and wait for external snap method call 44788 input.style.display = 'block'; 44789 input.focus(); 44790 input.click(); 44791 input.style.display = 'none'; 44792 } 44793 }, false); 44794 elem.appendChild(div); 44795 this.loaded = true; 44796 this.live = true; 44797 } 44798 else if (this.params.enable_flash && this.detectFlash()) { 44799 // flash fallback 44800 window.Webcam = Webcam; // needed for flash-to-js interface 44801 var div = document.createElement('div'); 44802 div.innerHTML = this.getSWFHTML(); 44803 elem.appendChild( div ); 44804 } 44805 else { 44806 this.dispatch('error', new WebcamError( this.params.noInterfaceFoundText )); 44807 } 44808 44809 // setup final crop for live preview 44810 if (this.params.crop_width && this.params.crop_height) { 44811 var scaled_crop_width = Math.floor( this.params.crop_width * scaleX ); 44812 var scaled_crop_height = Math.floor( this.params.crop_height * scaleY ); 44813 44814 elem.style.width = '' + scaled_crop_width + 'px'; 44815 elem.style.height = '' + scaled_crop_height + 'px'; 44816 elem.style.overflow = 'hidden'; 44817 44818 elem.scrollLeft = Math.floor( (this.params.width / 2) - (scaled_crop_width / 2) ); 44819 elem.scrollTop = Math.floor( (this.params.height / 2) - (scaled_crop_height / 2) ); 44820 } 44821 else { 44822 // no crop, set size to desired 44823 elem.style.width = '' + this.params.width + 'px'; 44824 elem.style.height = '' + this.params.height + 'px'; 44825 } 44826 }, 44827 44828 reset: function() { 44829 // shutdown camera, reset to potentially attach again 44830 if (this.preview_active) this.unfreeze(); 44831 44832 // attempt to fix issue #64 44833 this.unflip(); 44834 44835 if (this.userMedia) { 44836 if (this.stream) { 44837 if (this.stream.getVideoTracks) { 44838 // get video track to call stop on it 44839 var tracks = this.stream.getVideoTracks(); 44840 if (tracks && tracks[0] && tracks[0].stop) tracks[0].stop(); 44841 } 44842 else if (this.stream.stop) { 44843 // deprecated, may be removed in future 44844 this.stream.stop(); 44845 } 44846 } 44847 delete this.stream; 44848 delete this.video; 44849 } 44850 44851 if ((this.userMedia !== true) && this.loaded && !this.iOS) { 44852 // call for turn off camera in flash 44853 var movie = this.getMovie(); 44854 if (movie && movie._releaseCamera) movie._releaseCamera(); 44855 } 44856 44857 if (this.container) { 44858 this.container.innerHTML = ''; 44859 delete this.container; 44860 } 44861 44862 this.loaded = false; 44863 this.live = false; 44864 }, 44865 44866 set: function() { 44867 // set one or more params 44868 // variable argument list: 1 param = hash, 2 params = key, value 44869 if (arguments.length == 1) { 44870 for (var key in arguments[0]) { 44871 this.params[key] = arguments[0][key]; 44872 } 44873 } 44874 else { 44875 this.params[ arguments[0] ] = arguments[1]; 44876 } 44877 }, 44878 44879 on: function(name, callback) { 44880 // set callback hook 44881 name = name.replace(/^on/i, '').toLowerCase(); 44882 if (!this.hooks[name]) this.hooks[name] = []; 44883 this.hooks[name].push( callback ); 44884 }, 44885 44886 off: function(name, callback) { 44887 // remove callback hook 44888 name = name.replace(/^on/i, '').toLowerCase(); 44889 if (this.hooks[name]) { 44890 if (callback) { 44891 // remove one selected callback from list 44892 var idx = this.hooks[name].indexOf(callback); 44893 if (idx > -1) this.hooks[name].splice(idx, 1); 44894 } 44895 else { 44896 // no callback specified, so clear all 44897 this.hooks[name] = []; 44898 } 44899 } 44900 }, 44901 44902 dispatch: function() { 44903 // fire hook callback, passing optional value to it 44904 var name = arguments[0].replace(/^on/i, '').toLowerCase(); 44905 var args = Array.prototype.slice.call(arguments, 1); 44906 44907 if (this.hooks[name] && this.hooks[name].length) { 44908 for (var idx = 0, len = this.hooks[name].length; idx < len; idx++) { 44909 var hook = this.hooks[name][idx]; 44910 44911 if (typeof(hook) == 'function') { 44912 // callback is function reference, call directly 44913 hook.apply(this, args); 44914 } 44915 else if ((typeof(hook) == 'object') && (hook.length == 2)) { 44916 // callback is PHP-style object instance method 44917 hook[0][hook[1]].apply(hook[0], args); 44918 } 44919 else if (window[hook]) { 44920 // callback is global function name 44921 window[ hook ].apply(window, args); 44922 } 44923 } // loop 44924 return true; 44925 } 44926 else if (name == 'error') { 44927 if ((args[0] instanceof FlashError) || (args[0] instanceof WebcamError)) { 44928 message = args[0].message; 44929 } else { 44930 message = "Could not access webcam: " + args[0].name + ": " + 44931 args[0].message + " " + args[0].toString(); 44932 } 44933 44934 // default error handler if no custom one specified 44935 alert("Webcam.js Error: " + message); 44936 } 44937 44938 return false; // no hook defined 44939 }, 44940 44941 setSWFLocation: function(value) { 44942 // for backward compatibility. 44943 this.set('swfURL', value); 44944 }, 44945 44946 detectFlash: function() { 44947 // return true if browser supports flash, false otherwise 44948 // Code snippet borrowed from: https://github.com/swfobject/swfobject 44949 var SHOCKWAVE_FLASH = "Shockwave Flash", 44950 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", 44951 FLASH_MIME_TYPE = "application/x-shockwave-flash", 44952 win = window, 44953 nav = navigator, 44954 hasFlash = false; 44955 44956 if (typeof nav.plugins !== "undefined" && typeof nav.plugins[SHOCKWAVE_FLASH] === "object") { 44957 var desc = nav.plugins[SHOCKWAVE_FLASH].description; 44958 if (desc && (typeof nav.mimeTypes !== "undefined" && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { 44959 hasFlash = true; 44960 } 44961 } 44962 else if (typeof win.ActiveXObject !== "undefined") { 44963 try { 44964 var ax = new ActiveXObject(SHOCKWAVE_FLASH_AX); 44965 if (ax) { 44966 var ver = ax.GetVariable("$version"); 44967 if (ver) hasFlash = true; 44968 } 44969 } 44970 catch (e) {;} 44971 } 44972 44973 return hasFlash; 44974 }, 44975 44976 getSWFHTML: function() { 44977 // Return HTML for embedding flash based webcam capture movie 44978 var html = '', 44979 swfURL = this.params.swfURL; 44980 44981 // make sure we aren't running locally (flash doesn't work) 44982 if (location.protocol.match(/file/)) { 44983 this.dispatch('error', new FlashError("Flash does not work from local disk. Please run from a web server.")); 44984 return '<h3 style="color:red">ERROR: the Webcam.js Flash fallback does not work from local disk. Please run it from a web server.</h3>'; 44985 } 44986 44987 // make sure we have flash 44988 if (!this.detectFlash()) { 44989 this.dispatch('error', new FlashError("Adobe Flash Player not found. Please install from get.adobe.com/flashplayer and try again.")); 44990 return '<h3 style="color:red">' + this.params.flashNotDetectedText + '</h3>'; 44991 } 44992 44993 // set default swfURL if not explicitly set 44994 if (!swfURL) { 44995 // find our script tag, and use that base URL 44996 var base_url = ''; 44997 var scpts = document.getElementsByTagName('script'); 44998 for (var idx = 0, len = scpts.length; idx < len; idx++) { 44999 var src = scpts[idx].getAttribute('src'); 45000 if (src && src.match(/\/webcam(\.min)?\.js/)) { 45001 base_url = src.replace(/\/webcam(\.min)?\.js.*$/, ''); 45002 idx = len; 45003 } 45004 } 45005 if (base_url) swfURL = base_url + '/webcam.swf'; 45006 else swfURL = 'webcam.swf'; 45007 } 45008 45009 // if this is the user's first visit, set flashvar so flash privacy settings panel is shown first 45010 if (window.localStorage && !localStorage.getItem('visited')) { 45011 this.params.new_user = 1; 45012 localStorage.setItem('visited', 1); 45013 } 45014 45015 // construct flashvars string 45016 var flashvars = ''; 45017 for (var key in this.params) { 45018 if (flashvars) flashvars += '&'; 45019 flashvars += key + '=' + escape(this.params[key]); 45020 } 45021 45022 // construct object/embed tag 45023 html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" type="application/x-shockwave-flash" codebase="'+this.protocol+'://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+this.params.width+'" height="'+this.params.height+'" id="webcam_movie_obj" align="middle"><param name="wmode" value="opaque" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+swfURL+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><embed id="webcam_movie_embed" src="'+swfURL+'" wmode="opaque" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+this.params.width+'" height="'+this.params.height+'" name="webcam_movie_embed" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'"></embed></object>'; 45024 45025 return html; 45026 }, 45027 45028 getMovie: function() { 45029 // get reference to movie object/embed in DOM 45030 if (!this.loaded) return this.dispatch('error', new FlashError("Flash Movie is not loaded yet")); 45031 var movie = document.getElementById('webcam_movie_obj'); 45032 if (!movie || !movie._snap) movie = document.getElementById('webcam_movie_embed'); 45033 if (!movie) this.dispatch('error', new FlashError("Cannot locate Flash movie in DOM")); 45034 return movie; 45035 }, 45036 45037 freeze: function() { 45038 // show preview, freeze camera 45039 var self = this; 45040 var params = this.params; 45041 45042 // kill preview if already active 45043 if (this.preview_active) this.unfreeze(); 45044 45045 // determine scale factor 45046 var scaleX = this.params.width / this.params.dest_width; 45047 var scaleY = this.params.height / this.params.dest_height; 45048 45049 // must unflip container as preview canvas will be pre-flipped 45050 this.unflip(); 45051 45052 // calc final size of image 45053 var final_width = params.crop_width || params.dest_width; 45054 var final_height = params.crop_height || params.dest_height; 45055 45056 // create canvas for holding preview 45057 var preview_canvas = document.createElement('canvas'); 45058 preview_canvas.width = final_width; 45059 preview_canvas.height = final_height; 45060 var preview_context = preview_canvas.getContext('2d'); 45061 45062 // save for later use 45063 this.preview_canvas = preview_canvas; 45064 this.preview_context = preview_context; 45065 45066 // scale for preview size 45067 if ((scaleX != 1.0) || (scaleY != 1.0)) { 45068 preview_canvas.style.webkitTransformOrigin = '0px 0px'; 45069 preview_canvas.style.mozTransformOrigin = '0px 0px'; 45070 preview_canvas.style.msTransformOrigin = '0px 0px'; 45071 preview_canvas.style.oTransformOrigin = '0px 0px'; 45072 preview_canvas.style.transformOrigin = '0px 0px'; 45073 preview_canvas.style.webkitTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 45074 preview_canvas.style.mozTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 45075 preview_canvas.style.msTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 45076 preview_canvas.style.oTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 45077 preview_canvas.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+')'; 45078 } 45079 45080 // take snapshot, but fire our own callback 45081 this.snap( function() { 45082 // add preview image to dom, adjust for crop 45083 preview_canvas.style.position = 'relative'; 45084 preview_canvas.style.left = '' + self.container.scrollLeft + 'px'; 45085 preview_canvas.style.top = '' + self.container.scrollTop + 'px'; 45086 45087 self.container.insertBefore( preview_canvas, self.peg ); 45088 self.container.style.overflow = 'hidden'; 45089 45090 // set flag for user capture (use preview) 45091 self.preview_active = true; 45092 45093 }, preview_canvas ); 45094 }, 45095 45096 unfreeze: function() { 45097 // cancel preview and resume live video feed 45098 if (this.preview_active) { 45099 // remove preview canvas 45100 this.container.removeChild( this.preview_canvas ); 45101 delete this.preview_context; 45102 delete this.preview_canvas; 45103 45104 // unflag 45105 this.preview_active = false; 45106 45107 // re-flip if we unflipped before 45108 this.flip(); 45109 } 45110 }, 45111 45112 flip: function() { 45113 // flip container horiz (mirror mode) if desired 45114 if (this.params.flip_horiz) { 45115 var sty = this.container.style; 45116 sty.webkitTransform = 'scaleX(-1)'; 45117 sty.mozTransform = 'scaleX(-1)'; 45118 sty.msTransform = 'scaleX(-1)'; 45119 sty.oTransform = 'scaleX(-1)'; 45120 sty.transform = 'scaleX(-1)'; 45121 sty.filter = 'FlipH'; 45122 sty.msFilter = 'FlipH'; 45123 } 45124 }, 45125 45126 unflip: function() { 45127 // unflip container horiz (mirror mode) if desired 45128 if (this.params.flip_horiz) { 45129 var sty = this.container.style; 45130 sty.webkitTransform = 'scaleX(1)'; 45131 sty.mozTransform = 'scaleX(1)'; 45132 sty.msTransform = 'scaleX(1)'; 45133 sty.oTransform = 'scaleX(1)'; 45134 sty.transform = 'scaleX(1)'; 45135 sty.filter = ''; 45136 sty.msFilter = ''; 45137 } 45138 }, 45139 45140 savePreview: function(user_callback, user_canvas) { 45141 // save preview freeze and fire user callback 45142 var params = this.params; 45143 var canvas = this.preview_canvas; 45144 var context = this.preview_context; 45145 45146 // render to user canvas if desired 45147 if (user_canvas) { 45148 var user_context = user_canvas.getContext('2d'); 45149 user_context.drawImage( canvas, 0, 0 ); 45150 } 45151 45152 // fire user callback if desired 45153 user_callback( 45154 user_canvas ? null : canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100 ), 45155 canvas, 45156 context 45157 ); 45158 45159 // remove preview 45160 if (this.params.unfreeze_snap) this.unfreeze(); 45161 }, 45162 45163 snap: function(user_callback, user_canvas) { 45164 // use global callback and canvas if not defined as parameter 45165 if (!user_callback) user_callback = this.params.user_callback; 45166 if (!user_canvas) user_canvas = this.params.user_canvas; 45167 45168 // take snapshot and return image data uri 45169 var self = this; 45170 var params = this.params; 45171 45172 if (!this.loaded) return this.dispatch('error', new WebcamError("Webcam is not loaded yet")); 45173 // if (!this.live) return this.dispatch('error', new WebcamError("Webcam is not live yet")); 45174 if (!user_callback) return this.dispatch('error', new WebcamError("Please provide a callback function or canvas to snap()")); 45175 45176 // if we have an active preview freeze, use that 45177 if (this.preview_active) { 45178 this.savePreview( user_callback, user_canvas ); 45179 return null; 45180 } 45181 45182 // create offscreen canvas element to hold pixels 45183 var canvas = document.createElement('canvas'); 45184 canvas.width = this.params.dest_width; 45185 canvas.height = this.params.dest_height; 45186 var context = canvas.getContext('2d'); 45187 45188 // flip canvas horizontally if desired 45189 if (this.params.flip_horiz) { 45190 context.translate( params.dest_width, 0 ); 45191 context.scale( -1, 1 ); 45192 } 45193 45194 // create inline function, called after image load (flash) or immediately (native) 45195 var func = function() { 45196 // render image if needed (flash) 45197 if (this.src && this.width && this.height) { 45198 context.drawImage(this, 0, 0, params.dest_width, params.dest_height); 45199 } 45200 45201 // crop if desired 45202 if (params.crop_width && params.crop_height) { 45203 var crop_canvas = document.createElement('canvas'); 45204 crop_canvas.width = params.crop_width; 45205 crop_canvas.height = params.crop_height; 45206 var crop_context = crop_canvas.getContext('2d'); 45207 45208 crop_context.drawImage( canvas, 45209 Math.floor( (params.dest_width / 2) - (params.crop_width / 2) ), 45210 Math.floor( (params.dest_height / 2) - (params.crop_height / 2) ), 45211 params.crop_width, 45212 params.crop_height, 45213 0, 45214 0, 45215 params.crop_width, 45216 params.crop_height 45217 ); 45218 45219 // swap canvases 45220 context = crop_context; 45221 canvas = crop_canvas; 45222 } 45223 45224 // render to user canvas if desired 45225 if (user_canvas) { 45226 var user_context = user_canvas.getContext('2d'); 45227 user_context.drawImage( canvas, 0, 0 ); 45228 } 45229 45230 // fire user callback if desired 45231 user_callback( 45232 user_canvas ? null : canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100 ), 45233 canvas, 45234 context 45235 ); 45236 }; 45237 45238 // grab image frame from userMedia or flash movie 45239 if (this.userMedia) { 45240 // native implementation 45241 context.drawImage(this.video, 0, 0, this.params.dest_width, this.params.dest_height); 45242 45243 // fire callback right away 45244 func(); 45245 } 45246 else if (this.iOS) { 45247 var div = document.getElementById(this.container.id+'-ios_div'); 45248 var img = document.getElementById(this.container.id+'-ios_img'); 45249 var input = document.getElementById(this.container.id+'-ios_input'); 45250 // function for handle snapshot event (call user_callback and reset the interface) 45251 iFunc = function(event) { 45252 func.call(img); 45253 img.removeEventListener('load', iFunc); 45254 div.style.backgroundImage = 'none'; 45255 img.removeAttribute('src'); 45256 input.value = null; 45257 }; 45258 if (!input.value) { 45259 // No image selected yet, activate input field 45260 img.addEventListener('load', iFunc); 45261 input.style.display = 'block'; 45262 input.focus(); 45263 input.click(); 45264 input.style.display = 'none'; 45265 } else { 45266 // Image already selected 45267 iFunc(null); 45268 } 45269 } 45270 else { 45271 // flash fallback 45272 var raw_data = this.getMovie()._snap(); 45273 45274 // render to image, fire callback when complete 45275 var img = new Image(); 45276 img.onload = func; 45277 img.src = 'data:image/'+this.params.image_format+';base64,' + raw_data; 45278 } 45279 45280 return null; 45281 }, 45282 45283 configure: function(panel) { 45284 // open flash configuration panel -- specify tab name: 45285 // "camera", "privacy", "default", "localStorage", "microphone", "settingsManager" 45286 if (!panel) panel = "camera"; 45287 this.getMovie()._configure(panel); 45288 }, 45289 45290 flashNotify: function(type, msg) { 45291 // receive notification from flash about event 45292 switch (type) { 45293 case 'flashLoadComplete': 45294 // movie loaded successfully 45295 this.loaded = true; 45296 this.dispatch('load'); 45297 break; 45298 45299 case 'cameraLive': 45300 // camera is live and ready to snap 45301 this.live = true; 45302 this.dispatch('live'); 45303 break; 45304 45305 case 'error': 45306 // Flash error 45307 this.dispatch('error', new FlashError(msg)); 45308 break; 45309 45310 default: 45311 // catch-all event, just in case 45312 // console.log("webcam flash_notify: " + type + ": " + msg); 45313 break; 45314 } 45315 }, 45316 45317 b64ToUint6: function(nChr) { 45318 // convert base64 encoded character to 6-bit integer 45319 // from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding 45320 return nChr > 64 && nChr < 91 ? nChr - 65 45321 : nChr > 96 && nChr < 123 ? nChr - 71 45322 : nChr > 47 && nChr < 58 ? nChr + 4 45323 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0; 45324 }, 45325 45326 base64DecToArr: function(sBase64, nBlocksSize) { 45327 // convert base64 encoded string to Uintarray 45328 // from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding 45329 var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, 45330 nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, 45331 taBytes = new Uint8Array(nOutLen); 45332 45333 for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { 45334 nMod4 = nInIdx & 3; 45335 nUint24 |= this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; 45336 if (nMod4 === 3 || nInLen - nInIdx === 1) { 45337 for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { 45338 taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; 45339 } 45340 nUint24 = 0; 45341 } 45342 } 45343 return taBytes; 45344 }, 45345 45346 upload: function(image_data_uri, target_url, callback) { 45347 // submit image data to server using binary AJAX 45348 var form_elem_name = this.params.upload_name || 'webcam'; 45349 45350 // detect image format from within image_data_uri 45351 var image_fmt = ''; 45352 if (image_data_uri.match(/^data\:image\/(\w+)/)) 45353 image_fmt = RegExp.$1; 45354 else 45355 throw "Cannot locate image format in Data URI"; 45356 45357 // extract raw base64 data from Data URI 45358 var raw_image_data = image_data_uri.replace(/^data\:image\/\w+\;base64\,/, ''); 45359 45360 // contruct use AJAX object 45361 var http = new XMLHttpRequest(); 45362 http.open("POST", target_url, true); 45363 45364 // setup progress events 45365 if (http.upload && http.upload.addEventListener) { 45366 http.upload.addEventListener( 'progress', function(e) { 45367 if (e.lengthComputable) { 45368 var progress = e.loaded / e.total; 45369 Webcam.dispatch('uploadProgress', progress, e); 45370 } 45371 }, false ); 45372 } 45373 45374 // completion handler 45375 var self = this; 45376 http.onload = function() { 45377 if (callback) callback.apply( self, [http.status, http.responseText, http.statusText] ); 45378 Webcam.dispatch('uploadComplete', http.status, http.responseText, http.statusText); 45379 }; 45380 45381 // create a blob and decode our base64 to binary 45382 var blob = new Blob( [ this.base64DecToArr(raw_image_data) ], {type: 'image/'+image_fmt} ); 45383 45384 // stuff into a form, so servers can easily receive it as a standard file upload 45385 var form = new FormData(); 45386 form.append( form_elem_name, blob, form_elem_name+"."+image_fmt.replace(/e/, '') ); 45387 45388 // send data to server 45389 http.send(form); 45390 } 45391 45392}; 45393 45394Webcam.init(); 45395 45396if (typeof define === 'function' && define.amd) { 45397 define( function() { return Webcam; } ); 45398} 45399else if (typeof module === 'object' && module.exports) { 45400 module.exports = Webcam; 45401} 45402else { 45403 window.Webcam = Webcam; 45404} 45405 45406}(window));
45407// ========= 45408// = Alert = 45409// ========= 45410 45411$(document).ready(function() { 45412 45413 if ($('.conditions-alert--sticky').length > 0) { 45414 if($.cookie('conditions-alert') === null || $.cookie('conditions-alert') < $('.conditions-alert').data('updated')) { 45415 $('.conditions-alert--sticky').addClass('conditions-alert--active'); 45416 } 45417 45418 $('.js-conditions-alert-close').on('click', function() { 45419 $('#site_wide_alert').slideUp(300); 45420 $.cookie('conditions-alert', $('.conditions-alert').data('updated'), { expires: 1 }); 45421 }); 45422 } 45423}); 45424$(document).ready(function () { 45425 45426 // Check if function exists before calling. 45427 if (typeof $.fn.viewportChecker !== 'undefined' && $.isFunction($.fn.viewportChecker)) { 45428 $('.ac:not(.ac-once)').viewportChecker({ 45429 offset: 0, 45430 repeat: false, 45431 }); 45432 }; 45433 45434}); 45435function set_pass_balance(element){ 45436 pass_no = element.data('pass-no') 45437 $.ajax({ 45438 url: '/gift_cards/' + pass_no, 45439 type: 'get', 45440 dataType: 'json', 45441 success: function(data) { 45442 //processResponse(data); 45443 if (data.status == "success") { 45444 element.text("$" + data.balance) 45445 element.parents('.pass_info').find('.account_reload_link').show() 45446 if (data.voided) 45447 element.parents('.pass_info').find('.pass_info-voided').removeClass('hide'); 45448 }else{ 45449 element.text("$0.00") 45450 } 45451 }, 45452 error: function(data) { 45453 return "" 45454 } 45455 }); 45456} 45457 45458// $(document).ready(function(){ 45459 45460// $('span.pass-balance').each(function() { 45461// set_pass_balance($(this)); 45462// }); 45463 45464// }); 45465 45466$(document).ready(function(){ 45467 function add_cc_requirement() { 45468 $('#cc_number').rules("add",{required: true}); 45469 $('#cc_expiry_month').rules("add",{creditcardexpirymonth: true}); 45470 $('#cc_expiry_year').rules("add",{creditcardexpiryyear: true}); 45471 $('#cc_cvv').rules("add",{required: true}); 45472 } 45473 45474 function remove_cc_requirement() { 45475 $('#cc_number').rules("remove","required"); 45476 $('#cc_expiry_month').rules("remove","creditcardexpirymonth"); 45477 $('#cc_expiry_year').rules("remove","creditcardexpiryyear"); 45478 $('#cc_cvv').rules("remove","required"); 45479 } 45480 45481 function checkGiftCard() { 45482 if ($('#cart_giftcard').length > 0 && $('#cart_giftcard').val() !== '') { 45483 $('.giftcard.collapsible-form-item, #apply-giftcard').click(); 45484 } else { 45485 // Open Credit Card form if collapsed 45486 if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-plus')) { 45487 $('.creditcard.collapsible-form-item').click(); 45488 } 45489 } 45490 } 45491 45492 $('#apply-promocode').click(function(event) { 45493 event.preventDefault(); 45494 $('#apply-promocode').text('Validating..').addClass('disabled'); 45495 $.post('/cart/promocode', $('#cart_promocode').serialize(), function(result) { 45496 $('#apply-promocode').text('Apply').removeClass('disabled'); 45497 if (result.cart_totals) { 45498 $('.cart__totals').replaceWith(result.cart_totals); 45499 } 45500 if (result.cart_items && $('.cart__items').length > 0) { 45501 $('.cart__items').replaceWith(result.cart_items); 45502 } 45503 if (result.status == 'ok') { 45504 // yay, let's tell the user all is good! 45505 alert('Promo code has been successfully applied!'); 45506 checkGiftCard(); 45507 } 45508 else { 45509 // failed to apply promocode, let the user know 45510 alert("Sorry, couldn't find this promocode, please check your spelling."); 45511 } 45512 if (result.status) { 45513 $('input[name="cart[promocode]"]').val(result.promocode); 45514 $("p.promocode-message").text(result.message); 45515 } 45516 }); 45517 }); 45518 45519 $('#validate-bin').click(function(event) { 45520 event.preventDefault(); 45521 $('#validate-bin').text('Validating..').addClass('disabled'); 45522 $.post('/cart/validate_bin', {bin: $('#cc_number').val().slice(0,6)}, function(result) { 45523 45524 if (result.cart_totals) { 45525 $('.cart__totals').replaceWith(result.cart_totals); 45526 } 45527 if (result.cart_items && $('.cart__items').length > 0) { 45528 $('.cart__items').replaceWith(result.cart_items); 45529 } 45530 if (result.status == 'ok') { 45531 $("#validation-return-message").html('Your RBC Avion® Visa® has been verified.<br>Your Friday Friend Pass offer has been applied below.'); 45532 $("#cc_number").prop("readonly", true) 45533 } 45534 else { 45535 $("#validation-return-message").html('Error: Card not eligible for the BOGO promotion.'); 45536 $("#cc_number").removeProp("readonly") 45537 } 45538 if (result.status) { 45539 $('input[name="cart[promocode]"]').val(result.promocode); 45540 $('#validate-bin').text('Validate card').removeClass('disabled'); 45541 } 45542 }); 45543 }); 45544 45545 $('#apply-giftcard').click(function(event) { 45546 event.preventDefault(); 45547 $('.form-item--giftcard .form-item-message').hide(); 45548 $('.form-item--giftcard #giftcard-current-balance').hide(); 45549 $('#apply-giftcard').text('Validating..').addClass('disabled'); 45550 $.post('/cart/giftcard', $('#cart_giftcard').serialize(), function(result) { 45551 $('#apply-giftcard').text('Apply').removeClass('disabled'); 45552 if (result.status == "ok") { 45553 // Collapse Credit Card form if open 45554 if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-minus')) { 45555 $('.creditcard.collapsible-form-item').click(); 45556 }
45557 remove_cc_requirement(); 45558 } else { 45559 // Open Credit Card form if collapsed 45560 if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-plus')) { 45561 $('.creditcard.collapsible-form-item').click(); 45562 } 45563 add_cc_requirement(); 45564 } 45565 if (result.cart_totals) { 45566 $('.cart__totals').replaceWith(result.cart_totals); 45567 } 45568 $('.form-item--giftcard .form-item-message').text(result.message).css('display', 'block'); 45569 if (result.current_balance !== null) { 45570 $('.form-item--giftcard #giftcard-current-balance').text("Current Balance: $"+result.current_balance).css('display', 'block'); 45571 } 45572 }); 45573 }); 45574 45575 // Init 45576 checkGiftCard(); 45577}); 45578function calc_subtotal(with_activities) { 45579 with_activities = with_activities || false; 45580 var t=0.00; 45581 $('.buy_area select.price-select').each(function(){ 45582 var itm_price = $(this).find('option[value='+$(this).val()+']').attr('data-price') 45583 $(this).closest('tr.item_info').attr('data-price', itm_price); 45584 }); 45585 $('.buy_area tr.item_info, .buy_area .item_info').each(function(){ 45586 qty = parseInt($(this).find('.qty').val()); 45587 t = t + ( $(this).attr('data-price') * qty ); 45588 // Global activities 45589 $('.product_activities').find('.activities option[value!=""]:selected').each(function() { 45590 t = t + parseFloat($(this).attr('data-price') * qty ); 45591 }); 45592 }); 45593 // Activities by item 45594 $('.activities:not(.single-activity) option[value!=""]:selected, .admission_mods .form-item[data-item-index] input:checked').each(function() { 45595 var act_price = parseFloat($(this).attr('data-price')); 45596 if (!isNaN(act_price)) 45597 t = t + act_price; 45598 }); 45599 45600 return t; 45601} 45602 45603function item_quantity(item) { 45604 q = $('.item_info[data-item-id="'+item+'"]').find('.qty'); 45605 return (parseInt(q.val()) * q.closest('.item_info').data('for-n-users')); 45606} 45607 45608function total_quantity() { 45609 var q=0; 45610 $('.buy_area .qty').each(function(){ 45611 q = q + (parseInt($(this).val()) * $(this).closest('.item_info').data('for-n-users')); 45612 }); 45613 return q; 45614} 45615 45616function activity_claimed_quantity(activity_dci) { 45617 selected_activities = $('[data-dci="'+activity_dci+'"]:selected'); 45618 var q = 0 45619 selected_activities.each(function(){ 45620 q = q + $(this).data('for-n-users'); 45621 }); 45622 45623 return q; 45624} 45625 45626function activity_claimed_quantities() { 45627 selected_activities = {}; 45628 $('option[data-dci][value!=""]:selected').each(function(){ 45629 if (selected_activities[$(this).attr('data-dci')] === undefined) selected_activities[$(this).attr('data-dci')] = 0; 45630 selected_activities[$(this).attr('data-dci')] += $(this).data('for-n-users'); 45631 }); 45632 return selected_activities; 45633} 45634 45635function lock_buy_area() { 45636 $(".buy_area").addClass('muted'); 45637 $('.buy_area .tally').addClass('muted'); 45638 $('ul.times').addClass("loading"); 45639 // $('.buy_area select, .buy_area input, .buy_area button[type="submit"]').not("#local_postal_code").prop('disabled', true); 45640} 45641 45642function unlock_buy_area(item) { 45643 $(".buy_area").removeClass('muted'); 45644 $('ul.times').removeClass("loading"); 45645 if (!is_single_activity() || (is_single_activity() && $('.product__step-last').is(":visible"))) { 45646 $('.buy_area .tally').removeClass('muted'); 45647 } 45648 45649 45650 if ($('#product_buy_area').data('product-type') == 'scheduled_activity') { 45651 // $('.buy_area select, .buy_area input').removeAttr('disabled'); 45652 $('.buy_area tr.item_info td').removeClass('text-muted muted'); 45653 45654 if ( $('#product_buy_area').data('item-level-availability') == true && item != false && total_quantity() != 0 ) { 45655 selected_row = $('[data-item-id="'+item+'"]'); 45656 var siblings = selected_row.siblings('.item_info'); 45657 var siblings_qty_selects = siblings.find('.qty'); 45658 // siblings_qty_selects.attr('disabled','disabled') 45659 siblings.find('td').addClass('text-muted muted'); 45660 } 45661 } 45662} 45663 45664function hide_activities(activities) { 45665 activities.find('li[class!="item_benefit"], .savings_info').removeClass('visible').slideUp(); 45666 activities.find('.modifier_group').each(function(){ 45667 hide_modifier_group($(this)); 45668 }); 45669 activities.removeClass('open'); 45670} 45671 45672function hide_modifier_group(modifier_group) { 45673 group_activities = modifier_group.next('.modifier_group__list'); 45674 group_activities.find('select').val(""); 45675 if (group_activities.is(":visible")) { 45676 modifier_group.click(); 45677 } 45678 modifier_group.removeClass('visible').slideUp(); 45679} 45680 45681var currentPriceRequest = null; 45682 45683function get_sw_subtotal() { 45684 form = $('#edit_cart, #new_cart').first().serializeArray(); 45685 currentPriceRequest = $.ajax({ 45686 url: "/cart_items/get_items_price", 45687 type: 'POST', 45688 dataType: 'json', 45689 cache: true, 45690 data: form, 45691 beforeSend : function() { 45692 if(currentPriceRequest != null) { 45693 currentPriceRequest.abort(); 45694 } 45695 }, 45696 success: function(data) { 45697 var subtotal = calc_subtotal(true); 45698 if (data.price < subtotal) 45699 $('.running_total_without_discount').text(subtotal).formatCurrency().removeClass('hide'); 45700 $('.running_total').text("$"+data.price); 45701 }, 45702 error: function(data) { 45703 console.log('Failed to get items price'); 45704 }, 45705 complete: function() { 45706 $('.running_total').removeClass('loading'); 45707 } 45708 }); 45709} 45710 45711 45712function is_single_activity() { 45713 return ($('.single-activity').length > 0); 45714} 45715 45716function tram_times_present() { 45717 return ($(".tram-times").length > 0); 45718} 45719 45720function tram_times_required(date) { 45721 if (typeof date === 'string') 45722 date = Date.parseString(date); 45723 var start = $(".tram-times").data('activity-start-date') 45724 var end = $(".tram-times").data('activity-end-date') 45725 var days = $(".tram-times").data('activity-days'); 45726 var blackouts = $(".tram-times").data('blackouts'); 45727 45728 return activityDateAvailable(date, start, end, days, blackouts) 45729} 45730 45731function tram_times_required_highlight_datepicker() { 45732 return $(".tram-times").data('highlight-required-days'); 45733} 45734 45735function tram_times_required_highlight_datepicker_reference() { 45736 if (tram_times_required_highlight_datepicker()) { 45737 setTimeout(function() { 45738 var wrapper = $('.ui-datepicker-tram-times-required-reference-wrapper'); 45739 if (wrapper.length == 0) {
45740 wrapper = $('<div class="ui-datepicker-tram-times-required-reference-wrapper"><span class="ui-datepicker-tram-times-required-reference"></span> Requires Skyride booking.</div>'); 45741 } 45742 $('#ui-datepicker-div').append(wrapper); 45743 }, 0); 45744 } 45745} 45746 45747 45748function toggle_tram_times(date) { 45749 var req = tram_times_required(date); 45750 $(".tram-times").closest('.product__step').toggleClass('hide', !req); 45751 $('.product__step.tram-times__not-required').toggleClass('hide', req); 45752 $('.button.book-now').toggleClass('hide', !req); 45753 45754} 45755 45756function is_passholders_load_times() { 45757 return ($('.passholders-load-times').length > 0); 45758} 45759 45760function should_get_sw_subtotal() { 45761 // Always calculate price if product type is Bundled 45762 return $('#product_buy_area').data('product-type') == "scheduled_activity" || ($('#product_buy_area').data('product-type') == "bundled" && !is_passholders_load_times()); 45763 45764 // TEMPORARILY DEPRECATED 45765 //----------------------- 45766 // The logic below used to check if there's any selected activity 45767 // to then trigger a price calculation. Since items pricing rules can 45768 // now affect the price of the parent item, priciung must always be calculated 45769 //----------------------- 45770 45771 // checked_items_activities = false; 45772 // $('.item_activities').each(function(){ 45773 // item = $(this).data('item-id'); 45774 // if (item_quantity(item) > 0 && $(this).find('input:checked').length > 0) { 45775 // checked_items_activities = true; 45776 // } 45777 // }) 45778 45779 // checked_product_activities = ($('.product_activities input:checked').length > 0 && total_quantity() > 0); 45780 45781 // return checked_items_activities || checked_product_activities; 45782} 45783 45784function loading_running_totals() { 45785 if (should_get_sw_subtotal()) $('#product_buy_area .running_total').text('').addClass('loading'); 45786 $('#product_buy_area .running_total_without_discount').text('').addClass('hide'); 45787} 45788 45789function quick_checkout_check() { 45790 var activities_check = $('.activities [data-item-id][data-item-index] option[data-personal-info-required=1]:selected').length == 0; 45791 var trams_check = $('.tram-time:not(.tram-time--template) option[data-personal-info-required=1]:selected').length == 0; 45792 var items_check = true; 45793 $('#product_buy_area .item_info[data-personal-info-required=1] .qty').each(function() { 45794 if ($(this).val() > 0) { 45795 items_check = false; 45796 } 45797 }); 45798 45799 if (is_single_activity()) { 45800 45801 } 45802 45803 if (activities_check && items_check && trams_check) { 45804 toggle_quick_checkout_button('show'); 45805 } else { 45806 toggle_quick_checkout_button('hide'); 45807 } 45808} 45809 45810function toggle_quick_checkout_button(action) { 45811 if (action == 'show') { 45812 $('.quick-checkout-divider').removeClass('hidden'); 45813 $('#cart_submit_quick_checkout').removeClass('hidden'); 45814 } else { 45815 $('.quick-checkout-divider').addClass('hidden'); 45816 $('#cart_submit_quick_checkout').addClass('hidden'); 45817 } 45818 45819} 45820 45821function set_items_prices(date) { 45822 var product_id = $('#product_buy_area').data('product-id'); 45823 lock_buy_area(); 45824 $('.item_info .price').addClass('loading'); 45825 45826 var url = '/products/'+product_id+'/items_prices?date='+date; 45827 45828 if (is_single_activity()) { 45829 // If single activity, send the current mod group in order to get a bundled price 45830 // and get admission ticket prices as a separate item, 45831 // in order to handle activity bookings with or without ticket 45832 var item_modifier_group_id = $('#product_buy_area').data('item-modifier-group-id'); 45833 if (item_modifier_group_id) url = url+'&item_modifier_group_id='+item_modifier_group_id; 45834 url = url+'&include_admission_mods_as_items=true'; 45835 } else { 45836 // ...otherwise, bundle the admission ticket price with the parent items 45837 url = url+'&bundle_admission_mods=true'; 45838 } 45839 45840 $.ajax({ 45841 url: url, 45842 type: 'GET', 45843 dataType: 'json', 45844 data: '', 45845 success: function(data) { 45846 $.each(data, function(k, v){ 45847 var item = $('.item_info[data-item-id="'+v.item_id+'"]'); 45848 if (item.length > 0) { 45849 // It's an item price 45850 item.attr('data-price', v.price); 45851 item.find('td.price').text(v.price); 45852 } else { 45853 // It's an admission mod item price 45854 $('.admission_mods .form-item input[value="'+v.item_id+'"]').attr('data-price', v.price); 45855 } 45856 }); 45857 unlock_buy_area(false) 45858 $('.item_info .price').removeClass('loading'); 45859 }, 45860 error: function(data) { 45861 }, 45862 complete: function() { 45863 45864 unlock_buy_area(false); 45865 $('.item_info .price').removeClass('loading'); 45866 } 45867 }); 45868} 45869 45870function get_item(item_id) { 45871 return $('tr.item_info[data-item-id="'+item_id+'"]'); 45872} 45873 45874function get_item_quantity(item_id) { 45875 return get_item(item_id).find('.qty').val(); 45876} 45877 45878function get_item_activities(item_id) { 45879 return $('tr.item_activities[data-item-id="'+item_id+'"]'); 45880} 45881 45882function get_item_activities_list(item_id) { 45883 return get_item_activities(item_id).find('.activities'); 45884} 45885 45886 45887function toggle_single_activity_list(item_id, action) { 45888 var item_activities = get_item_activities(item_id) || $(document); 45889 var list = item_activities.find('.single-activity .modifier_group__list'); 45890 list.toggleClass('hide', (action !== 'show')); 45891} 45892 45893 45894var availability_cache = {}; 45895var availability_cache_expires_at = {}; 45896function show_available_activities(date, item_id, dci_codes) { 45897 45898 item_id = item_id || false; 45899 dci_codes = dci_codes || false; 45900 45901 lock_buy_area(); 45902 loading_running_totals(); 45903 45904 $(".loading_activities_error, .loading_activities_not_available, .checking_availability_error").addClass('hide'); 45905 45906 45907 if ( total_quantity() == 0 ) { 45908 toggle_single_activity_list(null, 'hide'); 45909 hide_activities($('.activities')); 45910 $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency(); 45911 if ($('#activity_date').val() != "") { 45912 unlock_buy_area(false); 45913 } 45914 45915 } else { 45916 45917 var product_id = $('#product_buy_area').data('product-id'); 45918 45919 var url = '/products/'+product_id+'/max_available?date='+date; 45920 45921 if (item_id) { 45922 var item_activities = get_item_activities_list(item_id); 45923 if (item_quantity(item_id) == 0 ) { 45924 toggle_single_activity_list(item_id, 'hide') 45925 hide_activities(item_activities); 45926 } else { 45927 if (!item_activities.hasClass('open')) { 45928 item_activities.siblings('.loading_activities').removeClass('hide'); 45929 } 45930 } 45931 url += '&item_id=' + item_id; 45932 } else { 45933 $('.activities.open').each(function(){ 45934 $(this).siblings('.loading_activities').removeClass('hide'); 45935 }); 45936 } 45937 45938 if (tram_times_present()) 45939 $(".tram-times").siblings('.loading_activities').removeClass('hide'); 45940 45941 45942 if (dci_codes.length > 0) url += '&dci_codes=' + dci_codes.join(','); 45943 45944 if (availability_cache[url]!==undefined && $.now() < availability_cache_expires_at[url]) { 45945 apply_availability_changes(availability_cache[url], item_id); 45946 } else { 45947 if (date) { 45948 $.ajax({ 45949 url: url, 45950 type: 'GET', 45951 dataType: 'json', 45952 data: '', 45953 success: function(data) { 45954 availability_cache[url] = data; 45955 availability_cache_expires_at[url] = $.now() + 60000; // 1 minute cache life 45956 apply_availability_changes(data, item_id); 45957 }, 45958 error: function(data) { 45959 if (item_id && item_activities.length > 0) 45960 if (dci_codes.length > 0) { 45961 for (var i = 0; i < dci_codes.length; i++) { 45962 item_activities.find('option[data-dci="'+dci_codes[i]+'"]').closest('select').val(''); 45963 item_activities.find('option[data-dci="'+dci_codes[i]+'"]').closest('select').siblings('.checking_availability_error').removeClass('hide'); 45964 } 45965 } else { 45966 item_activities.siblings(".loading_activities_error").removeClass('hide'); 45967 } 45968 after_show_available_activities(item_id); 45969 console.log('Failed to check availability'); 45970 45971 } 45972 }); 45973 } 45974 } 45975 } // end if quanity 0 45976} 45977 45978function apply_availability_changes(data, item_id) { 45979 unlock_buy_area(false) 45980 var activities = null; 45981 var claimed_qties = activity_claimed_quantities(); 45982 var rem_qties = {}; 45983 if (data !== null) { 45984 $.each(data, function(dci, entry) { 45985 // Keep track of remaining qties by DCI for further adjustments
45986 if (rem_qties[dci]===undefined) rem_qties[dci] = 0; 45987 rem_qties[dci] += parseInt(entry.qty_rem); 45988 45989 activity = $('.activities .form-item--template option[data-dci="'+dci+'"]'); 45990 if (activity.length > 0) { 45991 for (var j = 0; j < activity.length; j++) { 45992 this_activity = $(activity[j]); 45993 claimed_qty = claimed_qties[dci] || 0; 45994 this_activity.toggleClass('visible', (entry.qty_rem - claimed_qty >= this_activity.data('for-n-users'))); 45995 } 45996 } 45997 45998 tram_time = $('.tram-times .form-item option[data-dci="'+dci+'"]'); 45999 if (tram_time.length > 0) { 46000 for (var j = 0; j < tram_time.length; j++) { 46001 this_tram_time = $(tram_time[j]); 46002 this_tram_time.toggleClass('visible', entry.qty_rem >= total_quantity()); 46003 } 46004 } 46005 }); 46006 46007 $('.activities .form-item--template').each(function(){ 46008 template = $(this); 46009 is_single_activity = ($(this).closest('.single-activity').length > 0); 46010 template.siblings('.form-item[data-item-id="'+template.attr('data-item-id')+'"][data-item-index]').find('select').each(function(i, el){ 46011 select = $(el); 46012 selected_value = select.val(); 46013 options_selector = 'select option[value=""], select option.visible'; 46014 // if (item_id) { 46015 options_selector = options_selector + ', select option[value="'+selected_value+'"]'; 46016 // } 46017 options = template.find(options_selector).clone(); 46018 select.empty().append(options); 46019 if (select.find('option[value="'+selected_value+'"]').length > 0) { 46020 select.val(selected_value); 46021 } else { 46022 select.val(""); 46023 populate_modifier_ids(); 46024 } 46025 // For single activities, if only one value available, select it 46026 if (is_single_activity) { 46027 // Find if there's only one option available 46028 only_option = template.find('select option.visible[value!=""]'); 46029 if (selected_value == "" && only_option.length == 1) { 46030 only_option_dci = only_option.data('dci'); 46031 // Make sure claimed_qties object has a value for this DCI 46032 if (claimed_qties[only_option_dci]===undefined) claimed_qties[only_option_dci] = 0; 46033 // Check if there's availability left before selecting the only option 46034 if (rem_qties[only_option_dci] - claimed_qties[only_option_dci] >= only_option.data('for-n-users')) { 46035 // Select only option and increase claimed qty 46036 select.val(only_option.val()); 46037 claimed_qties[only_option_dci] += parseInt(only_option.data('for-n-users')); 46038 populate_modifier_ids(); 46039 set_step_2_select_state(); 46040 } else { 46041 // Remove option if no longer available 46042 select.find('option[value="'+only_option.val()+'"]').remove(); 46043 } 46044 } 46045 } 46046 }); 46047 }); 46048 activities = $('.activities'); 46049 46050 46051 $('.tram-times .tram-time--template').each(function(){ 46052 template = $(this); 46053 template.siblings('.tram-time').find('select').each(function(i, el){ 46054 select = $(el); 46055 selected_value = select.val(); 46056 options_selector = 'select option[value=""], select option'; 46057 options = template.find(options_selector).clone(); 46058 select.empty().append(options); 46059 // For tram times, sold out items show up disabled 46060 select.find('option:not(.visible)[value!=""]').attr("disabled", "disabled").append($("<span> (SOLD OUT)</span>")); 46061 if (select.find('option[value="'+selected_value+'"]').length > 0) { 46062 select.val(selected_value); 46063 } else { 46064 select.val(""); 46065 // populate_modifier_ids(); 46066 } 46067 }); 46068 }); 46069 } 46070 46071 if (activities.length > 0) { 46072 var this_item_id, is_single_activity, open_activities; 46073 activities.each(function(i, activity) { 46074 this_item_id = $(activity).closest('tr.item_activities').attr('data-item-id'); 46075 is_single_activity = $(activity).hasClass('single-activity'); 46076 open_activities = false 46077 $(activity).find('.modifier_group').each(function() { 46078 group_name = $(this).attr('data-group'); 46079 list = $(this).next('.modifier_group__list').first(); 46080 if (list.find('.form-item[data-item-index] option[data-group="'+group_name+'"]').length > 0) { 46081 if (is_single_activity && (!item_id || item_id == this_item_id)) { 46082 toggle_single_activity_list(this_item_id, 'show'); 46083 } 46084 $(this).slideDown(); 46085 open_activities = true 46086 } else { 46087 if (is_single_activity && (!item_id || item_id == this_item_id)) { 46088 toggle_single_activity_list(this_item_id, 'hide'); 46089 if (get_item_quantity(this_item_id) > 0) 46090 get_item_activities_list(this_item_id).siblings(".loading_activities_not_available").removeClass('hide'); 46091 } 46092 hide_modifier_group($(this)); 46093 } 46094 }); 46095 46096 if (open_activities) { 46097 $(this).find('.savings_info').slideDown(); 46098 $(this).addClass('open'); 46099 } else {
46100 $(this).find('.savings_info').slideUp(); 46101 $(this).removeClass('open'); 46102 } 46103 }); 46104 } 46105 46106 after_show_available_activities(item_id); 46107 46108 if (should_get_sw_subtotal()) { 46109 get_sw_subtotal(); 46110 } else { 46111 $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency(); 46112 } 46113 46114 quick_checkout_check(); 46115} 46116 46117function after_show_available_activities(item_id) { 46118 unlock_buy_area(false); 46119 item_activities = get_item_activities(item_id); 46120 // Remove activities loader 46121 if (item_activities.length > 0) 46122 item_activities.find('.loading_activities').addClass('hide'); 46123 else 46124 $('.loading_activities').addClass('hide'); 46125 46126 // Remove availability loader 46127 $('.activities select').removeClass('loading'); 46128 $('.tram-time select').removeClass('loading'); 46129 $('.checking_availability').addClass('hide'); 46130} 46131 46132function show_available_times(date, item) { 46133 46134 default_message = "Please select a quantity above."; 46135 if ($('.option.time').data('user-selectable-date') == true) { 46136 default_message = "Please select a date and a quantity above."; 46137 } 46138 46139 item = item || false; 46140 46141 if ( total_quantity() == 0 ) { 46142 $('ul.times li').slideUp(); 46143 $('ul.times input').prop('checked',false); 46144 $('#message').text(default_message).slideDown(); 46145 $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency(); 46146 unlock_buy_area(item) 46147 } else { 46148 46149 var product_id = $('#product_buy_area').data('product-id'); 46150 lock_buy_area(); 46151 loading_running_totals(); 46152 $('#message').slideUp(); 46153 46154 var url = '/products/'+product_id+'/max_available?date='+date; 46155 46156 if (item) { 46157 url += '&item_id=' + item; 46158 } 46159 46160 $.ajax({ 46161 url: url, 46162 type: 'GET', 46163 dataType: 'json', 46164 data: '', 46165 success: function(data) { 46166 unlock_buy_area(item); 46167 var most_avail = 0; 46168 $.each(data, function(dci, entry) { 46169 if (entry.qty_rem >= total_quantity() && entry.qty_rem != 0) { 46170 $('li[data-dci="'+dci+'"]').slideDown() 46171 } else { 46172 $('li[data-dci="'+dci+'"] input').prop('checked',false); 46173 $('li[data-dci="'+dci+'"]').slideUp(); 46174 } 46175 if (entry.qty_rem > most_avail) { 46176 most_avail = entry.qty_rem; 46177 } 46178 }); 46179 most_avail == 0 ? $('#message').text("Please try another date. We have no available times for this date.").show() : $('#none_available').hide(); 46180 most_avail < total_quantity() ? $('#message').text("Please try another date. There are no remaining times with "+total_quantity()+" available spaces for this day.").show() : $('#none_available').hide(); 46181 if (should_get_sw_subtotal()) { 46182 get_sw_subtotal(); 46183 } else { 46184 $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency(); 46185 } 46186 }, 46187 error: function(data) { 46188 console.log('Failed to check availability'); 46189 46190 } 46191 }); 46192 } // end if quanity 0 46193} 46194 46195var benefits_quantities_cache = {}; 46196function show_available_benefits(date) { 46197 46198 if (!$('#product_buy_area').data('load-benefits')) return true; 46199 46200 var product_id = $('#product_buy_area').data('product-id'); 46201 var url = "/users/benefits?date="+date+"&product_id="+product_id; 46202 if (is_single_activity()) { 46203 var item_modifier_group_id = $('#product_buy_area').data('item-modifier-group-id'); 46204 url += "&item_modifier_group_id="+item_modifier_group_id 46205 } 46206 $.ajax({ 46207 url: url, 46208 type: 'GET', 46209 dataType: 'json', 46210 data: '', 46211 success: function(data) { 46212 if (data.items_partials) { 46213 $("tr.item_benefits").each(function(i, b) { 46214 var item_benefits = $(b); 46215 var item_id = item_benefits.data("itemId"); 46216 if (data.items_partials[item_id]) 46217 item_benefits.find("td").html(data.items_partials[item_id]); 46218 }); 46219 } 46220 46221 if (data.admission_partial) { 46222 $(".item_benefits.admission_mods-benefits").html(data.admission_partial) 46223 } 46224 46225 if (data.add_and_save_partial) { 46226 $(".activities .item_benefits").html(data.add_and_save_partial) 46227 } 46228 46229 benefits_quantities_cache = {}; 46230 $.each(data.data, function(i, b) { 46231 if (!benefits_quantities_cache[b.benefitid]) benefits_quantities_cache[b.benefitid] = { 46232 pass_nos: {} 46233 }; 46234 46235 benefits_quantities_cache[b.benefitid].pass_nos[b.pass_no] = { 46236 remaining_qty: b.remainingquantity, 46237 redeemed_qty: 0 46238 } 46239 }); 46240 46241 $(".item_benefits").each(function(i, b) { 46242 if ($(b).find('.item_benefit:not(.hide)').length == 0) { 46243 $(b).hide(); 46244 } else { 46245 $(b).show(); 46246 } 46247 }); 46248 } 46249 }); 46250} 46251 46252 46253function validate_product_form( $form ) { 46254 46255 $('#buy_area_messages li').remove(); 46256 $('#product_buy_area .error').removeClass('error'); 46257 46258 if ( total_quantity() == 0 ) { 46259 $('<li/>', { 46260 text: "Please select a least one item quantity." 46261 }).appendTo('#buy_area_messages'); 46262 $('select.qty').effect('shake', { distance: 4, times: 2 }, 100 ); 46263 } 46264 46265 if (tram_times_present()) { 46266 if (validate_tram_times_required()) { 46267 validate_tram_times_sequence(); 46268 } 46269 } 46270 46271 // scheduled activites 46272 if ( $('.dates').length > 0 ) { 46273 if ( $('.dates input').val() == '' ) { 46274 $('<li/>', { 46275 text: "Please select a date." 46276 }).appendTo('#buy_area_messages'); 46277 $('.dates').effect('shake', { distance: 4, times: 2 }, 100 ); 46278 } 46279 } 46280 46281 if ( $('ul.times').length > 0 ) { 46282 if ( $('ul.times input:checked').length == 0 ) { 46283 $('<li/>', { 46284 text: "Please select a time." 46285 }).appendTo('#buy_area_messages'); 46286 $('ul.times').effect('shake', { distance: 4, times: 2 }, 100 ); 46287 } 46288 } 46289 46290 // gift cards 46291 if ( $('ul.designs').length > 0 ) { 46292 if ( $('ul.designs input:checked').length == 0 ) { 46293 $('<li/>', { 46294 text: "Please select a design." 46295 }).appendTo('#buy_area_messages'); 46296 $('ul.designs').effect('shake', { distance: 4, times: 2 }, 100 ); 46297 } 46298 } 46299 46300 // gift card refill 46301 if ( $('.option.pass_no input').length > 0 ) { 46302 if ( $('.option.pass_no input').val() == "" ) { 46303 $('<li/>', { 46304 text: "Please enter a gift card or pass number." 46305 }).appendTo('#buy_area_messages'); 46306 $('.option.pass_no').effect('shake', { distance: 4, times: 2 }, 100 ); 46307 } 46308 } 46309 46310 // retail items 46311 if ( $('#item_option_id').length > 0 ) { 46312 if ( $('#item_option_id').val() == "" ) { 46313 $('<li/>', { 46314 text: "Please select a colour and size." 46315 }).appendTo('#buy_area_messages'); 46316 $('.option.size, .option.colour').effect('shake', { distance: 4, times: 2 }, 100 ); 46317 } 46318 } 46319 46320 if (toggle_buy_area_messages() === false) { 46321 return false;
46322 } 46323 46324 return true; 46325} 46326 46327function validate_activity_form( $form ) { 46328 46329 var messages_area = $form.find('.product__step-form__messages'); 46330 messages_area.find('li').remove(); 46331 46332 var empty_select = $form.find('.form-item[data-item-id][data-item-index] option[value=""]:selected').closest('select'); 46333 if ( empty_select.length > 0 ) { 46334 $('<li/>', { 46335 text: "Please select a least one option per Guest." 46336 }).appendTo(messages_area); 46337 empty_select.effect('shake', { distance: 4, times: 2 }, 100 ); 46338 } 46339 46340 if ( messages_area.find('li').length > 0) { 46341 messages_area.slideDown(); 46342 return false; 46343 } else { 46344 messages_area.slideUp(); 46345 } 46346 46347 return true; 46348} 46349 46350function validate_tram_times_required() { 46351 46352 if (!tram_times_required($("#activity_date").val())) return true; 46353 46354 var error = false; 46355 if (is_staff_pass()) { 46356 if (get_unselected_tram_times().length > 1) { 46357 error = true; 46358 message = "Please select a minimum of one boarding time."; 46359 } 46360 } else { 46361 if (get_unselected_tram_times().length > 0) { 46362 error = true; 46363 is_upload = $('.tram-time:not(.tram-time--template)[data-type=Upload]').length > 0 46364 is_download = $('.tram-time:not(.tram-time--template)[data-type=Download]').length > 0 46365 details = (is_upload && is_download) ? "upload and download boarding times." : (is_upload ? "upload boarding time." : "download boarding time."); 46366 message = "Please select "+details; 46367 if ($("#download_only").is(":checked")) 46368 message = "Please select download boarding time."; 46369 } 46370 } 46371 46372 if (error) { 46373 $('<li/>', { 46374 text: message 46375 }).appendTo('#buy_area_messages'); 46376 $('.tram-time select[name=mods]').effect('shake', { distance: 4, times: 2 }, 100); 46377 $('.tram-time:not(.tram-time--template)').addClass('error'); 46378 46379 return false; 46380 } else { 46381 return true; 46382 } 46383} 46384 46385function validate_tram_times_sequence() { 46386 46387 if (is_staff_pass()) return true; 46388 46389 if ($('.tram-time:not(.tram-time--template)[data-type=Upload]').length > 0 46390 && $('.tram-time:not(.tram-time--template)[data-type=Download]').length > 0) { 46391 var upload_time = $('.tram-time:not(.tram-time--template)[data-type=Upload] option:selected').data('starttime'); 46392 var download_time = $('.tram-time:not(.tram-time--template)[data-type=Download] option:selected').data('starttime'); 46393 if (upload_time >= download_time) { 46394 message = "Selected download time must later than selected upload time. Please revise your selections to proceed."; 46395 $('<li/>', { 46396 text: message 46397 }).appendTo('#buy_area_messages'); 46398 $('.tram-time select').effect('shake', { distance: 4, times: 2 }, 100 ); 46399 $('.tram-time:not(.tram-time--template)').addClass('error'); 46400 return false; 46401 } 46402 } 46403 return true; 46404} 46405 46406function is_staff_pass() { 46407 return $('.staff-pass').length > 0; 46408} 46409 46410function toggle_buy_area_messages() { 46411 if ( $('#buy_area_messages li').length > 0) { 46412 $('#buy_area_messages').slideDown(); 46413 return false; 46414 } else { 46415 $('#buy_area_messages').slideUp(); 46416 } 46417} 46418 46419/* 46420 Create all fields for a hidden cart item form 46421*/ 46422function create_cart_item_attributes_item(item_id, item_modifier_group_id, date) { 46423 var block = $('<div></div>'); 46424 var cart_form = $("#edit_cart, #new_cart").first(); 46425 var index = cart_form.find("[data-item-id="+item_id+"]").length; 46426 var global_index = -1; 46427 cart_form.find("[data-item-id]").each(function(){ 46428 this_index = parseInt($(this).attr('data-item-global-index')); 46429 if (this_index > global_index) 46430 global_index = this_index; 46431 }); 46432 46433 global_index++; 46434 46435 block.attr("data-item-id", item_id); 46436 block.attr("data-item-index", index); 46437 block.attr("data-item-global-index", global_index); 46438 46439 block.append(create_cart_item_attributes_input_field('hidden', 'item_id', item_id, global_index, false, {})); 46440 if (item_modifier_group_id !== undefined && item_modifier_group_id > 0) 46441 block.append(create_cart_item_attributes_input_field('hidden', 'item_modifier_group_id', item_modifier_group_id, global_index, false, {})); 46442 block.append(create_cart_item_attributes_input_field('hidden', 'date', date, global_index, false, {}));
46443 block.append(create_cart_item_attributes_input_field('hidden', 'add_to_quantity', "1", global_index, false, {})); 46444 block.append(create_cart_item_attributes_input_field('hidden', 'benefits', $("input[data-item-id="+item_id+"][type=checkbox][name*=benefit]:checked").val(), global_index, false, {})); 46445 cart_form.append(block); 46446} 46447 46448/* 46449 Create a hidden cart item form field 46450*/ 46451function create_cart_item_attributes_input_field(type, name, value, index, is_array, attributes) { 46452 var input = $('<input/>'); 46453 input.attr("type", type); 46454 input.attr("id", "cart_cart_items_attributes_"+index+"_"+name); 46455 input.attr("name", "cart[cart_items_attributes]["+index+"]["+name+"]"+(is_array ? "[]" : "")); 46456 input.attr("value", value); 46457 $.each(attributes, function(key, value){ 46458 input.attr(key, value); 46459 }); 46460 return input; 46461} 46462 46463 46464/* 46465 Look at the visible modifiers/guests fields values and populate 46466 the hidden cart items form values 46467*/ 46468function populate_modifier_ids() { 46469 var cart_form = $("#edit_cart, #new_cart").first(); 46470 cart_form.find('[data-item-id][data-item-index] [name$="[item_modifier_ids][]"]').remove(); 46471 $('.form-item[data-item-id][data-item-index]').each(function(){ 46472 cart_item = cart_form.find('[data-item-id="'+$(this).attr('data-item-id')+'"][data-item-index="'+$(this).attr('data-item-index')+'"]'); 46473 value = $(this).find('select, input:checked').val(); 46474 if (value !== undefined && cart_item.find('[name$="[item_modifier_ids][]"][value="'+value+'"]').length == 0) { 46475 cart_item.append(create_cart_item_attributes_input_field('hidden', 'item_modifier_ids', $(this).find('select, input:checked').val(), cart_item.attr('data-item-global-index'), true, {})); 46476 } 46477 }); 46478 46479 tram_time_form_field = cart_form.find('[name$="[tram_times]"]'); 46480 tram_time_form_field.val($('.tram-time:not(.tram-time--template) option:selected').map(function(){return $(this).data('dci')}).get().join()); 46481} 46482 46483/* 46484 Keep consistency on the hidden cart items form fields indexing 46485 and reflect the order across all modifiers/guests fields 46486*/ 46487function set_items_global_index_and_sort_guests(){ 46488 var cart_form = $("#edit_cart, #new_cart").first(); 46489 // Set global indexes to all items 46490 var new_index = 0; 46491 $('tr.item_info').each(function() { 46492 // For those items with quantity grater than zero... 46493 if ($(this).find('.qty').val() > 0) { 46494 item_id = $(this).attr('data-item-id'); 46495 // ...and all corresponding hidden cart items form fields... 46496 cart_form.find('[data-item-id="'+item_id+'"][data-item-global-index]').each(function(){ 46497 // Grab current local and global index 46498 var current_global_index = $(this).attr('data-item-global-index'); 46499 var current_local_index = $(this).attr('data-item-index'); 46500 // Set the new global index to form items and replace all form fields names indexes 46501 $(this).attr('data-item-global-index', new_index); 46502 $(this).find('input').each(function(i, el){ 46503 $(el).attr('id', $(el).attr('id').replace("_"+current_global_index+"_", "_"+new_index+"_")); 46504 $(el).attr('name', $(el).attr('name').replace("["+current_global_index+"]", "["+new_index+"]")); 46505 }); 46506 // Set the new global index to all modifiers/guests fields 46507 $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+current_local_index+'"]').attr('data-item-global-index', new_index); 46508 $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+current_local_index+'"] label .guest-index').text(parseInt(current_local_index)+1); 46509 // Increment new index for next iteration 46510 new_index++; 46511 }); 46512 } 46513 }); 46514 46515 // Sort guests 46516 $('.activities .modifier_group__list').each(function(){ 46517 var items = $(this).find('.form-item[data-item-id][data-item-index]'); 46518 items.sort(function(a,b) { 46519 return +$(a).data('itemGlobalIndex') - +$(b).data('itemGlobalIndex'); 46520 }); 46521 $(this).find('.form-item[data-item-id][data-item-index]').remove(); 46522 $(this).append(items); 46523 }); 46524} 46525 46526/* 46527 Generate item summary for a set quantity of guests and a price 46528*/ 46529function item_guests_summary(item, qty, price) { 46530 item_name = $(item).attr('data-item-name'); 46531 return $('<div>'+item_name+' X '+qty+'<div class="right item-price">$'+((price || 0) * qty).toFixed(2)+'</div></div>') 46532} 46533 46534/* 46535 Generate tram times summary 46536*/ 46537function tram_times_summary() { 46538 var summary = "<p>"; 46539 $('.tram-time:not(.tram-time--template)').each(function(){ 46540 summary += $(this).data("type") + ": " + $(this).find('option:selected').text() + "<br>"; 46541 }); 46542 summary += "</p>"; 46543 return summary; 46544} 46545 46546/* 46547 Toggle tram times step for non-single activities 46548*/ 46549function toggle_tram_times_step() { 46550 if (!is_single_activity()) { 46551 populate_modifier_ids(); 46552 if (total_quantity() > 0) { 46553 $('.product__step-step3 .buy-label h6').removeClass('disabled'); 46554 $('.product__step-step3 .product__step-form').slideDown(); 46555 } else { 46556 $('.product__step-step3 .buy-label h6').addClass('disabled'); 46557 $('.product__step-step3 .product__step-form').slideUp(); 46558 } 46559 46560 } 46561} 46562 46563/* 46564 Reset single activity form 46565*/ 46566function reset_form(date) { 46567 46568 if (is_single_activity()) { 46569 $('.product__step').not('.product__step-step2').find('.product__step-form').slideUp(); 46570 $('[data-item-id][data-item-index][data-item-global-index]').remove(); 46571 $('.product__step-summary').html(''); 46572 $('.product__step:not(.product__step-last) .buy-label a').addClass('hide'); 46573 $('.product__step-last').addClass('hide'); 46574 $('.product__step-last .buy-label a .right').text('Hide'); 46575 scroll_to_step('.product__step-step1'); 46576 } 46577 $('.product__step-step2 .product__step-form').slideDown(); 46578 $('.product__step-step2 .buy-label h6').removeClass('disabled'); 46579 $('tr.item_info').each(function(){ 46580 item_id = $(this).attr('data-item-id'); 46581 if (get_item_quantity(item_id) > 0) 46582 set_form_fields_for_item(item_id, true); 46583 }); 46584 set_tram_times_fields(); 46585 46586 show_available_activities(date, null); 46587} 46588 46589function scroll_to_step(step) { 46590 $('html, body').animate({ 46591 scrollTop: $(step).offset().top - 200 46592 }, 500); 46593} 46594 46595function set_step_2_select_state() { 46596 var activities_selects = $('.product__step-step2 .form-item[data-item-id][data-item-index] select'); 46597 var empty_activities_selects = activities_selects.find('option[value=""]:selected').closest('select'); 46598 if (activities_selects.length == 0 || empty_activities_selects.length > 0) { 46599 $('.product__step-step2 .product__step-form__select, .product__step .buy-label a').attr('disabled', 'disabled'); 46600 } else { 46601 $('.product__step-step2 .product__step-form__select, .product__step .buy-label a').removeAttr('disabled'); 46602 } 46603} 46604 46605function set_form_fields_for_item(item_id, without_availability_check) {
46606 without_availability_check = without_availability_check || false; 46607 var item = get_item(item_id); 46608 var cart_form = $("#edit_cart, #new_cart").first(); 46609 var item_modifier_group_id = item.attr('data-item-modifier-group-id'); 46610 var item_name = item.attr('data-item-name'); 46611 var qty = get_item_quantity(item_id); 46612 var existingQty = cart_form.find("[data-item-id="+item_id+"]").length; 46613 46614 // Update existing fields date 46615 cart_form.find('[data-item-id="'+item_id+'"] input[name$="[date]"]').val($('#activity_date').val()); 46616 46617 // Add necessary number of fields to match current total quantity 46618 if (qty >= existingQty) { 46619 for(i=existingQty; i < qty; i++) { 46620 create_cart_item_attributes_item(item_id, item_modifier_group_id, $('#activity_date').val()); 46621 } 46622 $('.form-item--template[data-item-id="'+item_id+'"]').each(function(){ 46623 var item_activity = $(this).clone(); 46624 item_activity.removeClass('form-item--template').show(); 46625 for(i=existingQty; i < qty; i++) { 46626 item_activity.attr("data-item-index", i); 46627 item_activity.find('label .item-name').html(item_name); 46628 $(this).parent().append(item_activity.clone()); 46629 } 46630 }); 46631 // Remove necessary number of fields to match current total quantity 46632 } else { 46633 for(i=existingQty - 1; i >= qty; i--) { 46634 cart_form.find('[data-item-id="'+item_id+'"][data-item-index="'+i+'"]').remove(); 46635 $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+i+'"]').remove(); 46636 } 46637 } 46638 // Set global indexes and populate hidden cart items form fields values 46639 set_items_global_index_and_sort_guests(); 46640 populate_modifier_ids(); 46641 set_benefits(); 46642 set_step_2_select_state(); 46643 if (!without_availability_check) show_available_activities( $('#activity_date').val(), item_id ); 46644} 46645 46646function set_tram_times_fields() { 46647 $('.tram-time:not(.tram-time--template)').remove(); 46648 $('.tram-time--template').each(function(){ 46649 var tram_time = $(this).clone(); 46650 tram_time.removeClass('tram-time--template').show(); 46651 $(this).parent().append(tram_time.clone()); 46652 }); 46653} 46654 46655 46656function get_unselected_tram_times() { 46657 var selector = ".tram-time:not(.tram-time--template) select"; 46658 if ($("#download_only").is(":checked")) { 46659 selector = ".tram-time[data-type=Download]:not(.tram-time--template) select"; 46660 } 46661 return $(selector).filter(function(){ 46662 return $(this).val() == ""; 46663 }); 46664} 46665 46666function set_benefits() { 46667 var cart_form = $("#edit_cart, #new_cart").first(); 46668 $('.form-item[data-item-id][data-item-index]').each(function(){ 46669 cart_item = cart_form.find('[data-item-id="'+$(this).attr('data-item-id')+'"][data-item-index="'+$(this).attr('data-item-index')+'"]'); 46670 let items_benefits = $("tr.item_benefits input[data-item-id="+$(this).attr('data-item-id')+"][type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get(); 46671 let admission_items_benefits = $(".admission_mods-benefits input[type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get(); 46672 let add_and_save_activities_benefits = $(".activities .item_benefits input[type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get(); 46673 cart_item.find('input[name$="[benefits]"]').val( 46674 items_benefits 46675 .concat(admission_items_benefits) 46676 .concat(add_and_save_activities_benefits) 46677 .join(',') 46678 ) 46679 }); 46680} 46681 46682function update_benefits_quantities(e) { 46683 46684 if (e) { 46685 // If context item is provided, show/hide item benefits depending on item qty 46686 let current_item_qty = $(e).val(); 46687 let item_benefits = $(e).closest("tr.item_info").next('.item_benefits'); 46688 if (item_benefits) 46689 item_benefits.toggleClass('hide', (current_item_qty == 0)); 46690 } 46691 46692 // Collect current state of items quantities 46693 var items_qties = {}; 46694 let items = $('tr.item_info'); 46695 for (var i = 0; i < items.length; i++) { 46696 let item = $(items[i]); 46697 let qty = parseInt(item.find('select.qty').val()); 46698 items_qties[item.data("itemId")] = qty 46699 } 46700 // For each benefit quantities... 46701 Object.entries(benefits_quantities_cache).forEach(function([b_id, b]) { 46702 // Assigned current item quantities 46703 benefits_quantities_cache[b_id]["items_qties"] = JSON.parse(JSON.stringify(items_qties
46703)); 46704 // For each benefit pass no 46705 Object.entries(b.pass_nos).forEach(function([p_no, qties]) { 46706 // Reset benefit/pass no redeemed qty 46707 benefits_quantities_cache[b_id].pass_nos[p_no]["redeemed_qty"] = 0; 46708 // For each benefit/pass no/item qty... 46709 Object.entries(items_qties).forEach(function([item_id, qty]) { 46710 qty = benefits_quantities_cache[b_id]["items_qties"][item_id]; 46711 if (qty > 0) { 46712 // Find the benefits checkbox that handles this benefit, for this pass no and this item: 46713 // Benefits checkboxes can be located within... 46714 // 1- items 46715 let is_item_benefit = true 46716 let benefit_box = $('.item_benefits[data-item-id='+item_id+']').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]"); 46717 // 2- or admission ticket step 46718 if (benefit_box.length == 0) { 46719 is_item_benefit = false 46720 benefit_box = $('.admission_mods-benefits').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]"); 46721 } 46722 // 3- or add and save step 46723 if (benefit_box.length == 0) { 46724 is_item_benefit = false 46725 benefit_box = $('.activities .item_benefits').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]"); 46726 } 46727 46728 let benefit_quantities_cache = benefits_quantities_cache[b_id].pass_nos[p_no] 46729 let remaining_qty = benefit_quantities_cache["remaining_qty"] - benefit_quantities_cache["redeemed_qty"]; 46730 46731 if (remaining_qty > 0) { 46732 benefit_box.prop("disabled", false); 46733 if (benefit_box.is(":checked")) { 46734 let redeemable_qty = qty > remaining_qty ? remaining_qty : qty; 46735 benefits_quantities_cache[b_id].pass_nos[p_no]["redeemed_qty"] += redeemable_qty; 46736 benefits_quantities_cache[b_id]["items_qties"][item_id] = qty - redeemable_qty; 46737 } 46738 } else { 46739 if (is_item_benefit) 46740 benefit_box.prop("checked", false); 46741 } 46742 } 46743 }); 46744 }); 46745 }); 46746 46747 Object.entries(benefits_quantities_cache).forEach(function([b_id, b]) { 46748 Object.entries(b.pass_nos).forEach(function([p_no, qties]) { 46749 let final_remaining_qty = qties["remaining_qty"] - qties["redeemed_qty"]; 46750 let benefit_boxes = $('.item_benefits input[data-benefit-id="'+b_id+'"][data-pass-no="'+p_no+'"]'); 46751 46752 benefit_boxes.toggleClass("hide", (b.remainingquantity == 0)); 46753 benefit_boxes.each(function(i, b){ 46754 if (final_remaining_qty == 0 && !$(b).is(":checked")) { 46755 $(b).prop("disabled", true) 46756 } else { 46757 $(b).prop("disabled", false) 46758 } 46759 }); 46760 benefit_boxes.next('label').find('span.item_benefit-qty_available').text("("+final_remaining_qty+" available)"); 46761 }); 46762 }); 46763 46764 set_benefits(); 46765 loading_running_totals(); 46766 get_sw_subtotal(); 46767} 46768 46769/* 46770 Populate form modifier ids on any activity selection change 46771 Enable Step 2 Select button and any edit button, only if all activity selects have value 46772*/ 46773$(document).on("change", '#product_buy_area[data-product-type="bundled"] .form-item[data-item-index] select, .tram-time:not(.tram-time--template) select, #product_buy_area[data-product-type="bundled"] .form-item[data-item-index] input', function(){ 46774 populate_modifier_ids(); 46775 set_step_2_select_state(); 46776}); 46777 46778/* 46779 Select/Unselect all guests admission tickets with one click 46780*/ 46781$(document).on("change", '#product_buy_area[data-product-type="bundled"] input[name="add_admission_mods"]', function(){ 46782 var add_admission_mods = $('input[name="add_admission_mods"]:checked').val(); 46783 var checked = (add_admission_mods == "1"); 46784 $('.admission_mods').attr('data-add-tickets', add_admission_mods); 46785 $('.admission_mods [data-item-id][data-item-index] input').prop('checked', checked).change(); 46786 loading_running_totals(); 46787 get_sw_subtotal(); 46788}); 46789 46790/* 46791 Submit/Select activity step 2 form (Activity/Guest quantities) 46792*/ 46793$(document).on("click", '.product__step-step2 button.product__step-form__select', function(){ 46794 // Validate form to be sure there aren't empty dropboxes 46795 if (!validate_activity_form($(this).closest('.product__step-form'))) return true; 46796 // Clear Step 2 form summary and Step 3 form details to later populate them 46797 var step2_summary = $('.product__step-step2 .product__step-summary'); 46798 var step3_add_details = $('.product__step-step3 .product__step-form .form-item.add .details'); 46799 step2_summary.html(''); 46800 step3_add_details.html(''); 46801 // Fill out Step 2 form summary and Step 3 form details 46802 $('tr.item_info').each(function() { 46803 qty = $(this).find('.qty').val(); 46804 if (qty > 0) { 46805 item_id = $(this).attr('data-item-id'); 46806 activity_price = $('.product__step-step2 .product__step-form [data-item-index][data-item-id="'+item_id+'"] option:selected').attr('data-price'); 46807 ticket_price = $('.product__step-step3 .product__step-form [data-item-index][data-item-id="'+item_id+'"] input').attr('data-price'); 46808 step2_summary.append(item_guests_summary($(this), qty, activity_price)); 46809 step3_add_details.append(item_guests_summary($(this), qty, ticket_price)); 46810 } 46811 }); 46812 // Populate step 3 pricing details based on step 2 quantities
46813 $('[name="add_admission_mods"][value="'+$('.admission_mods').attr('data-add-tickets')+'"]').prop('checked', true).change(); 46814 // Go to step 3 46815 $('.product__step-step2 .product__step-form').slideUp(); 46816 $('.product__step-step2 .buy-label a').removeClass('hide'); 46817 $('.product__step-step2 .product__step-summary').slideDown(); 46818 $('.product__step-step3 .product__step-summary').slideUp(); 46819 $('.product__step-step3 .buy-label a').addClass('hide'); 46820 $('.product__step-step3 .buy-label h6').removeClass('disabled'); 46821 $('.product__step-step3 .product__step-form').slideDown(); 46822 scroll_to_step($('.product__step-step2')); 46823}); 46824 46825/* 46826 Select activity step 3 form (Admission ticket selection) 46827*/ 46828$(document).on("click", '.product__step-step3 button.product__step-form__select', function(){ 46829 // Clear form summary 46830 var step3_summary = $('.product__step-step3 .product__step-summary'); 46831 step3_summary.html(''); 46832 // If tickets were added, fill out summary with details about pricing and quantities 46833 // and switch add and save content 46834 if ($('input[name="add_admission_mods"]:checked').val() == '1') { 46835 $('tr.item_info').each(function() { 46836 qty = $(this).find('.qty').val(); 46837 if (qty > 0) { 46838 item_id = $(this).attr('data-item-id'); 46839 ticket_price = $('.product__step-step3 .product__step-form [data-item-index][data-item-id="'+item_id+'"] input').attr('data-price'); 46840 step3_summary.append(item_guests_summary($(this), qty, ticket_price)); 46841 } 46842 }); 46843 $('.product__step-last .add-and-save').removeClass('hide'); 46844 $('.product__step-last .not-add-and-save').addClass('hide'); 46845 // Else, fill out summary with message and $0.00 price 46846 // and switch add and save content 46847 } else { 46848 step3_summary.html('<div>I already have a Ticket or Pass<div class="right item-price">$0.00</div></div>'); 46849 $('.product__step-last .add-and-save').addClass('hide'); 46850 $('.product__step-last .not-add-and-save').removeClass('hide'); 46851 } 46852 // Go to tram times step 46853 $('.product__step-step3 .product__step-form').slideUp(); 46854 $('.product__step-step3 .buy-label a').removeClass('hide'); 46855 $('.product__step-step3 .product__step-summary').slideDown(); 46856 if (tram_times_present() && tram_times_required($("#activity_date").val())) { 46857 $('.product__step-tram-times .buy-label a .right').text('Hide'); 46858 $('.product__step-tram-times .product__step-summary').slideUp(); 46859 $('.product__step-tram-times .buy-label a').addClass('hide'); 46860 $('.product__step-tram-times .buy-label h6').removeClass('disabled'); 46861 $('.product__step-tram-times .product__step-form').slideDown(); 46862 } else { 46863 toggle_last_step(); 46864 } 46865 46866 scroll_to_step($('.product__step-step3')); 46867}); 46868 46869/* 46870 Select activity step 4 form (Tram times selection) 46871*/ 46872$(document).on("click", '.product__step-tram-times button.product__step-form__select', function(){ 46873 // Clear form errors 46874 $('.tram-time').removeClass('error'); 46875 $('#buy_area_messages li').remove(); 46876 if (validate_tram_times_sequence()) { 46877 // Set form summary 46878 $('.product__step-tram-times .product__step-summary').html(tram_times_summary()); 46879 // Go to last step 46880 $('.product__step-tram-times .product__step-form').slideUp(); 46881 $('.product__step-tram-times .buy-label a').removeClass('hide'); 46882 $('.product__step-tram-times .product__step-summary').slideDown(); 46883 toggle_last_step(); 46884 scroll_to_step($('.product__step-tram-times')); 46885 } 46886 toggle_buy_area_messages(); 46887}); 46888 46889/* 46890 Toggle last step 46891*/ 46892function toggle_last_step() { 46893 setTimeout(function(){ 46894 $('.buy_area .tally').removeClass('muted'); 46895 },0); 46896 $('.product__step-last .buy-label a .right').text('Hide'); 46897 if ($('.product__step-last .form-item[data-item-index] option[data-dci]').length > 0) { 46898 $('.product__step-last').removeClass('hide'); 46899 $('.product__step-last .product__step-form').slideDown(); 46900 } else { 46901 $('.product__step-last').addClass('hide'); 46902 $('.product__step-last .product__step-form').slideUp(); 46903 $('.product__step-last .product__step-form .form-item[data-item-index] select').val("").change(); 46904 } 46905} 46906 46907/* 46908 Handle click on Edit activity step form 46909*/ 46910$(document).on("click", '.product__step:not(.product__step-last) .buy-label a', function(e){ 46911 e.preventDefault(); 46912 $('.buy_area .tally').addClass('muted'); 46913 // Get current step wrapper 46914 var current_step = $(this).closest('.product__step'); 46915 // Hide all forms 46916 $('.product__step .product__step-form').slideUp(); 46917 // Show all edit buttons and summaries, except for current step 46918 $('.product__step').not(current_step).find('.buy-label a').removeClass('hide'); 46919 $('.product__step').not(current_step).find('.product__step-summary').slideDown(); 46920 // Reset step 5 form 46921 $('.product__step-last .buy-label a .right').text('Hide'); 46922 $('.product__step-last').addClass('hide'); 46923 // Show current step form
46924 current_step.find('.product__step-summary').slideUp(); 46925 current_step.find('.product__step-form').slideDown(); 46926 $(this).addClass('hide'); 46927 setTimeout(function(){ 46928 scroll_to_step(current_step); 46929 }, 300); 46930}); 46931 46932/* 46933 Handle click on Hide activity step form 46934*/ 46935$(document).on("click", '.product__step-last .buy-label a', function(e){ 46936 e.preventDefault(); 46937 var current_step = $(this).closest('.product__step'); 46938 var handle = $(this).find('.right'); 46939 if (handle.text() == 'Hide') { 46940 current_step.find('.product__step-form').slideUp(); 46941 handle.text('Show'); 46942 } else { 46943 current_step.find('.product__step-form').slideDown(); 46944 handle.text('Hide'); 46945 } 46946 scroll_to_step(current_step); 46947}); 46948 46949/* 46950 Set activity/option prices if not unique-price is false 46951*/ 46952$(document).on("change", 'select[data-unique-price=false]', function(e){ 46953 e.preventDefault(); 46954 var selected_option = $(this).find('option:selected'); 46955 var label = $(this).siblings('label'); 46956 46957 if (selected_option.data('price') === undefined) 46958 price = "" 46959 else 46960 price = '$'+selected_option.data('price'); 46961 46962 label.find('.item-price').text(price); 46963}); 46964 46965$(document).on("change", ".tram-time select", function(e){ 46966 var unselected = get_unselected_tram_times(); 46967 var next_button = $(this).closest(".product__step-form").find(".product__step-form__select"); 46968 if (unselected.length == 0) { 46969 next_button.removeAttr('disabled'); 46970 } 46971 else { 46972 next_button.attr('disabled', 'disabled'); 46973 } 46974}); 46975 46976$(document).on("change", ".item_benefits input[type=checkbox][name*=benefit_]", function(e){ 46977 update_benefits_quantities(); 46978}); 46979 46980$(document).ready(function(){ 46981 46982 $('a.what_is_btn').click(function(){ 46983 $('.what_is').slideToggle(); 46984 return false; 46985 }); 46986 46987 //Cart - Checkout Now - Alert any workflow hooks or unselected modifiers 46988 $('#ecomm_cart a.checkout_now').click(function(){ 46989 if ($('#ecomm_cart .product__modifiers fieldset.select_one input[type!=hidden]').length > 0 ) { 46990 var mod_selected = false; 46991 $('#ecomm_cart .product__modifiers fieldset.select_one').each(function(){ 46992 if ( $(this).find('input:checked').length > 0 ) { 46993 mod_selected = true 46994 } else { 46995 mod_selected = false; 46996 $(this).effect('shake', { distance: 4, times: 2 }, 100 ); 46997 } 46998 }); 46999 if (!mod_selected) { 47000 notify("Please review each item in your cart and select any additional options"); 47001 $(this).text("Checkout Now"); 47002 return false; 47003 } 47004 } 47005 if ($('#ecomm_cart .cart__items li.show_alert').length > 0 ) { 47006 var alerts = []; 47007 $('#ecomm_cart .cart__items li.show_alert').each(function(){ 47008 alerts.push( $(this).data('alert-text') ); 47009 }); 47010 alerts = alerts.unique(); 47011 if (confirm(alerts.join(". ")+"\n\nClick OK to Continue Checkout.")) { 47012 return true; 47013 } else { 47014 $(this).text("Checkout Now"); 47015 return false; 47016 } 47017 } 47018 47019 }); 47020 47021 // update totals 47022 $('body').bind('content_replaced', function(){ 47023 $('span.grand_total').text( $('#ecomm_cart').data('grand-total') ); 47024 }); 47025 47026 // make checkboxes behave like radios for grouped select one mods 47027 $("#ecomm_cart .product__modifiers .select_one input").on("click", function(e) { 47028 var submit = true 47029 if ($(this).prop('checked') == true) { 47030 $(this).closest('.mod-group').find('input').not(this).prop('checked', false); 47031 } else { 47032 $(this).prop('checked', true); 47033 submit = false 47034 } 47035 if (submit) { 47036 $(this).closest('form').submit().addClass("loading"); 47037 $(this).closest('mod-group').addClass("loading"); 47038 } 47039 }); 47040 47041}); 47042$(document).ready(function(){ 47043 47044// ===================== 47045// = Waiver Navigation = 47046// ===================== 47047 47048 47049 $('.waiver--intro > a').click(function(event) { 47050 $(this).closest('.waiver--intro').hide(); 47051 $(this).closest('.waiver--intro').next('.waiver-other-steps').removeClass('hidden'); 47052 refresh_scrolling(); 47053 }); 47054 47055 refresh_scrolling = function() { 47056 info_div = document.getElementById("additional_info"); 47057 if (info_div) 47058 info_div.appendChild(document.createElement("span")); 47059 } 47060 47061 refresh_scrolling(); 47062 47063 $('.btn-next').click(function(){ 47064 tab = $(this).closest('.tab-content').prev().find('> .active').next('li').find('a'); 47065 tab.trigger('click') 47066 $('html, body').animate({ 47067 scrollTop: tab.offset().top - 160 47068 }, 500); 47069 refresh_scrolling(); 47070 }); 47071 47072 $('.btn-previous').click(function(){ 47073 tab = $(this).closest('.tab-content').prev().find('> .active').prev('li').find('a'); 47074 tab.trigger('click'); 47075 $('html, body').animate({ 47076 scrollTop: tab.offset().top - 160 47077 }, 500); 47078 refresh_scrolling(); 47079 }); 47080 47081 $('a.disabled').click(function(e) { 47082 e.preventDefault(); 47083 }); 47084 47085 $(".waiver-form ul.nav").on('show', "li.disabled a", function(event) { 47086 event.stopImmediatePropagation(); 47087 return false;
47088 }); 47089 $(".waiver-form ul.nav").off('show', "li:not(.disabled) a") 47090 47091 $(".waiver-form ul.nav").off(); 47092 47093 $(".agreed_to_waiver").change(function(){ 47094 var current_section = $(this).closest('.tab-pane').index() + 2; 47095 47096 if ( $(this).is(':checked') ) { 47097 $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+') a').attr('data-toggle', 'tab').removeClass('disabled'); 47098 $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+')').removeClass('disabled'); 47099 $(this).closest('.tab-pane').find('.btn-agree').removeClass('disabled'); 47100 } 47101 else { 47102 $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+') a').addClass('disabled').removeAttr('data-toggle'); 47103 $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+')').addClass('disabled'); 47104 $(this).closest('.tab-pane').find('.btn-agree').addClass('disabled'); 47105 $(this).closest('.tab-pane').nextAll().find(".agreed_to_waiver").prop('checked', false).trigger("change") 47106 } 47107 47108 47109 }); 47110 47111 $('.item.waiver-header').click(function(){ 47112 var current = $(this).next('.additional_info.form-details') 47113 if (current.hasClass('hide')){ 47114 current.toggleClass('hide'); 47115 $('.additional_info.form-details').not(current).addClass('hide'); 47116 } 47117 }) 47118 47119 toggleWaiverContinueBtn = function(){ 47120 if ($(".waiver-form-details[data-completed=false]").length){ 47121 $('.button.waiver-continue').addClass('hidden'); 47122 } 47123 else { 47124 $('.button.waiver-continue').removeClass('hidden'); 47125 } 47126 } 47127 toggleWaiverContinueBtn(); 47128 47129 showNextWaiver = function(){ 47130 current = $('.additional_info.form-details').first(); 47131 current.removeClass('hide'); 47132 $('.additional_info.form-details').not(current).addClass('hide'); 47133 //if ($(".waiver-form-details[data-completed=false][data-type=3rd_party]").length == 0) { 47134 $("#onerisk_waivers__iframe-modal").modal('show'); 47135 //} 47136 47137 } 47138 showNextWaiver(); 47139 47140 $(window).on("message", function(e) { 47141 try { 47142 var data = JSON.parse(e.originalEvent.data); 47143 if (data.messageType == "waiverCompleted") { 47144 $('.waiver-form').each(function(i, f){ 47145 if ($(f).find('input[name="waiver_signoff[liability_form_attributes][siriusware_liability_form]"]').val() == data.posFormId 47146 && $(f).find('input[name="waiver_signoff[liability_form_attributes][siriusware_guest_no]"]').val() == data.posGuestId) { 47147 $(f).find('form').submit(); 47148 console.log('waiver form submitted'); 47149 return false; 47150 } else { 47151 console.log('no matching waiver form found'); 47152 } 47153 }); 47154 } else if (data.messageType == "allCompleted" || data.messageType == "allWaiversCompleted") { 47155 $('.waiver-form').each(function(i, f){ 47156 $(f).find('form').submit(); 47157 }) 47158 47159 setTimeout(function(){ $('#onerisk_waivers__iframe-modal').modal("hide"); }, 1000); 47160 } 47161 console.log(data); 47162 } catch(e) { 47163 } 47164 }); 47165 47166 $(document).ajaxSuccess(function() { 47167 toggleWaiverContinueBtn(); 47168 showNextWaiver(); 47169 }); 47170 47171 $.validator.addMethod("iagreerule", function(value, element, param) { 47172 return this.optional(element) || value === param; 47173 }, "You must enter {0}"); 47174 47175 jQuery.validator.messages.required = ""; 47176 47177 $('.waiver-update-button').each(function() { 47178 $(this).validate({ 47179 invalidHandler: function(e, validator) { 47180 var errors = validator.numberOfInvalids(); 47181 if (errors) { 47182 var message = errors == 1 47183 ? 'There is 1 error in the form. It has been highlighted in red.' 47184 : 'There are ' + errors + ' errors in the form. They have been highlighted in red.'; 47185 $("div.errors").html(message); 47186 $("div.errors").show(); 47187 } else { 47188 $("div.errors").hide(); 47189 } 47190 }, 47191 errorElement: "span", 47192 errorLabelContainer: ".error", 47193 highlight: function(element) { 47194 $(element).closest('.field').removeClass('success').addClass('error'); 47195 }, 47196 unhighlight: function(element) { 47197 $(element).closest('.field').removeClass('error').addClass('success'); 47198 }, 47199 success: function(element) { 47200 $(element).closest('.field').removeClass('error').addClass('success'); 47201 if ($('#hash_view').val()) { 47202 $('.intro').html('You have successfully signed the eWaiver.'); 47203 $('span.required').remove(); 47204 } 47205 }, 47206 rules: { 47207 // simple rule, converted to {required:true} 47208 "cart_item[waiver_signoff_attributes][waiver_full_name]": { 47209 required: true, 47210 minlength: 3 47211 }, 47212 // compound rule 47213 iagree: { 47214 required: true, 47215 iagreerule: 'I AGREE' 47216 } 47217 }, 47218 messages: { 47219 iagree: "Please type 'I AGREE'", 47220 "cart_item[waiver_signoff_attributes][waiver_full_name]": "Please enter your full name" 47221 } 47222 47223 }); 47224 }); 47225 47226 $(".onerisk_waivers__iframe iframe").load(function(){ 47227 $(this).siblings(".loader-wrapper").addClass("hide"); 47228 $(this).removeClass("hide"); 47229 }) 47230}); 47231$(document).ready(function(){ 47232 47233 47234 // Payment & Shipping checkout#index 47235 $('a#same_as_billing').click(function(){ 47236 $('#billing_address input[type="text"]').each(function(){ 47237 var target_id = $(this).attr('id').replace(/billing/g,"shipping"); 47238 var val = $(this).val(); 47239 $("#"+target_id).val(val); 47240 }); 47241 $(this).closest('form').valid(); 47242 return false;
47243 }); 47244 47245 47246 $('form#complete_checkout, form.complete_checkout').submit(function(e){ 47247 if (!$(this).valid()){ 47248 e.preventDefault(); 47249 notify("Form invalid, please fix issues before submitting.", "1"); 47250 return; 47251 } 47252 47253 show_order_status_dialog(); 47254 47255 if ($(this).data('remote') == true){ 47256 e.preventDefault(); 47257 47258 $(window).bind("beforeunload",function(event) { 47259 return "Your order is processing. Are you sure?"; 47260 }); 47261 47262 var data = $(this).serialize(); 47263 $.ajax({ 47264 type: "POST", 47265 url: $(this).attr('action'), 47266 data: data, 47267 headers: { 'Cache-Control': 'no-cache'} 47268 }).success(function(data){ 47269 47270 $(window).unbind("beforeunload"); 47271 47272 if ( data.status == "ok" && data.siriusware_wwsale_id ) { 47273 window.location = "/orders/"+data.siriusware_wwsale_id+"/thanks"; 47274 } else if ( data.status == "error" ) { 47275 if (data.error_type == 'dupe_user') { 47276 checkout_login_issue("There was an error submitting your order:<br><strong>"+data.message); 47277 } else if (data.error_type == 'contact_support') { 47278 checkout_processing_message('We apologize as we are unable to complete your request. Please contact Guest Services to complete your purchase at <a "href"="tel:+16049809311">604.980.9311</a> or <a "href"="mailto:[email protected]">[email protected]</a>.', "/checkout", "Close"); 47279 } else { 47280 checkout_processing_message("There was an error submitting your order:<br><strong>"+data.message+"</strong> Please edit your order and try again.", "/checkout", "Edit Order"); 47281 } 47282 } else { 47283 checkout_processing_message("There was an error processing your payment. Please try again in a few minutes.", "/checkout", "Close"); 47284 } 47285 }); 47286 return false; 47287 } 47288 }); 47289}); 47290 47291function show_order_status_dialog() { 47292 var dialog = $('#checkout_processing'); 47293 if (!dialog[0]) { 47294 dialog = $('<div/>', { 47295 id: "checkout_processing" 47296 }) 47297 } 47298 dialog.html('<p class="message">Submitting your order...</p>'); 47299 dialog.appendTo('body').dialog({ 47300 width: 400, 47301 // height: 200, 47302 closeOnEscape: false, 47303 draggable: false, 47304 open: function(event, ui) { $(".ui-dialog-titlebar-close").hide(); }, 47305 resizable: false, 47306 modal: true, 47307 title: "Order Status", 47308 close: function(){ 47309 dialog.dialog('destroy').remove(); 47310 } 47311 }); 47312 $('<div/>', { 47313 "class": "progress_bar" 47314 }).appendTo('#checkout_processing'); 47315 47316 loadCheckoutSurvey(); 47317} 47318 47319var poll_tries=0; 47320function poll_for_checkout_success(sw_id) { 47321 $.ajax({ 47322 url: '/checkout/'+sw_id+'/get_status', 47323 type: 'GET', 47324 dataType: 'json', 47325 success: function(data) { 47326 if (data.status == 'pending') { 47327 if (poll_tries < 60) { 47328 poll_tries++; 47329 setTimeout(function() { poll_for_checkout_success(sw_id); }, 2000); 47330 } else { 47331 if (window.survey) { 47332 checkout_processing_message("There was a delay in processing your payment. We will keep trying and email you when your order has been processed.<br>Order #:"+sw_id, "/account", "Go to My Account page"); 47333 } else { 47334 window.location = "/checkout/"+data.order_number+"/delayed"; 47335 } 47336 } 47337 } else if (data.status == 'error') { 47338 checkout_processing_message("There was an error processing your order: "+data.message+". Please correct the error and try again.<br>Order #:"+sw_id, "close_dialog", "Close"); 47339 } else if (data.status == 'rejected') { 47340 checkout_processing_message("We're sorry, your order could not be completed. Please try again or contact guest services.<br>Order #:"+sw_id, "close_dialog", "Close"); 47341 } else { 47342 if (window.survey) { 47343 checkout_processing_message("Your order was processed successfully", "/orders/"+data.order_number+"/thanks", "View Receipt"); 47344 } else { 47345 window.location = "/orders/"+data.order_number+"/thanks"; 47346 } 47347 } 47348 }, 47349 error: function(data) { 47350 checkout_processing_message("There was an error processing your payment. Please try again in a few minutes.<br>Order #:"+sw_id, "close_dialog", "Close"); 47351 } 47352 }); 47353} 47354 47355function checkout_processing_message(message, url, link_text) { 47356 if ($("#checkout_processing").length == 0) 47357 show_order_status_dialog() 47358 47359 $(".ui-dialog-titlebar-close").show(); 47360 $('#checkout_processing .message').html(message); 47361 $('#checkout_processing .progress_bar').remove(); 47362 if (url == "close_dialog") { 47363 $('<a/>', { 47364 "href": "#", 47365 "class": "button", 47366 text: link_text, 47367 click: function(){ 47368 $('#checkout_processing').dialog('destroy').remove(); 47369 } 47370 }).insertAfter('#checkout_processing .message'); 47371 } else { 47372 $('<a/>', { 47373 "href": url, 47374 "class": "button", 47375 text: link_text 47376 }).insertAfter('#checkout_processing .message'); 47377 } 47378} 47379 47380function checkout_login_issue(message) { 47381 $(".ui-dialog-titlebar-close").show(); 47382 $('#checkout_processing .message').html(message); 47383 $('#checkout_processing .progress_bar').remove(); 47384 $('<a/>', { 47385 "href": '/login', 47386 "class": "button login-btn", 47387 text: 'Login' 47388 }).insertAfter('#checkout_processing .message'); 47389 $('<a/>', { 47390 "href": '/forgot', 47391 "class": "small", 47392 text: "Forgot your password?" 47393 }).insertAfter('#checkout_processing .login-btn'); 47394 $('.login-btn').after(" "); 47395} 47396 47397function loadCheckoutSurvey() { 47398 $.ajax({ 47399 url: "/checkout/survey.html", 47400 dataType: "html", 47401 success: function(data) { 47402 window.survey = true 47403 47404 // resize dialog 47405 $("#checkout_processing").dialog("option", "width", 620) 47406 $("#checkout_processing").dialog("option", "height", 520) 47407 $("#checkout_processing").dialog("option", "position", $("#checkout_processing").dialog("option", "position")); 47408 47409 // append survey 47410 var $survey = $('<div/>', { 47411 "class": "checkout_survey", 47412 "html": data 47413 }).appendTo('#checkout_processing'); 47414 47415 $survey.find("form").submit(function(){ 47416 var data = $(this).serialize(); 47417 47418 $.ajax({ 47419 url: $(this).attr('action'), 47420 data: data, 47421 type: 'POST', 47422 dataType: 'json', 47423 success: function(data) { 47424 window.survey = false
47425 $survey.text("Thank you for your response."); 47426 $("#checkout_processing").dialog("option", "width", 400) 47427 $("#checkout_processing").dialog("option", "height", 200) 47428 $("#checkout_processing").dialog("option", "position", $("#checkout_processing").dialog("option", "position")); 47429 } 47430 }); 47431 47432 return false; 47433 }); 47434 47435 } 47436 }); 47437} 47438; 47439$(document).ready(function(){ 47440 47441 jQuery.validator.messages.required = ""; 47442 47443 // Add method to validate delivery date 47444 jQuery.validator.addMethod("validdeliverydate", function(value, element, params) { 47445 formItem = $(element).closest('.form-item'); 47446 if (formItem.closest('.user_personal_info_fields').find('.user-type').val() == 'self') 47447 return true; 47448 47449 var today = new Date(); 47450 var todaydd = today.getDate(); 47451 var todaymm = today.getMonth()+1; 47452 var todayyyyy = today.getFullYear(); 47453 47454 if(todaydd < 10){ 47455 todaydd='0'+todaydd; 47456 } 47457 47458 if(todaymm < 10){ 47459 todaymm="0"+todaymm; 47460 } 47461 47462 deliveryyyyy = formItem.find('select[name*="delivery_date(1i)"]').val(); 47463 deliverymm = formItem.find('select[name*="delivery_date(2i)"]').val(); 47464 deliverydd = formItem.find('select[name*="delivery_date(3i)"]').val(); 47465 47466 if(deliverydd < 10){ 47467 deliverydd='0'+deliverydd; 47468 } 47469 if(deliverymm < 10){ 47470 deliverymm="0"+deliverymm; 47471 } 47472 47473 if ([deliveryyyyy,deliverymm,deliverydd].join('-') < [todayyyyy,todaymm,todaydd].join('-')) { 47474 formItem.removeClass('success').addClass('error'); 47475 return false; 47476 } 47477 formItem.removeClass('error').addClass('success'); 47478 47479 return true; 47480 47481 }, "Please make sure delivery dates are greater or equal than today."); 47482 47483 $('#additional_info #edit_cart').validate({ 47484 invalidHandler: function(e, validator) { 47485 var errors = validator.numberOfInvalids(); 47486 if (errors) { 47487 var message = errors == 1 47488 ? 'There is 1 error in the form. It has been highlighted in red.' 47489 : 'There are ' + errors + ' errors in the form. They have been highlighted in red.'; 47490 $("div.errors").html(message); 47491 $("div.errors").show(); 47492 } else { 47493 $("div.errors").hide(); 47494 } 47495 }, 47496 errorElement: "span", 47497 errorLabelContainer: "#errors", 47498 highlight: function(element) { 47499 // Small delay to make sure errors on select_date fields get highlighted 47500 setTimeout(function(){ 47501 $(element).closest('.form-item').removeClass('success').addClass('error'); 47502 }, 100); 47503 }, 47504 unhighlight: function(element) { 47505 $(element).closest('.form-item').removeClass('error').addClass('success'); 47506 }, 47507 success: function(element) { 47508 $(element).closest('.form-item').removeClass('error').addClass('success'); 47509 } 47510 47511 }); 47512 47513 // Ser delivery date rule 47514 $('.form-item--delivery-date').each(function() { 47515 $(this).find('select').first().rules('add', { 47516 validdeliverydate: true, 47517 }); 47518 }); 47519 47520 $('.form-item--delivery-date select[name*="[delivery_date(2i)]"], .form-item--delivery-date select[name*="[delivery_date(3i)]"]').change(function(){ 47521 $(this).siblings('select[name*="[delivery_date(1i)]"]').focus().blur(); 47522 }) 47523 47524 $('#continue_to_checkout').click(function(){ 47525 if ( $('#additional_info #edit_cart').valid()) { 47526 if ($(".lookup-pass:visible").length > 0) { 47527 $('html, body').animate({ 47528 scrollTop: $(".lookup-pass:visible").first().offset().top - 200 47529 }, 500); 47530 47531 notify("Please fill out missing contact information."); 47532 return false; 47533 } 47534 47535 if ( $('.agreed_to_waiver').length > 0 && $('.agreed_to_waiver').prop('checked') != true) { 47536 notify("Please read each waiver and click the check box to indicate you agree to the terms of the waiver."); 47537 return false; 47538 } 47539 47540 $(this).val("Please wait..."); 47541 return true; 47542 } 47543 else { 47544 notify("Form invalid, please fix issues before submitting.", "1"); 47545 return false; 47546 } 47547 }); 47548 47549 var $mapping = { 47550 'new': '3rd_party', 47551 'managed_user': 'managed_user', 47552 'minor': 'kid' 47553 }; 47554 47555 updateUserType = function(){ 47556 var $mapping = { 47557 'new': '3rd_party', 47558 'managed_user': 'managed_user', 47559 'minor': 'kid' 47560 }; 47561 47562 $('.user-type').each(function(index){ 47563 var $origin = $(this).prev().find('input.populate_form:checked'); 47564 var user_id = $origin.val(); 47565 if (!$mapping[user_id])
47566 $mapping[user_id] = 'self'; 47567 $(this).val($mapping[user_id]); 47568 47569 }) 47570 } 47571 updateUserType(); 47572 47573 // Select a Guest Controls 47574 $('#additional_info input.populate_form').change(function(){ 47575 var user_id = $(this).val(); 47576 var cart_item_id = $(this).data('cartItemId'); 47577 var $field_set = $(this).closest('.user_personal_info_fields'); 47578 47579 if (user_id == "managed_user") { 47580 user_id = $(this).siblings('.managed_users').val(); 47581 } 47582 changeUser( $field_set, user_id, cart_item_id); 47583 47584 $field_set.find('a.change-again').hide(); 47585 if (user_id != "managed_user" && user_id != "existing_user") { 47586 $(this).next('a.change-again').removeClass('hide'); 47587 $(this).next('a.change-again').show(); 47588 } else { 47589 $(this).next('a.change-again').hide(); 47590 } 47591 47592 // update user type 47593 var $user_type = $(this).closest('.block.form').find('.user-type'); 47594 if (!$mapping[user_id]) 47595 $mapping[user_id] = 'self'; 47596 $user_type.val($mapping[user_id]); 47597 47598 }); 47599 47600 47601 $('#additional_info a.change-again').click(function(){ 47602 // if ($(this).hasClass('change-self')) 47603 // changeUser( $(this).closest('.user_personal_info_fields'), "123" ); 47604 // else 47605 changeUser( $(this).closest('.user_personal_info_fields'), "new" ); 47606 return false; 47607 }); 47608 47609 $('#additional_info select.populate_form').change(function(){ 47610 var $field_set = $(this).closest('.user_personal_info_fields'); 47611 47612 $(this).siblings('.managed_user_radio').first().attr('checked', true); 47613 47614 var user_id = $(this).val(); 47615 var cart_item_id = $(this).data('cartItemId'); 47616 47617 changeUser( $field_set, user_id, cart_item_id ); 47618 47619 $field_set.find('a.change-again').hide(); 47620 }); 47621 47622 $('.recipient-fields input[name*=recipient_first_name], .recipient-fields input[name*=recipient_last_name], .recipient-fields input[name*=recipient_email]').change(function() { 47623 var field_set = $(this).closest('.user_personal_info_fields'); 47624 var name = $(this).attr('name'); 47625 if (name.indexOf("recipient_first_name") > -1) { 47626 field_set.find(".name-fields input[type=hidden][name*=first_name]").val($(this).val()); 47627 47628 } else if (name.indexOf("recipient_last_name") > -1) { 47629 field_set.find(".name-fields input[type=hidden][name*=last_name]").val($(this).val()); 47630 47631 } else if (name.indexOf("recipient_email") > -1) { 47632 field_set.find(".name-fields input[type=hidden][name*=email]").val($(this).val()); 47633 } 47634 }); 47635 47636 function changeUser($field_set, user_id, cart_item_id) { 47637 var url = $('.change-user-controls').data('user-data-path'); 47638 47639 $.ajax({ 47640 url: url, 47641 data: { 47642 user_id: user_id, 47643 cart_item_id: cart_item_id 47644 }, 47645 type: 'GET', 47646 dataType: 'json', 47647 success: function(data) { 47648 populateForm($field_set, data, user_id); 47649 47650 }, 47651 error: function() { 47652 } 47653 }); 47654 }; 47655 47656 function showContactEmailField($field_set) { 47657 $field_set.find('.form-item--contact-email').removeClass('hide'); 47658 $field_set.find('.form-item--contact-email input').addClass('required').prop('required', true); 47659 } 47660 47661 function hideContactEmailField($field_set) { 47662 $field_set.find('.form-item--contact-email').addClass('hide').removeClass('error'); 47663 $field_set.find('.form-item--contact-email input').removeClass('required').prop('required', false).val(''); 47664 } 47665 47666 function populateForm($field_set, data, user_id) { 47667 47668 var is_current_user = (data.id == user_id); 47669 47670 for ( field in data ) { 47671 if (field == 'siriusware_mugshot_cache_preview_url') { 47672 $field_set.find('.form-item--photo-preview img').attr('src', data[field] ); 47673 } else if (field != "id") { 47674 $field_set.find("input[name*='\["+field+"\]'], select[name*='\["+field+"\]']").val( data[field] ); 47675 } 47676 } 47677 47678 // show/hide mugshot field 47679 if (data["has_siriusware_mug_shot"]) { 47680 $field_set.find("input[name*='siriusware_mugshot_cache']").closest('.form-item').addClass('hide'); 47681 $field_set.find(".form-item.form-item--has-a-photo").removeClass('hide'); 47682 } else { 47683 $field_set.find("input[name*='siriusware_mugshot_cache']").closest('.form-item').removeClass('hide'); 47684 $field_set.find(".form-item.form-item--has-a-photo").addClass('hide'); 47685 } 47686 47687 for ( field in data.address ) { 47688 if (field != "id") { 47689 $field_set.find(".address_fields input[name*="+field+"], .address_fields select[name*="+field+"]").val( data.address[field] ).change(); 47690 if (field == "country") { 47691 // If country, repopulate province 47692 $field_set.find(".address_fields input[name*='province'], .address_fields select[name*='province']").val( data.address["province"] ); 47693 } 47694 } 47695 } 47696 47697 if (data.cart_item_email !== null) { 47698 for ( field in data.cart_item_email ) { 47699 if (field != "id") { 47700 $field_set.find(".recipient-fields input[name*="+field+"]").val( data.cart_item_email[field] ); 47701 } 47702 } 47703 } else { 47704 // set user fields 47705 $field_set.find(".recipient-fields input[name*=recipient_first_name]").val(data['first_name']); 47706 $field_set.find(".recipient-fields input[name*=recipient_last_name]").val(data['last_name']); 47707 $field_set.find(".recipient-fields input[name*=recipient_email]").val(data['email']); 47708 $field_set.find(".recipient-fields input[name*=recipient_email_type]").val(data['email']); 47709 47710 // set disabled fields 47711 $field_set.find(".recipient-disabled .recipient_first_name").text(data['first_name']); 47712 $field_set.find(".recipient-disabled .recipient_last_name").text(data['last_name']); 47713 $field_set.find(".recipient-disabled .recipient_email").text(data['email']); 47714 } 47715 47716 // set name (for disabled state) 47717 $field_set.find(".name-disabled .first_name").text(data['first_name']); 47718 $field_set.find(".name-disabled .last_name").text(data['last_name']); 47719 47720 // set id's 47721 $field_set.find("input[name*='\[address_attributes\]\[id\]']").last().val( data.address.id );
47722 $field_set.find("input[name*='\[id\]']").last().val( data.id ); 47723 47724 // show / hide user lookup form AND lock / unlock name fields 47725 if (data.id) { 47726 if (!isNaN(user_id) && data['birth_date(1i)'] == null){ 47727 showLookup($field_set, true, user_id) 47728 $field_set.find(".name-disabled").slideUp(); 47729 $field_set.find(".recipient-disabled").slideUp(); 47730 $field_set.find(".name-fields").slideDown().removeClass('hide'); 47731 $field_set.find(".recipient-fields").slideDown().removeClass('hide'); 47732 return; 47733 } 47734 showLookup($field_set, false, user_id) 47735 $field_set.find(".name-disabled").slideDown().removeClass('hide'); 47736 $field_set.find(".recipient-disabled").slideDown().removeClass('hide'); 47737 $field_set.find(".recipient-disabled").find(".form-item").removeClass('hide'); 47738 $field_set.find(".name-fields").slideUp(); 47739 $field_set.find(".recipient-fields").slideUp(); 47740 hideContactEmailField($field_set); 47741 } else { 47742 showLookup($field_set, true, user_id) 47743 $field_set.find(".name-disabled").slideUp(); 47744 $field_set.find(".recipient-disabled").slideUp(); 47745 $field_set.find(".recipient-disabled").find(".form-item").removeClass('hide'); 47746 $field_set.find(".name-fields").slideDown().removeClass('hide'); 47747 $field_set.find(".recipient-fields").slideDown().removeClass('hide'); 47748 showContactEmailField($field_set); 47749 } 47750 47751 // Show/Hide Add Pass to My Account 47752 $field_set.find('.form-item--add-pass-to-manager').toggleClass('hide', is_current_user); 47753 $field_set.find('.form-item--add-pass-to-manager').find('input[type=checkbox]').prop('checked', !is_current_user); 47754 } 47755 47756 $('#additional_info a.skip-lookup').click(function(){ 47757 var $field_set = $(this).closest('.user_personal_info_fields'); 47758 showLookup($field_set, false); 47759 47760 return false; 47761 }); 47762 47763 function showLookup($field_set, state, user_id) { 47764 user_id = user_id || "3rd_party" 47765 if (state == true) { 47766 if (!isNaN(user_id)){ 47767 $field_set.find(".self-lookup-pass").removeClass('hide'); 47768 $field_set.find(".self-lookup-pass").slideDown(); 47769 $field_set.find(".lookup-pass").slideUp(); 47770 } 47771 else { 47772 $field_set.find(".lookup-pass").removeClass('hide'); 47773 $field_set.find(".lookup-pass").slideDown(); 47774 $field_set.find(".self-lookup-pass").slideUp(); 47775 } 47776 $field_set.find(".user-form").slideUp(); 47777 } else { 47778 if (!isNaN(user_id)) { 47779 $field_set.find(".self-lookup-pass").slideUp(); 47780 $field_set.find(".lookup-pass").slideUp(); 47781 } 47782 else { 47783 $field_set.find(".lookup-pass").slideUp(); 47784 $field_set.find(".self-lookup-pass").slideUp(); 47785 } 47786 $field_set.find(".user-form").removeClass('hide'); 47787 $field_set.find(".user-form").slideDown(); 47788 } 47789 } 47790 47791 $("#additional_info .self-lookup-pass a.submit-self-lookup").click(function(e) { 47792 e.preventDefault(); 47793 47794 var $button = $(this); 47795 var prev_text = $(this).text(); 47796 $button.text("Please wait..."); 47797 47798 var $field_set = $button.closest('.user_personal_info_fields'); 47799 var $lookup_form = $button.closest('.self-lookup-pass'); 47800 47801 // {"siriusware_pass_no" => "166078036000", "date" => "1980-04-12"} 47802 var date = [ 47803 $lookup_form.find("select[name='lookup_birth_date[year]']").val(), 47804 $lookup_form.find("select[name='lookup_birth_date[month]']").val(), 47805 $lookup_form.find("select[name='lookup_birth_date[day]']").val() 47806 ].join("-") 47807 47808 var data = { 47809 pass: { 47810 siriusware_pass_no: $lookup_form.find("input[name='lookup_pass_no']").val() 47811 } 47812 } 47813 47814 if (date != '--') 47815 data.pass.date = date; 47816 47817 $lookup_form.find(".error").slideUp(); 47818 $.ajax({ 47819 url: "/users/add_pass_to_self", 47820 data: data, 47821 dataType: "json", 47822 type: 'POST', 47823 success: function(data, status) { 47824 populateForm($field_set, data, 'self'); 47825 $button.text(prev_text); 47826 }, 47827 error: function() { 47828 $lookup_form.find(".error").slideDown(); 47829 $button.text(prev_text); 47830 } 47831 }); 47832 }); 47833 47834 $("#additional_info .lookup-pass a.submit-lookup").click(function(e) { 47835 e.preventDefault(); 47836 47837 var $button = $(this); 47838 var prev_text = $(this).text(); 47839 $button.text("Please wait..."); 47840 47841 var $field_set = $button.closest('.user_personal_info_fields'); 47842 var $lookup_form = $button.closest('.lookup-pass'); 47843 47844 // {"siriusware_pass_no" => "100123456", "date" => "1977-11-1"} 47845 var date = [ 47846 $lookup_form.find("select[name='lookup_birth_date[year]']").val(), 47847 $lookup_form.find("select[name='lookup_birth_date[month]']").val(), 47848 $lookup_form.find("select[name='lookup_birth_date[day]']").val() 47849 ].join("-") 47850 47851 var data = { 47852 pass: { 47853 input_no: $lookup_form.find("input[name='lookup_pass_no']").val(), 47854 date: date 47855 } 47856 } 47857 $.ajax({ 47858 url: "/user_lookup/pass", 47859 data: data, 47860 dataType: "json", 47861 type: 'GET', 47862 success: function(data, status) { 47863 populateForm($field_set, data, '3rd_party'); 47864 $button.text(prev_text); 47865 }, 47866 error: function() { 47867 $lookup_form.find(".error-message").slideDown(); 47868 $button.text(prev_text); 47869 } 47870 }); 47871 }); 47872 47873 // same as above 47874 $('#additional_info a.same_as_above').each(function(){ 47875 if ($(this).closest('.personal_info_fields').index('.personal_info_fields') > 0 || 47876 $(this).closest('.user_personal_info_fields').index('.user_personal_info_fields') > 0) { 47877 $(this).parent().removeClass('hide'); 47878 $(this).parent().show(); 47879 } 47880 }); 47881 47882 $('#additional_info a.same_as_above').click(function(){ 47883 const parent_class = $(this).data('same-as-above') == 'address' ? 'address_fields' : 'user_personal_info_fields'; 47884 47885 var $copy_to = $(this).closest('.'+parent_class); 47886 47887 // multi-person item 47888 var $copy_from = $(this).closest('.personal_info_fields').prev(); 47889 47890 if ($copy_from.length == 0) { 47891 $copy_from = $(this).closest('.cart__item').prevAll('.cart__item').first().find('.personal_info_fields').first() 47892 } 47893 47894 var $fields = $copy_from.find('.'+parent_class+' input, .'+parent_class+' select'); 47895 $fields.each(function(){ 47896 var $field = $(this); 47897 var field_name = $field.attr('name').match(/\[([^\[^\]]*)\]$/); 47898 if (field_name) { 47899 var name = field_name.pop(); 47900 name = name.replace("(","_").replace(")","") 47901 $copy_to.find('input[id*='+name+'], select[id*='+name+']').each(function(){ 47902 if ( $(this).attr('id').split("_").pop() != "id" ) { 47903 $(this).val( $field.val() ); 47904 $(this).change(); 47905 } 47906 }); 47907 } 47908 }); 47909 47910 return false;
47911 }); 47912 47913}); 47914$(document).ready(function(){ 47915 47916 jQuery.validator.messages.required = ""; 47917 47918 $('.edit_user_address').validate({ 47919 invalidHandler: function(e, validator) { 47920 var errors = validator.numberOfInvalids(); 47921 if (errors) { 47922 var message = errors == 1 47923 ? 'There is 1 error in the form. It has been highlighted in red.' 47924 : 'There are ' + errors + ' errors in the form. They have been highlighted in red.'; 47925 $("div.errors").html(message); 47926 $("div.errors").show(); 47927 } else { 47928 $("div.errors").hide(); 47929 } 47930 }, 47931 errorElement: "span", 47932 errorLabelContainer: "#errors", 47933 highlight: function(element) { 47934 $(element).closest('.form-item').removeClass('success').addClass('error'); 47935 }, 47936 unhighlight: function(element) { 47937 $(element).closest('.form-item').removeClass('error').addClass('success'); 47938 } 47939 }); 47940 47941 $('.edit_user_address .form-actions button').click(function(){ 47942 if ($('.edit_user_address').valid()) { 47943 $(this).val("Please wait..."); 47944 return true; 47945 } 47946 else { 47947 notify("Form invalid, please fix issues before submitting.", "1"); 47948 return false; 47949 } 47950 }); 47951}); 47952$.widget("ui.tsSlideshow", { 47953 47954 // default options 47955 options: { 47956 rate: 3000, 47957 duration: 1500 47958 }, 47959 47960 _create: function() { 47961 var self = this; 47962 self.curIndex = self.element.children().first().index(); 47963 self.element.children().eq( self.curIndex ).fadeIn(self.options.duration, function(){ 47964 self.timer = setTimeout(function(){self.next();},self.options.rate); 47965 }); 47966 47967 }, 47968 47969 update: function() { 47970 47971 }, 47972 47973 next: function() { 47974 var self = this; 47975 self.element.children().eq( self.curIndex ).css('z-index','0'); 47976 self.element.children().eq( self._nextIndex() ).css('z-index','1').fadeIn( self.options.duration, function(){ 47977 // hide previous 47978 self.element.children().eq( self.curIndex ).css('display','none'); 47979 47980 self.curIndex = self._nextIndex(); 47981 clearTimeout(self.timer); 47982 self.timer = setTimeout(function(){self.next();},self.options.rate); 47983 47984 }); 47985 }, 47986 47987 start: function() { 47988 var self = this; 47989 self.next(); 47990 }, 47991 47992 stop: function() { 47993 var self = this; 47994 clearTimeout(self.timer); 47995 }, 47996 47997 _nextIndex: function() { 47998 var self = this; 47999 var total = self.element.children().length; 48000 if ( self.curIndex == (total - 1)) { 48001 return 0; 48002 } 48003 return this.curIndex + 1; 48004 }, 48005 48006 destroy: function() { 48007 $.Widget.prototype.destroy.apply(this, arguments); // default destroy 48008 // now do other stuff particular to this widget 48009 } 48010 48011}); 48012/* 48013* On Off Switch Plugin 48014* 48015* Copyright (c) 2011 Thought Shop Creative Inc. 48016* 48017* By Trevor Johnston 48018* 48019* Date: 2011-04-12 48020* Rev: 1.0-2 48021*/ 48022 48023(function($){ 48024 48025 $.widget("ui.tsWidgets", { 48026 // default options 48027 options: { 48028 48029 }, 48030 48031 active: false, 48032 48033 _create: function() { 48034 var self = this; 48035 48036 self._bindTriggerClicks(); 48037 48038 // check external clicks 48039 $(document).mousedown(function(event){ 48040 self._checkExternalClick(event); 48041 }); 48042 }, 48043 48044 // Public Methods 48045 48046 value: function( newValue ) { 48047 48048 }, 48049 48050 // Private Methods 48051 48052 _bindTriggerClicks: function() { 48053 var self = this; 48054 48055 self.element.find('a').click(function(){ 48056 if ( self.active && $(this).hasClass('active') ) { 48057 self._hideWidgets(); 48058 } else { 48059 self._showWidget( $(this) ); 48060 } 48061 return false; 48062 }); 48063 }, 48064 48065 _showWidget: function( $trigger ) { 48066 var self = this; 48067 var widget_class = $trigger.attr('href').replace(/^#/, ''); 48068 48069 if (!self.active) { 48070 self._showWidgets(); 48071 } 48072 48073 $('#widgets .widget').hide(); 48074 $('#widget_triggers a').removeClass('active'); 48075 48076 $('#widgets').find('.'+widget_class).show(); 48077 $trigger.addClass("active"); 48078 48079 ga('send', 'event', widget_class, 'click', 'footer widgets'); 48080 }, 48081 48082 _showWidgets: function() { 48083 var self = this; 48084 48085 self.active = true; 48086 48087 closeGrid(); 48088 48089 $('#widgets').animate({ 48090 height: '455px' 48091 }, 400, function() { 48092 // Animation complete. 48093 }); 48094 pause_full_screen_bg(); 48095 }, 48096 48097 _hideWidgets: function() { 48098 var self = this; 48099 48100 self.active = false;
48101 $('#widget_triggers a').removeClass('active'); 48102 48103 $('#widgets').animate({ 48104 height: '0px' 48105 }, 400, function() { 48106 // Animation complete. 48107 }); 48108 resume_full_screen_bg(); 48109 }, 48110 48111 _checkExternalClick: function(event) { 48112 var self = this; 48113 48114 if (self.active == false) { 48115 return; 48116 } 48117 48118 var $target = $(event.target); 48119 if ($target[0].id != '#widgets' && 48120 $target[0].id != '#widget_triggers' && 48121 $target.parents('#widgets').length == 0 && 48122 $target.parents('#widget_triggers').length == 0) { 48123 self._hideWidgets(); 48124 } 48125 }, 48126 48127 destroy: function() { 48128 $.Widget.prototype.destroy.apply(this, arguments); // default destroy 48129 // now do other stuff particular to this widget 48130 } 48131 }); 48132 48133})(jQuery); 48134// GROUSE MAIN DESKTOP JS FILE 48135 48136// Not required anymore, JQuery 1.9 infers data type from header. 48137// Besides, this brakes the whole AJAX framework, forcing 48138// everything to be JSON. 48139// $.ajaxSettings.dataType = "json"; 48140 48141jQuery.fn.fadeToggle = function(speed, easing, callback) { 48142 return this.animate({opacity: 'toggle'}, speed, easing, callback); 48143}; 48144 48145jQuery.fn.lazyLoadImages = function() { 48146 48147 return this.each(function() { 48148 48149 var $grid_image = $(this); 48150 $grid_image.addClass("loading"); 48151 var url = $grid_image.data('url'); 48152 var img = new Image(); 48153 $(img).load(function() { 48154 $(this).hide(); 48155 $grid_image.replaceWith(this); 48156 $(this).fadeIn(); 48157 }).attr('src', url); 48158 48159 }); 48160 48161}; 48162 48163Array.prototype.unique = 48164 function() { 48165 var a = []; 48166 var l = this.length; 48167 for(var i=0; i<l; i++) { 48168 for(var j=i+1; j<l; j++) { 48169 // If this[i] is found later in the array 48170 if (this[i] === this[j]) 48171 j = ++i; 48172 } 48173 a.push(this[i]); 48174 } 48175 return a; 48176}; 48177 48178// ==================== 48179// = CMS Help Buttons = 48180// ==================== 48181 48182$(document).ready(function(){ 48183 $('div.help').livequery(function(){ 48184 var $self = $(this); 48185 var button = $('<a/>', { 48186 "class": "help", 48187 mouseenter: function(){ 48188 $self.css({ 48189 top: button.position().top, 48190 left: button.position().left 48191 }); 48192 $self.fadeIn('fast'); 48193 } 48194 }); 48195 48196 $self.prev('label').append( button ); 48197 48198 $self.bind('mouseout', function(){ 48199 $(this).fadeOut('fast'); 48200 }).bind('click', function(){ 48201 $(this).fadeOut('fast'); 48202 }); 48203 48204 }); 48205 48206 48207 48208}); 48209 48210 48211// =================== 48212// = Notify Function = 48213// =================== 48214function notify(message,status) { 48215 var repeat = false; 48216 if (!message) { return false; } 48217 if (!status) { status = "notice"; } 48218 48219 if ( !$('#ts-notify').length ) { 48220 $('<div/>', { 48221 "id": "ts-notify" 48222 }).hover(function(){ // stop fadeout on hover 48223 $(this).stop(true); 48224 $(this).fadeTo(300,1); 48225 },function(){ // re-instate fadeout on mouseLeave 48226 $(this).delay(10000).fadeTo(600,0,function(){ $(this).remove(); }); 48227 }).appendTo('body'); 48228 } 48229 48230 var $close_button = $('<button/>', { 48231 "class": "close", 48232 "html": "x", 48233 click : function(){ 48234 $(this).parent().hide().remove(); 48235 if ( !$('#ts-notify .notification').length ) { 48236 $('#ts-notify').remove(); 48237 } 48238 } 48239 }); 48240 48241 var parsedMessage = $.parseHTML(message); 48242 if (parsedMessage.length > 0) 48243 parsedMessage = parsedMessage[0].textContent 48244 else 48245 parsedMessage = message 48246 48247 var $body = $('<div/>', { 48248 "class": "notification-body", 48249 "html": parsedMessage 48250 }) 48251 48252 var notification = $('<div/>', { 48253 "class": "notification "+status 48254 }).prepend($body).prepend($close_button); 48255 48256 48257 $('#ts-notify > div').each(function(){ 48258 if ( $(this).html() == notification.html() ) { repeat = true; } 48259 }); 48260 48261 if ( repeat == false ) { 48262 $('#ts-notify').prepend(notification); 48263 48264 $('#ts-notify').stop(true).fadeTo(1,1); 48265 48266 $('#ts-notify').show().fadeTo(600,1,function(){ 48267 //delay and fadeout 48268 $(this).delay(5000).fadeTo(600,0,function(){$(this).remove();}); 48269 }); 48270 } 48271 48272} 48273 48274// =========================== 48275// = AJAX Response Processor = 48276// =========================== 48277function processResponse(response) { 48278 if (response.message) { 48279 notify(response.message,response.status); 48280 } 48281 48282 if ( response.html ) { 48283 if (response.mode == "replace") { 48284 $($('[id="'+response.dom_id+'"]')).each(function(){ 48285 $(this).replaceWith(response.html) 48286 }) 48287 $('body').trigger('content_replaced'); 48288 } 48289 if (response.mode == "insert") { 48290 $($('[id="'+response.dom_id+'"]')).each(function(){ 48291 $(this).append(response.html); 48292 }) 48293 } 48294 // Special case: Remove image 48295 } else if (response.mode == "replace" && response.dom_id.indexOf("container_media") >= 0) { 48296 $($('[id="'+response.dom_id+'"]')).each(function(){ 48297 $(this).find('img').remove(); 48298 }) 48299 $('body').trigger('content_replaced'); 48300 } 48301 48302 if (response.mode == "remove") { 48303 $($('[id="'+response.dom_id+'"]')).each(function(){ 48304 $(this).slideUp(600, function(){ $(this).remove(); }); 48305 }) 48306 } 48307 48308 if (response.mode == "redirect") { 48309 window.location = response.url; 48310 } 48311 48312 $('.loading').removeClass("loading"); 48313 48314} 48315 48316$(document).ready(function(){ 48317 $(document).on('ajax:success', 'form[data-remote=true], a[data-remote=true]', function(evt, data, status, xhr) { 48318 processResponse(data); 48319 }); 48320 48321 48322 $(document).on('change', '.submit_onChange', function(event) { 48323 if ($("form#"+$(this).attr('form')).length > 0) { 48324 $("form#"+$(this).attr('form')).submit().addClass("loading"); 48325 } else { 48326 $(this).closest('form').submit().addClass("loading"); 48327 } 48328 $(this).addClass("loading"); 48329 if ($(this).hasClass('reload_onSubmit')) window.location.reload(); 48330 }); 48331 48332}); 48333 48334 48335// ======================= 48336// = cObject Fit support = 48337// ======================= 48338$(document).ready(function() { 48339 if ( ! Modernizr.objectfit ) { 48340 $('.feature-block__image .media, .banner__image .media').each(function () { 48341 var $container = $(this), 48342 imgUrl = $container.find('img').prop('src'); 48343 if (imgUrl) { 48344 $container 48345 .css('backgroundImage', 'url(' + imgUrl + ')') 48346 .addClass('compat-object-fit'); 48347 } 48348 }); 48349 } 48350}); 48351 48352 48353// ====================== 48354// = disable_with a tags = 48355// ====================== 48356// $(document).ready(function(){ 48357// $('a[data-disable-with]').click(function(){ 48358// $(this).text( $(this).data('disable-with') ); 48359// }); 48360// }); 48361 48362// ======================================= 48363// = common inline form show/hide events = 48364// ======================================= 48365 48366$(document).ready(function(){ 48367 48368 // $('input.telephone').mask("999-999-9999"); 48369 48370 // external links open in new window 48371 $("a[href^='http']").not("a[href*='grousemountain.com']").attr('target','_blank'); 48372 48373 48374 $('.inline_form').hide(); 48375 48376 // toggle open form 48377 $(document).on('click', '.show_inline_form', function(){ 48378 var form_id = $(this).attr('href'); 48379 if ( $(this).hasClass('open')) { 48380 $(form_id).parent().slideUp(); 48381 $(this).removeClass("open"); 48382 } else { 48383 $('.inline_form').slideUp(); // close all open forms 48384 $(form_id).parent().slideDown(); 48385 $(this).addClass("open"); 48386 } 48387 return false;
48388 }); 48389 48390 // close form on successful submission 48391 $(document).on('ajax:success', '.inline_form form[data-remote=true]', function(evt, data, status, xhr) { 48392 $('.inline_form').slideUp(); // close all open forms 48393 if ( $(this).hasClass('form_method_create')) { 48394 $(this).find('input').val(''); 48395 } 48396 }); 48397 48398 // close form on successful submission 48399 $(document).on('ajax:success', '#new_user', function(evt, data, status, xhr) { 48400 if (data.status == "exists") { 48401 $('.panel-login .step2').hide(); 48402 $('.panel-login .step_forgot').show(); 48403 } 48404 }); 48405 48406 $('.field.link_to div.opt2').hide(); 48407 $('body').on('click','.field.link_to a.opt2',function(){ 48408 $('.field.link_to div.opt1').hide(); 48409 $('.field.link_to div.opt2').show(); 48410 $('.field.link_to a').removeClass('active'); 48411 $(this).addClass('active'); 48412 }); 48413 $('body').on('click','.field.link_to a.opt1',function(){ 48414 $('.field.link_to div.opt2').hide(); 48415 $('.field.link_to div.opt1').show(); 48416 $('.field.link_to a').removeClass('active'); 48417 $(this).addClass('active'); 48418 }); 48419 48420}); 48421 48422 48423// ==================== 48424// = Full Screen BG's = 48425// ==================== 48426 48427jQuery.fn.full_screen_bg = function(url,gravity,slideshow,link_url, rate) { 48428 var $container = $(this); 48429 if (!gravity) { gravity = "c"; } 48430 48431 if ( $('#fsbg').length == 0 ) { 48432 var $bg_wrapper = $('<div/>',{ 48433 "id" : "fsbg", 48434 "class" : "media full_screen_bg" 48435 }); 48436 } else { 48437 var $bg_wrapper = $('#fsbg'); 48438 } 48439 48440 $container.prepend($bg_wrapper); 48441 48442 var img = new Image(); 48443 $(img).load(function() { 48444 $(this).hide(); 48445 $bg_wrapper.append(this); 48446 $(this).addClass(gravity); 48447 if ( link_url ) { 48448 $(this).click(function(){ 48449 window.location = link_url; 48450 }); 48451 $(this).css('cursor','pointer'); 48452 } 48453 // positionBackground(); 48454 if ( slideshow ) { 48455 if ( !$bg_wrapper.data('tsSlideshow') ) { 48456 if (!rate) { rate = 3 } 48457 $bg_wrapper.tsSlideshow({ rate: parseInt(rate) * 1000 } ); 48458 } 48459 } else { 48460 $(this).fadeIn(600,function(){ 48461 if (typeof firstVisit == 'function') { 48462 firstVisit(); 48463 } 48464 }); 48465 } 48466 }).attr('src', url); 48467 48468}; 48469 48470function pause_full_screen_bg() { 48471 if ( $('#fsbg').data('tsSlideshow') ) { 48472 $('#fsbg').tsSlideshow('stop'); 48473 } 48474} 48475 48476function resume_full_screen_bg() { 48477 if ( $('#fsbg').data('tsSlideshow') ) { 48478 $('#fsbg').tsSlideshow('start'); 48479 } 48480} 48481 48482function loadBackgrounds(editMode) { 48483 if (editMode == true) { 48484 var noCache = '?'+new Date().getTime(); 48485 } else { 48486 var noCache = ''; 48487 } 48488} 48489 48490function loadSidebarBanners(editMode) { 48491 if (editMode == true) { 48492 var noCache = '?'+new Date().getTime(); 48493 } else { 48494 var noCache = ''; 48495 } 48496} 48497 48498function positionBackground() { 48499 if ($('#fsbg img').length > 0) { 48500 var bg_height = $('#fsbg img').first().height(); 48501 if ( bg_height > 1000 ) { 48502 $('#site_container img.e, #site_container img.c, #site_container img.w').css('margin-top', "-" + (bg_height/2) + "px"); 48503 } 48504 } 48505} 48506 48507$(document).ready(function(){ 48508 48509 loadBackgrounds(); 48510 48511 // this may or may not be needed... 48512 $(window).resize(function() { 48513 positionBackground(); 48514 }); 48515 positionBackground(); 48516 48517 //$('#site_wide_alert').slideDown(); 48518}); 48519 48520// =============== 48521// = Grid Panels = 48522// =============== 48523 48524function closeGrid() { 48525 $('body').removeClass("panel_open"); 48526 $('#nav li').removeClass('active'); 48527 $('.panel').fadeOut(400); 48528 $('#pullout').animate({ 48529 left: '-762px' 48530 }, 400, function(){ 48531 $(this).removeClass("open"); 48532 $(this).find('.media .slideshow').cycle('pause'); 48533 resume_full_screen_bg(); 48534 }); 48535} 48536 48537function openGrid(panel_id) { 48538 if (!panel_id) { return false; } 48539 if (panel_id.match(/itinerary/)) { 48540 return false; 48541 } 48542 try { 48543 if ( $('#pullout #'+panel_id).length > 0 ) { 48544 $('body').addClass("panel_open"); 48545 $('.panel').fadeOut(400); 48546 $('#nav li').removeClass('active'); 48547 $('#nav a[href="#'+panel_id+'"]').closest('li').addClass('active'); 48548 $('#pullout').not('.open').animate({ 48549 left: '236px' 48550 }, 400, function() { 48551 $(this).addClass("open"); 48552 }); 48553 $('#pullout #'+panel_id).fadeIn(400, function(){ 48554 $(this).find('div.img').lazyLoadImages(); 48555 $(this).find('.media .slideshow').cycle('resume'); 48556 pause_full_screen_bg(); 48557 }); 48558 48559 //_gaq.push(['_trackEvent', 'Grids', panel_id]); 48560 if (typeof ga !== 'undefined') 48561 ga('send', 'event', panel_id, 'click', 'grid panels'); 48562 } 48563 } catch (e) { 48564 console.log('Failed to open grid', e); 48565 } 48566 48567} 48568 48569$(document).ready(function(){ 48570 48571 // pause all cycle slideshows 48572 if($('#pullout .media .slideshow').length > 0) 48573 $('#pullout .media .slideshow').cycle('pause'); 48574 48575 // Main Nav Links: Open panel or follow href 48576 $(document).on('click', '#nav.main-nav li a, a.open_grid, #pullout li a.cell_link', function(e) { 48577 var href = $(this).attr('href'); 48578 if (href && href.match(/^#/)) { 48579 // close if active 48580 if ( $(this).closest('li').hasClass('active') && $('#pullout').is('.o
48580pen') ) { 48581 closeGrid(); 48582 } else { 48583 // open pullout and show panel 48584 panel_id = href.replace(/^#/,"").replace(/\//, ""); 48585 openGrid(panel_id); 48586 if (typeof _gaq == 'object') { 48587 _gaq.push(['_trackPageview', href]); 48588 } 48589 } 48590 // return false; 48591 } 48592 if ( $('#pullout.edit-mode').length == 0 ) { 48593 window.location = href; 48594 } 48595 return false; 48596 }); 48597 48598 // Close Panel Button 48599 $(document).on('click', '.panel a.close_panel', function(event) { 48600 closeGrid(); 48601 }); 48602 48603 // if url includes hash, open grid 48604 var current_hash = location.hash.replace(/\?.*$/, ''); 48605 if (current_hash.length > 0) { 48606 grid = current_hash.replace(/^#/,""); 48607 grid = grid.replace(/\//,""); 48608 openGrid(grid); 48609 } 48610 48611 // // toggle grids: hide grid menu links & create toggle button 48612 48613 $('#nav a:contains("|")').each(function(){ 48614 $(this).hide(); 48615 var labels = $(this).text().split("|"); 48616 var ids = []; 48617 $('#nav a:contains('+labels[0]+')').each(function(){ 48618 ids.push($(this).attr('href')); 48619 }); 48620 $('#nav a:contains('+labels[0]+')').each(function(){ 48621 var cur = $(this).attr('href'); 48622 var list = $('<ul/>',{ 48623 "class" : "toggle" 48624 }); 48625 for (var i=1; i<labels.length; i++) { 48626 var list_item = $('<li/>',{ 48627 "class": "t"+i 48628 }); 48629 var link = $('<a/>',{ 48630 href : ids[i-1], 48631 text : labels[i], 48632 click : function(){ 48633 openGrid( $(this).attr('href').replace(/^#/,"") ); 48634 } 48635 }); 48636 list_item.append(link); 48637 list_item.appendTo(list); 48638 } 48639 $(cur+' .title').append(list); 48640 }); 48641 }); 48642 48643 // =================== 48644 // = end grid panels = 48645 // =================== 48646 48647 48648 // ==================================== 48649 // = ecom category page tag filtering = 48650 // ==================================== 48651 $('#filter_by_tag a.filter_by').click(function(){ 48652 var tag = $(this).data('tag'); 48653 var rxp = new RegExp(tag) 48654 48655 48656 $('#category-list li').each(function(){ 48657 $(this).data('tags').match(rxp) ? $(this).show() : $(this).hide(); 48658 }); 48659 48660 $('#filter_by_tag a.filter_by').removeClass("active"); 48661 $(this).addClass("active"); 48662 return false; 48663 }); 48664 48665 48666 48667 // other stuff. should be moved somewhere more logical 48668 48669 48670 $('.dropdowns div').hide(); 48671 $('.dropdowns a').click(function() { 48672 48673 var href = $(this).attr('href'); 48674 //$('.dropdowns .terms').slideToggle(); 48675 48676 if (href.match(/^#/)) { 48677 48678 href = href.replace(/^#/,""); 48679 $('.dropdowns a').removeClass('active'); 48680 $(this).addClass('active'); 48681 48682 $('.dropdowns div.'+href).slideToggle(); 48683 return false; 48684 48685 } 48686 }); 48687 48688 // Share Tab on Pages 48689 $('#main li.share a').click(function(){ 48690 if ( $('#share_box').hasClass("visible") ) { 48691 $('#share_box').slideUp().removeClass("visible"); 48692 $(this).removeClass("active"); 48693 } else { 48694 if ( $('#share_box').length == 0 ) { 48695 48696 var addthis_buttons = $('<!-- AddThis Button BEGIN --> \ 48697 <div class="addthis_toolbox addthis_default_style addthis_32x32_style"> \ 48698 <a class="addthis_button_facebook"></a> \ 48699 <a class="addthis_button_twitter"></a> \ 48700 <a class="addthis_button_pinterest_share"></a> \ 48701 <a class="addthis_button_google_plusone_share"></a> \ 48702 <a class="addthis_button_compact"></a><a class="addthis_counter addthis_bubble_style"></a> \ 48703 </div> \ 48704 <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-536803930156f630"></script> \ 48705 <!-- AddThis Button END -->'); 48706 var addthis = $('<li class="addthis"/>').append(addthis_buttons); 48707 48708 var pdf_button = $('<a/>', { 48709 "href" : window.location+".pdf", 48710 "text" : "Download a PDF of this page." 48711 }); 48712 var pdf = $('<li class="pdf"/>').append(pdf_button); 48713 48714 var share_button = $('<ul/>',{ 48715 "id" : "share_box", 48716 "class" : "share_box" 48717 }).hide().append(addthis,pdf).insertAfter($(this)); 48718 48719 // position off left or right side of link 48720 var offset = $(this).position(); 48721 if (offset.left < (422 - 109)) { 48722 share_button.css({ 48723 left: offset.left 48724 }); 48725 } else { 48726 share_button.css({ 48727 left: offset.left - 422 + 109 48728 }); 48729 } 48730 48731 } 48732 $('#share_box').slideDown().addClass("visible"); 48733 $(this).addClass("active"); 48734 } 48735 return false;
48736 }); 48737 48738 $('#main .menubar li.active').click(function(e){ 48739 e.preventDefault(); 48740 var tabs = $('#main .menubar li:not(.active)'); 48741 if ($(this).hasClass('open')) { 48742 tabs.slideUp(); 48743 $(this).removeClass('open'); 48744 } else { 48745 tabs.slideDown(); 48746 $(this).addClass('open'); 48747 } 48748 }); 48749 48750 // Footer Widgets 48751 $('#widget_triggers').tsWidgets(); 48752 48753 // Grind Time Lazy Load 48754 $('#footer a.grind:not(.snowshoe-grind) span.grind_time').load('/grind_stats/widget?top_time=true'); 48755 $('#widget_grind .live_times').load('/grind_stats/widget'); 48756 48757 // Footer News Rotation 48758 if($('#js-news-rotate').length > 0) 48759 $('#js-news-rotate').cycle({ 48760 containerResize: 0, 48761 slideResize: 0 48762 }); 48763 48764 // ==================== 48765 // = Placeholder Text = 48766 // ==================== 48767 48768 // store default values 48769 $('.placeholder').each(function(){ 48770 $(this).data('placeholder', $(this).val()); 48771 }); 48772 48773 // remove placeholder on focus 48774 $('.placeholder').focus(function(){ 48775 if ($(this).val() == $(this).data('placeholder') ) { 48776 $(this).val(""); 48777 } 48778 }); 48779 48780 // restore placeholder on blur 48781 $('.placeholder').blur(function(){ 48782 if ($(this).val() == "" ) { 48783 $(this).val( $(this).data('placeholder') ); 48784 } 48785 }); 48786 48787}); 48788 48789// ====================================== 48790// = other dev code that needs clean up = 48791// ====================================== 48792 48793$(document).ready(function(){ 48794 48795 // checkout login - forgot password 48796 $(document).on('click', '#login_signup a.forgot_password', function(){ 48797 $(this).closest('form').slideUp(); 48798 $('#login_signup .step_forgot').slideDown(); 48799 return false; 48800 }); 48801 $(document).on('click', '#login_signup a.show_login', function(){ 48802 $('#login_signup .step_forgot').slideUp(); 48803 $('form#user_login').slideDown(); 48804 return false; 48805 }); 48806 48807 $("#pullout .panel li a").hover( 48808 function () { 48809 $(this).find("div.grid_caption").animate({ 48810 bottom: '-5px' 48811 }, 200, function() { 48812 // Animation complete. 48813 }); 48814 }, 48815 function () { 48816 $(this).find("div.grid_caption").animate({ 48817 bottom: '-56px' 48818 }, 100, function() { 48819 // Animation complete. 48820 }); 48821 } 48822 ); 48823 48824 48825 48826 /* ADMINISTRATIVE JS BELOW -- TO BE MOVED TO APP-ADMIN.JS */ 48827 48828 48829 48830 $('.gallery .slide_nav a').hide(); 48831 48832 $('.gallery .slide_contain').hover( 48833 function () { 48834 $('.gallery .slide_nav a').fadeIn(500); 48835 }, 48836 function () { 48837 $('.gallery .slide_nav a').fadeOut(300); 48838 } 48839 ); 48840 48841 48842 $('.datetimepicker').livequery(function(){ 48843 $(this).datetimepicker({ 48844 ampm: true, 48845 dateFormat: 'yy-mm-dd' 48846 }); 48847 }); 48848 $('.datepicker').livequery(function(){ 48849 $(this).datepicker({ 48850 dateFormat: 'yy-mm-dd' 48851 }); 48852 }); 48853 48854}); 48855 48856// ============================ 48857// = TopNav AJAX = 48858// ============================ 48859$(document).ready(function() { 48860 48861 // TOGGLE TRANSACTIONS IN MY ACCOUNT 48862 $(document).on('click', '.transaction h4', function(){ 48863 if ($(this).closest('#offline_sales').length > 0 && !$(this).data('loaded')) { 48864 var self = $(this); 48865 self.siblings('ul').addClass('loading'); 48866 $.ajax({ 48867 url: self.data('summary'), 48868 type: 'get', 48869 dataType: 'json', 48870 success: function(data) { 48871 self.data('loaded', true); 48872 self.siblings('ul').replaceWith($(data.html)); 48873 self.siblings('ul').show(); 48874 }, 48875 error: function() { 48876 } 48877 }); 48878 } 48879 $(this).siblings('ul').slideToggle(); 48880 $(this).toggleClass('open'); 48881 return false; 48882 }); 48883 48884 // SHOW PASSWORD FORM IN ACCOUNT EDIT MODE 48885 $('form.change_password').hide(); 48886 $('h3 a.change').click(function(){ 48887 $(this).parent('h3').siblings('form.change_password').slideToggle(); 48888 return false; 48889 }); 48890 48891 // SHOW/HIDE FOR ACCOUNT LOGIN PANEL 48892 $('.panel-login a.show_new_account').click(function(){ 48893 $('.panel-login .step1').hide(); 48894 $('.panel-login .step2').show(); 48895 $('.panel-login .step_forgot').hide(); 48896 }); 48897 48898 // SHOW/HIDE FOR ACCOUNT LOGIN PANEL 48899 $('.panel-login .step2').hide(); 48900 $('.panel-login .step3').hide(); 48901 $('.panel-login .step1 a.btn').click(function(){ 48902 $('.panel-login .step1').fadeOut(200); 48903 $('.panel-login .step2').delay(200).fadeIn(200); 48904 }); 48905 48906 $('.panel-login .step2 a.btn').click(function(){ 48907 $('.panel-login .step2').fadeOut(200); 48908 $('.panel-login .step3').delay(200).fadeIn(200); 48909 }); 48910 48911 $('.acct_options li a, a.show_login').click(function(){ 48912 $('.panel-login .step1').show(); 48913 $('.panel-login .step2').hide(); 48914 $('.panel-login .step3').hide(); 48915 $('.panel-login .step_forgot').hide(); 48916 }); 48917 48918 $('.panel-login a.forgot').click(function(){ 48919 // $('.panel-login .step1').hide(); 48920 // $('.panel-login .step_forgot').show(); 48921 }); 48922 48923 // $('.panel-login .step_forgot form button').click(function(){ 48924 // $('.panel-login .enter_pass').hide(); 48925 // $('.panel-login .msg_success').show(); 48926 // }); 48927 48928 // $('.panel-balance .step1 form button').click(function(){ 48929 // $('.panel-balance .step1').fadeOut(200); 48930 // $('.panel-balance .step2').delay(250).fadeIn(200); 48931 // }); 48932 48933 $('.ccv_btn').click(function(){ 48934 $('#ccv').slideToggle(); 48935 return false;
48936 }); 48937 $('#ccv a.close').click(function(){ 48938 $('#ccv').slideUp(); 48939 return false; 48940 }); 48941 $('#cc_cvv').keydown(function(){ 48942 $('#ccv').slideUp(); 48943 }); 48944 48945 //REVEAL FORM TO CONNECT NEW PASS IN MY ACCOUNT 48946 // $('.passes a.add').click(function(e){ 48947 // e.preventDefault(); 48948 // $('.passes form.connect_pass').slideDown(); 48949 // // $('.passes p.description').hide(); 48950 // return false; 48951 // }); 48952 48953 $('.acct_options li a').hover(function(){ 48954 $(this).find('span.hover').css('display','block'); 48955 $(this).find('span.hover').delay(220).animate({ 48956 top: 32, 48957 opacity: 100 48958 }, 300 ); 48959 }, function(){ 48960 $(this).find('span.hover').animate({ 48961 top: 28, 48962 opacity: 0 48963 }, 300 ); 48964 $(this).find('span.hover').css('display','none'); 48965 }); 48966 48967 // MOUNTAIN MAP POPUP NAVIGATION 48968 $('.points li a.dot').click(function(){ 48969 $('.popup').fadeOut(400); 48970 $('.popup').css('z-index','1'); 48971 $('#mm_legend li a').removeClass('active'); 48972 $(this).siblings('.popup').fadeIn(400); 48973 48974 $('#mm_view .points li').css('z-index','5'); 48975 $(this).parent('li').css('z-index','10'); 48976 48977 $('#mm_view .points li .popup').css('z-index','10'); 48978 $(this).siblings('.popup').css('z-index','20'); 48979 48980 return false; 48981 }); 48982 48983 $('#points li a.dot').click(function(){ 48984 48985 $('.popup').fadeOut(400); 48986 $('.popup').css('z-index','1'); 48987 $('#mm_legend li a').removeClass('active'); 48988 $(this).siblings('.popup').fadeIn(400); 48989 48990 $('#mm_view #points li').css('z-index','5'); 48991 $(this).parent('li').css('z-index','10'); 48992 48993 $('#mm_view #points li .popup').css('z-index','10'); 48994 $(this).siblings('.popup').css('z-index','20'); 48995 48996 return false; 48997 }); 48998 48999 $('#mm_legend li a').click(function() { 49000 var href = $(this).attr('href'); 49001 href = href.replace(/^#/,""); 49002 $('#mm_legend li a').removeClass('active'); 49003 $(this).addClass('active'); 49004 $('.popup').fadeOut(400); 49005 $('.popup').css('z-index','1'); 49006 $('#mm_view #points #'+href+' .popup').fadeIn(400); 49007 $('#mm_view #points li').css('z-index','5'); 49008 $('#mm_view #points #'+href).css('z-index','10'); 49009 $('#mm_view #points li .popup').css('z-index','10'); 49010 $('#mm_view #points #'+href+' .popup').css('z-index','20'); 49011 return false; 49012 }); 49013 49014 $('.mountain_map img.view').click(function() { 49015 $('.popup').fadeOut(400); 49016 }); 49017 49018 $('.conditions_tabs ul.tabs a').click(function(){ 49019 $('.tab_container .tab').fadeOut(300); 49020 $('.conditions_tabs ul.tabs a').removeClass('active'); 49021 $(this).addClass('active'); 49022 var href = $(this).attr('href'); 49023 href = href.replace(/^#/,""); 49024 $('.tab_container #'+href).delay(350).fadeIn(400); 49025 return true; 49026 }); 49027 49028 if($("#main.current_conditions .cycle").length > 0) 49029 $("#main.current_conditions .cycle").cycle(); 49030 49031 // $('.tab_container tr:even').addClass('odd'); 49032 $('.now a.view').click(function(){ 49033 $('.tab_container .tab').fadeOut(300); 49034 $('.tab_container #forecast').delay(350).fadeIn(400); 49035 $('.conditions_tabs ul.tabs a').removeClass('active'); 49036 $('ul.tabs a[href=#forecast]').addClass('active'); 49037 return false; 49038 }); 49039 49040 // Current Conditions Metric/Imperial Toggle 49041 $('#units_toggle .show_metric a').click(function(){ 49042 $('#main.current_conditions .imperial, .feature-block--snow-report .imperial').fadeOut(500, function(){ 49043 $('#main.current_conditions .metric, .feature-block--snow-report .metric').fadeIn(500); 49044 }); 49045 $('#units_toggle li').removeClass('active'); 49046 $(this).parent().addClass('active'); 49047 return false; 49048 }); 49049 $('#units_toggle .show_imperial a').click(function(){ 49050 $('#main.current_conditions .metric, .feature-block--snow-report .metric').fadeOut(500, function(){ 49051 $('#main.current_conditions .imperial, .feature-block--snow-report .imperial').fadeIn(500); 49052 }); 49053 $('#units_toggle li').removeClass('active'); 49054 $(this).parent().addClass('active'); 49055 return false; 49056 }); 49057 49058 // Current conditions modal livecam/gallery toggle 49059 // $('.visual_toggle a').on("click", function(){ 49060 // if ($(this).parent().hasClass('active')) { 49061 // $("#visual-modal").modal('show'); 49062 // } else { 49063 // var target = $(this).data('target'); 49064 // var that = $(this).attr('href'); 49065 49066 // $('.visuals > div').fadeOut(300); 49067 // $('.visuals .'+target).delay(301).fadeIn(300); 49068 // $('.visual_toggle li').removeClass('active'); 49069 // $('.visual_toggle li.'+target).addClass('active'); 49070 // } 49071 // return false; 49072 // }); 49073 49074 $("#livecam_btn").on("click", function(){ 49075 $("#livecam_holder").html('<iframe src="/grouse_livecam_html.html" width="640" height="480" alt="" seamless></iframe>'); 49076 }); 49077 49078 // $("#livecam_btn").click(function(){ 49079 // $('.visuals > div').fadeOut(300); 49080 // $('.visuals .livecam').delay(301).fadeIn(300); 49081 // $('.visual_toggle li').removeClass('active'); 49082 // $('.visual_toggle li.livecam').addClass('active'); 49083 // }); 49084 // $("#recent-gallery").click(function(){ 49085 // $('.visuals > div').fadeOut(300); 49086 // $('.visuals .recent-gallery').delay(301).fadeIn(300); 49087 // $('.visual_toggle li').removeClass('active'); 49088 // $('.visual_toggle li.recent-gallery').addClass('active'); 49089 // }); 49090 49091 if($('#summer_events .attractions').length > 0) 49092 $('#summer_events .attractions').cycle({ 49093 fx: 'scrollLeft', 49094 timeout: 6400,
49095 speed: 800 49096 }); 49097 49098 $('#season_toggle a').click(function(){ 49099 $('#season_toggle li').toggleClass("active"); 49100 $(".season_toggle").toggle("slow"); 49101 // if ( $(this).attr('href') == "#snow" ) { 49102 // $('#summer_events .attractions').cycle('pause'); 49103 // } else { 49104 // $('#summer_events .attractions').cycle('resume'); 49105 // } 49106 return false; 49107 }); 49108 49109 49110 // lazy load mini cart 49111 $('#nav li.n_cart_trigger a').bind('click',function(){ 49112 if (!$.trim( $('#cart_preview').html() ).length) { 49113 $('#cart_preview').load('/cart/mini_cart'); 49114 } 49115 }); 49116 49117}); 49118 49119// mini cart badge 49120function updateMiniCartBadge() { 49121 $.getJSON('/cart/mini_cart_badge', function(data) { 49122 $("#mini_cart_badge").text(data.count) 49123 }); 49124} 49125 49126// ==================================== 49127// = Custom global validation methods = 49128// ==================================== 49129 49130// Add method to validate phone number 49131jQuery.validator.addMethod("phoneno", function(phone_number, element) { 49132 phone_number = phone_number.replace(/\s+/g, ""); 49133 return this.optional(element) || phone_number.length > 9 && phone_number.length < 16 49134 phone_number.match(/^((\+[1-9]{1,4}[ \-]*)|(\([0-9]{2,3}\)[ \-]*)|([0-9]{2,4})[ \-]*)*?[0-9]{3,4}?[ \-]*[0-9]{3,4}?$/); 49135}, "Please specify a valid phone number"); 49136 49137 49138// ========================== 49139// = Photo form item helper = 49140// ========================== 49141 49142$(document).ready(function(){ 49143 49144 function readPhotoURL(input) { 49145 if (input.files && input.files[0]) { 49146 var reader = new FileReader(); 49147 49148 reader.onload = function (e) { 49149 $(input).siblings('.form-item--photo-preview').find('img').attr('src', e.target.result); 49150 } 49151 49152 reader.readAsDataURL(input.files[0]); 49153 49154 $(input).siblings('input').val(''); 49155 } 49156 } 49157 49158 $('.form-item--photo-upload input').change(function(){ 49159 readPhotoURL(this); 49160 }); 49161 49162}); 49163 49164 49165$(document).on('click', '.collapsible-form-item', function() { 49166 $(this).siblings('.collapsible-form-item--form').slideToggle(); 49167 $(this).find('i').toggleClass('icon-plus icon-minus'); 49168}); 49169 49170 49171// ========================== 49172// = Responsive image maps = 49173// ========================== 49174$(document).ready(function(){ 49175 $('map').imageMapResize(); 49176}); 49177 49178// ========================== 49179// = Collapsible menubar on mobile= 49180// ========================== 49181$(document).ready(function() { 49182 if ($(window).width() < 720) { 49183 $('ul.menubar').addClass('collapsible'); 49184 } 49185}); 49186 49187 49188// ========================== 49189// = Helper = 49190// ========================== 49191function urlHasParam(name){ 49192 var results = new RegExp('[\?&]' + name + '([^]*)').exec(window.location.href); 49193 if (results==null){ 49194 return false; 49195 } 49196 else{ 49197 return true; 49198 } 49199} 49200 49201function getFormattedDate(date) { 49202 let year = date.getFullYear(); 49203 let month = (1 + date.getMonth()).toString().padStart(2, '0'); 49204 let day = date.getDate().toString().padStart(2, '0'); 49205 49206 return year + '-' + month + '-' + day; 49207} 49208 49209function activityDateAvailable(date, start, end, days, blackouts) { 49210 var formatted_date = getFormattedDate(date); 49211 var show = true; 49212 49213 if (start !== '') 49214 show = formatted_date >= start 49215 49216 if (show && end !== '') 49217 show = formatted_date <= end 49218 49219 if (show && days && days !== ''){ 49220 show = $.inArray(date.getDay().toString(), days.toString().split(',')) !== -1; 49221 } 49222 49223 if (show && blackouts && blackouts.length > 0) { 49224 49225 for (var i = 0; i < blackouts.length; ++i) { 49226 if (blackouts[i][0] <= formatted_date && blackouts[i][1] >= formatted_date) { 49227 show = false; 49228 break; 49229 } 49230 } 49231 } 49232 49233 return show; 49234} 49235 49236 49237// ========================== 49238// = IE 11 Compatibility = 49239// ========================== 49240if (!String.prototype.padStart) { 49241 String.prototype.padStart = function padStart(targetLength,padString) { 49242 targetLength = targetLength>>0; //truncate if number or convert non-number to 0; 49243 padString = String((typeof padString !== 'undefined' ? padString : ' ')); 49244 if (this.length > targetLength) { 49245 return String(this); 49246 } 49247 else { 49248 targetLength = targetLength-this.length; 49249 if (targetLength > padString.length) { 49250 padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed 49251 }
49252 return padString.slice(0,targetLength) + String(this); 49253 } 49254 }; 49255} 49256 49257 49258 49259 49260 49261 49262; 49263// ====================== 49264// = Mobile Menu Toggle = 49265// ====================== 49266 49267$(document).ready(function() { 49268 49269 $('.js-menu-main-toggle').on('click', function() { 49270 $(this).toggleClass('js-menu-main-toggle-active'); 49271 $(this).toggleClass('menu--main__toggle--active'); 49272 $('.layout-container-inner, .menu--main').toggleClass('menu--active'); 49273 }); 49274 49275 $('.layout-container-inner.menu--active').on('click', function() { 49276 $('.menu--main__toggle').removeClass('js-menu-main-toggle-active'); 49277 $('.menu--main__toggle').removeClass('menu--main__toggle--active'); 49278 $('.layout-container-inner, .menu--main').removeClass('menu--active'); 49279 }); 49280 49281}); 49282 49283// ====================== 49284// = Sticky Menu Header = 49285// ====================== 49286 49287$(window).bind('scroll', function () { 49288 if ($(window).scrollTop() > ($(window).height() / 2.5) && $('#header:not(.scrolling)')) { 49289 $('#header, .layout-container').addClass('scrolling'); 49290 } else { 49291 $('#header, .layout-container').removeClass('scrolling'); 49292 } 49293}); 49294 49295// ================= 49296// = Mega Sub Menu = 49297// ================= 49298 49299$(document).ready(function() { 49300 49301 if ($(window).width() > 1069) { 49302 49303 $('.menu-level-1 > li').on('mouseover', function() { 49304 $(this).find('.menu-level-2').addClass('menu-level-2--active'); 49305 }); 49306 $('.menu-level-1 > li').on('mouseout', function() { 49307 $(this).find('.menu-level-2').removeClass('menu-level-2--active'); 49308 }); 49309 $('.menu--secondary-level-1 > li').on('mouseover', function() { 49310 $(this).find('.menu--secondary-level-2').addClass('menu--secondary-level-2--active'); 49311 }); 49312 $('.menu--secondary-level-1 > li').on('mouseout', function() { 49313 $(this).find('.menu--secondary-level-2').removeClass('menu--secondary-level-2--active'); 49314 }); 49315 49316 49317 } else { 49318 49319 $('.js-menu-item-toggle').on('click', function(event) { 49320 $(this).toggleClass('js-menu-toggle-active'); 49321 $(this).toggleClass('menu__button-toggle--active'); 49322 $(this).parents('li').toggleClass('js-menu-toggle-active').find('.menu-level-2').slideToggle('fast'); 49323 }); 49324 49325 } 49326 49327}); 49328 49329// =============== 49330// = Menu Search = 49331// =============== 49332 49333$(document).ready(function() { 49334 49335 $('.js-menu-search').on('click', function() { 49336 if ($(this).hasClass('js-menu-search-active')) { 49337 $(this).removeClass('js-menu-search-active'); 49338 $('.menu-search').removeClass('menu-search--active'); 49339 } else { 49340 $(this).addClass('js-menu-search-active'); 49341 $('.menu-search').addClass('menu-search--active'); 49342 } 49343 }); 49344 $('.js-menu-search-close').on('click', function() { 49345 $('.js-menu-search').removeClass('js-menu-search-active'); 49346 $('.menu-search').removeClass('menu-search--active'); 49347 }); 49348 49349}); 49350 49351// ===================== 49352// = Menu Active State = 49353// ===================== 49354 49355$(document).ready(function(){ 49356 $('nav a[href="' + location.pathname + '"]').addClass('active'); 49357}); 49358 49359// ======================= 49360// = In page link scroll = 49361// ======================= 49362 49363$(document).ready(function(){ 49364 // $('a[href^="' + window.location.pathname + '#"]').on('click', function(event) { 49365 // var target = $(this.getAttribute('href')); 49366 // if(target.length) { 49367 // event.preventDefault(); 49368 // var targetOffset = target.offset().top; 49369 // $('html, body').stop().animate({ 49370 // scrollTop: targetOffset - 80 49371 // }, 800); 49372 // } 49373 // }); 49374 //$('html, body').hide(); 49375 49376 // if (window.location.hash) { 49377 // setTimeout(function() { 49378 // $('html, body').scrollTop().show(); 49379 // $('html, body').animate({ 49380 // scrollTop: $(window.location.hash).offset().top 49381 // }, 1000) 49382 // }, 0); 49383 // } 49384 // else { 49385 // $('html, body').show(); 49386 // } 49387 49388 function getUrlVars() { 49389 var vars = [], hash; 49390 var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); 49391 for(var i = 0; i < hashes.length; i++) { 49392 hash = hashes[i].split('='); 49393 vars.push(hash[0]); 49394 vars[hash[0]] = hash[1]; 49395 } 49396 return vars; 49397 } 49398 49399 var hash = window.location.hash; 49400 49401 if (hash) { 49402 49403 var hashOnly = hash.split('?')[0]; 49404 49405 setTimeout(function() {
49406 try { 49407 $('html, body').animate({ 49408 scrollTop: $(hashOnly).offset().top - 135 49409 }, 1000) 49410 } catch (e) { 49411 console.log('Failed to trigger ScrollTop', e); 49412 } 49413 }, 500); 49414 49415 // Active targeted tab 49416 if (hash.indexOf("?tab") >= 0) { 49417 var tab = getUrlVars()["tab"]; 49418 $(".tab_container").find(".tab").hide(); 49419 $(".tab_container").find(".tab"+ '#' + tab).show(); 49420 $("ul.tabs").find('li a.active').removeClass("active"); 49421 $("ul.tabs").find('li a[href$="' + '#' + tab + '"]').addClass("active"); 49422 } 49423 49424 } 49425 49426}); 49427 49428 49429$(document).ready(function(){ 49430 if($('#plan_your_day_quiz').length) { 49431 49432 // setup the navigation 49433 $('.quiz_question').first().show(); 49434 $('.submit_quiz').last().show(); 49435 $('a.next_question').last().hide(); 49436 49437 // move to the next section 49438 $('a.next_question').click(function(e) { 49439 e.preventDefault(); 49440 var this_question = $(this).closest('.quiz_question') 49441 if (this_question.find('input:checked').length) { 49442 var current_index = this_question.attr('id').replace("quiz_question_",""); 49443 this_question.hide(); 49444 $('#quiz_question_' + (parseInt(current_index) + 1)).show(); 49445 } 49446 }); 49447 } 49448}); 49449/* Simple JavaScript Inheritance 49450 * By John Resig http://ejohn.org/ 49451 * MIT Licensed. 49452 */ 49453// Inspired by base2 and Prototype 49454(function(){ 49455 var initializing = false; 49456 49457 // The base JQClass implementation (does nothing) 49458 window.JQClass = function(){}; 49459 49460 // Collection of derived classes 49461 JQClass.classes = {}; 49462 49463 // Create a new JQClass that inherits from this class 49464 JQClass.extend = function extender(prop) { 49465 var base = this.prototype; 49466 49467 // Instantiate a base class (but only create the instance, 49468 // don't run the init constructor) 49469 initializing = true; 49470 var prototype = new this(); 49471 initializing = false; 49472 49473 // Copy the properties over onto the new prototype 49474 for (var name in prop) { 49475 // Check if we're overwriting an existing function 49476 prototype[name] = typeof prop[name] == 'function' && 49477 typeof base[name] == 'function' ? 49478 (function(name, fn){ 49479 return function() { 49480 var __super = this._super; 49481 49482 // Add a new ._super() method that is the same method 49483 // but on the super-class 49484 this._super = function(args) { 49485 return base[name].apply(this, args || []); 49486 }; 49487 49488 var ret = fn.apply(this, arguments); 49489 49490 // The method only need to be bound temporarily, so we 49491 // remove it when we're done executing 49492 this._super = __super; 49493 49494 return ret; 49495 }; 49496 })(name, prop[name]) : 49497 prop[name]; 49498 } 49499 49500 // The dummy class constructor 49501 function JQClass() { 49502 // All construction is actually done in the init method 49503 if (!initializing && this._init) { 49504 this._init.apply(this, arguments); 49505 } 49506 } 49507 49508 // Populate our constructed prototype object 49509 JQClass.prototype = prototype; 49510 49511 // Enforce the constructor to be what we expect 49512 JQClass.prototype.constructor = JQClass; 49513 49514 // And make this class extendable 49515 JQClass.extend = extender; 49516 49517 return JQClass; 49518 }; 49519})(); 49520 49521(function($) { // Ensure $, encapsulate 49522 49523 /** Abstract base class for collection plugins v1.0.1. 49524 Written by Keith Wood (kbwood{at}iinet.com.au) December 2013. 49525 Licensed under the MIT (http://keith-wood.name/licence.html) license. 49526 @module $.JQPlugin 49527 @abstract */ 49528 JQClass.classes.JQPlugin = JQClass.extend({ 49529 49530 /** Name to identify this plugin. 49531 @example name: 'tabs' */ 49532 name: 'plugin', 49533 49534 /** Default options for instances of this plugin (default: {}). 49535 @example defaultOptions: { 49536 selectedClass: 'selected', 49537 triggers: 'click' 49538 } */ 49539 defaultOptions: {}, 49540 49541 /** Options dependent on the locale. 49542 Indexed by language and (optional) country code, with '' denoting the default language (English/US). 49543 @example regionalOptions: { 49544 '': { 49545 greeting: 'Hi' 49546 } 49547 } */ 49548 regionalOptions: {}, 49549 49550 /** Names of getter methods - those that can't be chained (default: []). 49551 @example _getters: ['activeTab'] */ 49552 _getters: [], 49553 49554 /** Retrieve a marker class for affected elements. 49555 @private 49556 @return {string} The marker class. */ 49557 _getMarker: function() { 49558 return 'is-' + this.name; 49559 }, 49560 49561 /** Initialise the plugin. 49562 Create the jQuery bridge - plugin name <code>xyz</code> 49563 produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */ 49564 _init: function() { 49565 // Apply default localisations 49566 $.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {}); 49567 // Camel-case the name 49568 var jqName = camelCase(this.name); 49569 // Expose jQuery singleton manager 49570 $[jqName] = this; 49571 // Expose jQuery collection plugin 49572 $.fn[jqName] = function(options) { 49573 var otherArgs = Array.prototype.slice.call(arguments, 1); 49574 if ($[jqName]._isNotChained(options, otherArgs)) { 49575 return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs)); 49576 } 49577 return this.each(function() { 49578 if (typeof options === 'string') { 49579 if (options[0] === '_' || !$[jqName][options]) { 49580 throw 'Unknown method: ' + options; 49581 } 49582 $[jqName][options].apply($[jqName], [this].concat(otherArgs)); 49583 } 49584 else { 49585 $[jqName]._attach(this, options); 49586 } 49587 }); 49588 }; 49589 }, 49590 49591 /** Set default values for all subsequent instances. 49592 @param options {object} The new default options. 49593 @example $.plugin.setDefauls({name: value}) */ 49594 setDefaults: function(options) { 49595 $.extend(this.defaultOptions, options || {}); 49596 }, 49597 49598 /** Determine whether a method is a getter and doesn't permit chaining. 49599 @private 49600 @param name {string}
49600 The method name. 49601 @param otherArgs {any[]} Any other arguments for the method. 49602 @return {boolean} True if this method is a getter, false otherwise. */ 49603 _isNotChained: function(name, otherArgs) { 49604 if (name === 'option' && (otherArgs.length === 0 || 49605 (otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) { 49606 return true; 49607 } 49608 return $.inArray(name, this._getters) > -1; 49609 }, 49610 49611 /** Initialise an element. Called internally only. 49612 Adds an instance object as data named for the plugin. 49613 @param elem {Element} The element to enhance. 49614 @param options {object} Overriding settings. */ 49615 _attach: function(elem, options) { 49616 elem = $(elem); 49617 if (elem.hasClass(this._getMarker())) { 49618 return; 49619 } 49620 elem.addClass(this._getMarker()); 49621 options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {}); 49622 var inst = $.extend({name: this.name, elem: elem, options: options}, 49623 this._instSettings(elem, options)); 49624 elem.data(this.name, inst); // Save instance against element 49625 this._postAttach(elem, inst); 49626 this.option(elem, options); 49627 }, 49628 49629 /** Retrieve additional instance settings. 49630 Override this in a sub-class to provide extra settings. 49631 @param elem {jQuery} The current jQuery element. 49632 @param options {object} The instance options. 49633 @return {object} Any extra instance values. 49634 @example _instSettings: function(elem, options) { 49635 return {nav: elem.find(options.navSelector)}; 49636 } */ 49637 _instSettings: function(elem, options) { 49638 return {}; 49639 }, 49640 49641 /** Plugin specific post initialisation. 49642 Override this in a sub-class to perform extra activities. 49643 @param elem {jQuery} The current jQuery element. 49644 @param inst {object} The instance settings. 49645 @example _postAttach: function(elem, inst) { 49646 elem.on('click.' + this.name, function() { 49647 ... 49648 }); 49649 } */ 49650 _postAttach: function(elem, inst) { 49651 }, 49652 49653 /** Retrieve metadata configuration from the element. 49654 Metadata is specified as an attribute: 49655 <code>data-<plugin name>="<setting name>: '<value>', ..."</code>. 49656 Dates should be specified as strings in this format: 'new Date(y, m-1, d)'. 49657 @private 49658 @param elem {jQuery} The source element. 49659 @return {object} The inline configuration or {}. */ 49660 _getMetadata: function(elem) { 49661 try { 49662 var data = elem.data(this.name.toLowerCase()) || ''; 49663 data = data.replace(/'/g, '"'); 49664 data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) { 49665 var count = data.substring(0, i).match(/"/g); // Handle embedded ':' 49666 return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':'); 49667 }); 49668 data = $.parseJSON('{' + data + '}'); 49669 for (var name in data) { // Convert dates 49670 var value = data[name]; 49671 if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) { 49672 data[name] = eval(value); 49673 } 49674 } 49675 return data; 49676 } 49677 catch (e) { 49678 return {}; 49679 } 49680 }, 49681 49682 /** Retrieve the instance data for element. 49683 @param elem {Element} The source element. 49684 @return {object} The instance data or {}. */ 49685 _getInst: function(elem) { 49686 return $(elem).data(this.name) || {}; 49687 }, 49688 49689 /** Retrieve or reconfigure the settings for a plugin. 49690 @param elem {Element} The source element. 49691 @param name {object|string} The collection of new option values or the name of a single option. 49692 @param [value] {any} The value for a single named option. 49693 @return {any|object} If retrieving a single value or all options. 49694 @example $(selector).plugin('option', 'name', value) 49695 $(selector).plugin('option', {name: value, ...}) 49696 var value = $(selector).plugin('option', 'name') 49697 var options = $(selector).plugin('option') */ 49698 option: function(elem, name, value) { 49699 elem = $(elem); 49700 var inst = elem.data(this.name); 49701 if (!name || (typeof name === 'string' && value == null)) { 49702 var options = (inst || {}).options; 49703 return (options && name ? options[name] : options); 49704 } 49705 if (!elem.hasClass(this._getMarker())) { 49706 return; 49707 } 49708 var options = name || {}; 49709 if (typeof name === 'string') { 49710 options = {}; 49711 options[name] = value; 49712 } 49713 this._optionsChanged(elem, inst, options); 49714 $.extend(inst.options, options); 49715 }, 49716 49717 /** Plugin specific options processing. 49718 Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>. 49719 Override this in a sub-class to perform extra activities. 49720 @param elem {jQuery} The current jQuery element. 49721 @param inst {object} The instance settings. 49722 @param options {object} The new options. 49723 @example _optionsChanged: function(elem, inst, options) { 49724 if (options.name != inst.options.name) { 49725 elem.removeClass(inst.options.name).addClass(options.name); 49726 } 49727 } */ 49728 _optionsChanged: function(elem, inst, options) { 49729 }, 49730 49731 /** Remove all trace of the plugin. 49732 Override <code>_preDestroy</code> for plugin-specific processing. 49733 @param elem {Element} The source element. 49734 @example $(selector).plugin('destroy') */ 49735 destroy: function(elem) { 49736 elem = $(elem); 49737 if (!elem.hasClass(this._getMarker())) { 49738 return; 49739 } 49740 this._preDestroy(elem, this._getInst(elem)); 49741 elem.removeData(this.name).removeClass(this._getMarker()); 49742 }, 49743 49744 /** Plugin specific pre destruction. 49745 Override this in a sub-class to perform extra activities and undo everything that was 49746 done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions. 49747 @param elem {jQuery} The current jQuery element. 49748 @param inst {object} The instance settings. 49749 @example _preDestroy: function(elem, inst) { 49750 elem.off('.' + this.name); 49751 } */ 49752 _preDestroy: function(elem, inst) { 49753 } 49754 }); 49755 49756 /** Convert names from hyphenated to camel-case. 49757 @private 49758 @param value {string} The original hyphenated name. 49759 @return {string} The camel-case version. */ 49760 function camelCase(name) { 49761 return name.replace(/-([a-z])/g, function(match, group) { 49762 return group.toUpperCase(); 49763 }); 49764 } 49765 49766 /** Expose the plugin base. 49767 @namespace "$.JQPlugin" */ 49768 $.JQPlugin = { 49769 49770 /** Create a new collection plugin. 49771 @memberof "$.JQPlugin"
49772 @param [superClass='JQPlugin'] {string} The name of the parent class to inherit from. 49773 @param overrides {object} The property/function overrides for the new class. 49774 @example $.JQPlugin.createPlugin({ 49775 name: 'tabs', 49776 defaultOptions: {selectedClass: 'selected'}, 49777 _initSettings: function(elem, options) { return {...}; }, 49778 _postAttach: function(elem, inst) { ... } 49779 }); */ 49780 createPlugin: function(superClass, overrides) { 49781 if (typeof superClass === 'object') { 49782 overrides = superClass; 49783 superClass = 'JQPlugin'; 49784 } 49785 superClass = camelCase(superClass); 49786 var className = camelCase(overrides.name); 49787 JQClass.classes[className] = JQClass.classes[superClass].extend(overrides); 49788 new JQClass.classes[className](); 49789 } 49790 }; 49791 49792})(jQuery); 49793/* http://keith-wood.name/countdown.html 49794 Countdown for jQuery v2.0.2. 49795 Written by Keith Wood (kbwood{at}iinet.com.au) January 2008. 49796 Available under the MIT (http://keith-wood.name/licence.html) license. 49797 Please attribute the author if you use it. */ 49798 49799 49800(function($) { // Hide scope, no $ conflict 49801 49802 var pluginName = 'countdown'; 49803 49804 var Y = 0; // Years 49805 var O = 1; // Months 49806 var W = 2; // Weeks 49807 var D = 3; // Days 49808 var H = 4; // Hours 49809 var M = 5; // Minutes 49810 var S = 6; // Seconds 49811 49812 /** Create the countdown plugin. 49813 <p>Sets an element to show the time remaining until a given instant.</p> 49814 <p>Expects HTML like:</p> 49815 <pre><div></div></pre> 49816 <p>Provide inline configuration like:</p> 49817 <pre><div data-countdown="name: 'value'"></div></pre> 49818 @module Countdown 49819 @augments JQPlugin 49820 @example $(selector).countdown({until: +300}) */ 49821 $.JQPlugin.createPlugin({ 49822 49823 /** The name of the plugin. */ 49824 name: pluginName, 49825 49826 /** Countdown expiry callback. 49827 Triggered when the countdown expires. 49828 @callback expiryCallback */ 49829 49830 /** Countdown server synchronisation callback. 49831 Triggered when the countdown is initialised. 49832 @callback serverSyncCallback 49833 @return {Date} The current date/time on the server as expressed in the local timezone. */ 49834 49835 /** Countdown tick callback. 49836 Triggered on every <code>tickInterval</code> ticks of the countdown. 49837 @callback tickCallback 49838 @param periods {number[]} The breakdown by period (years, months, weeks, days, 49839 hours, minutes, seconds) of the time remaining/passed. */ 49840 49841 /** Countdown which labels callback. 49842 Triggered when the countdown is being display to determine which set of labels 49843 (<code>labels</code>, <code>labels1</code>, ...) are to be used for the current period value. 49844 @callback whichLabelsCallback 49845 @param num {number} The current period value. 49846 @return {number} The suffix for the label set to use. */ 49847 49848 /** Default settings for the plugin. 49849 @property until {Date|number|string} The date/time to count down to, or number of seconds 49850 offset from now, or string of amounts and units for offset(s) from now: 49851 'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds. 49852 @example until: new Date(2013, 12-1, 25, 13, 30) 49853 until: +300 49854 until: '+1O -2D' 49855 @property [since] {Date|number|string} The date/time to count up from, or 49856 number of seconds offset from now, or string for unit offset(s): 49857 'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds. 49858 @example since: new Date(2013, 1-1, 1) 49859 since: -300 49860 since: '-1O +2D' 49861 @property [timezone=null] {number} The timezone (hours or minutes from GMT) for the target times, 49862 or null for client local timezone. 49863 @example timezone: +10 49864 timezone: -60 49865 @property [serverSync=null] {serverSyncCallback} A function to retrieve the current server time 49866 for synchronisation. 49867 @property [format='dHMS'] {string} The format for display - upper case for always, lower case only if non-zero, 49868 'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds. 49869 @property [layout=''] {string} Build your own layout for the countdown. 49870 @example layout: '{d<}{dn} {dl}{d>} {hnn}:{mnn}:{snn}' 49871 @property [compact=false] {boolean} True to display in a compact format, false for an expanded one. 49872 @property [padZeroes=false] {boolean} True to add leading zeroes 49873 @property [significant=0] {number} The number of periods with non-zero values to show, zero for all. 49874 @property [description=''] {string} The description displayed for the countdown. 49875 @property [expiryUrl=''] {string} A URL to load upon expiry, replacing the current page. 49876 @property [expiryText=''] {string} Text to display upon expiry, replacing the countdown. This may be HTML. 49877 @property [alwaysExpire=false] {boolean} True to trigger <code>onExpiry</code> even if target time has passed. 49878 @property [onExpiry=null] {expiryCallback} Callback when the countdown expires - 49879 receives no parameters and <code>this</code> is the containing division. 49880 @example onExpiry: function() { 49881 ... 49882 } 49883 @property [onTick=null] {tickCallback} Callback when the countdown is updated - 49884 receives <code>number[7]</code> being the breakdown by period 49885 (years, months, weeks, days, hours, minutes, seconds - based on 49886 <code>format</code>) and <code>this</code> is the containing division. 49887 @example onTick: function(periods) { 49888 var secs = $.countdown.periodsToSeconds(periods); 49889 if (secs < 300) { // Last five minutes 49890 ... 49891 } 49892 } 49893 @property [tickInterval=1] {number} The interval (seconds) between <code>onTick</code> callbacks. */ 49894 defaultOptions: { 49895 until: null, 49896 since: null, 49897 timezone: null, 49898 serverSync: null, 49899 format: 'dHMS', 49900 layout: '', 49901 compact: false, 49902 padZeroes: false, 49903 significant: 0, 49904 description: '', 49905 expiryUrl: '', 49906 expiryText: '', 49907 alwaysExpire: false, 49908 onExpiry: null, 49909 onTick: null, 49910 tickInterval: 1 49911 }, 49912 49913 /** Localisations for the plugin. 49914 Entries are objects indexed by the language code ('' being the default US/English). 49915 Each object has the following attributes. 49916 @property [labels=['Years','Months','Weeks','Days','Hours','Minutes','Seconds']] {string[]} 49917 The display texts for the counter periods. 49918 @property [labels1=['Year','Month','Week','Day','Hour','Minute','Second']] {string[]} 49919 The display texts for the counter periods if they have a value of 1. 49920 Add other <code>labels<em>n</em></code> attributes as necessary to 49921 cater for other numeric idiosyncrasies of the localisation. 49922 @property [compactLabels=['y','m','w','d']] {string[]} The compact texts for the counter periods. 49923 @property [whichLabels=null] {whichLabelsCallback} A function to determine which 49924 <code>labels<em>n</em></code> to use. 49925 @example whichLabels: function(num) { 49926 return (num > 1 ? 0 : 1); 49927 } 49928 @property [digits=['0','1',...,'9']] {number[]} The digits to display (0-9). 49929 @property [timeSeparator=':'] {string} Separator for time periods in the compact layout. 49930 @property [isRTL=false] {boolean} True for right-to-left languages, false for left-to-right. */ 49931 regionalOptions: { // Available regional settings, indexed by language/country code 49932 '': { // Default regional settings - English/US 49933 labels: ['Years', 'Months', 'Weeks', 'Days', 'Hours', 'Minutes', 'Seconds'], 49934 labels1: ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minute', 'Second'], 49935 compactLabels: ['y', 'm', 'w', 'd'], 49936 whichLabels: null, 49937 digits: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], 49938 timeSeparator: ':', 49939 isRTL: false 49940 } 49941 }, 49942 49943 /** Names of getter methods - those that can't be chained. */ 49944 _getters: ['getTimes'], 49945 49946 /* Class name for the right-to-left marker. */ 49947 _rtlClass: pluginName + '-rtl', 49948 /* Class name for the countdown section marker. */ 49949 _sectionClass: pluginName + '-section',
49950 /* Class name for the period amount marker. */ 49951 _amountClass: pluginName + '-amount', 49952 /* Class name for the period name marker. */ 49953 _periodClass: pluginName + '-period', 49954 /* Class name for the countdown row marker. */ 49955 _rowClass: pluginName + '-row', 49956 /* Class name for the holding countdown marker. */ 49957 _holdingClass: pluginName + '-holding', 49958 /* Class name for the showing countdown marker. */ 49959 _showClass: pluginName + '-show', 49960 /* Class name for the description marker. */ 49961 _descrClass: pluginName + '-descr', 49962 49963 /* List of currently active countdown elements. */ 49964 _timerElems: [], 49965 49966 /** Additional setup for the countdown. 49967 Apply default localisations. 49968 Create the timer. */ 49969 _init: function() { 49970 var self = this; 49971 this._super(); 49972 this._serverSyncs = []; 49973 var now = (typeof Date.now == 'function' ? Date.now : 49974 function() { return new Date().getTime(); }); 49975 var perfAvail = (window.performance && typeof window.performance.now == 'function'); 49976 // Shared timer for all countdowns 49977 function timerCallBack(timestamp) { 49978 var drawStart = (timestamp < 1e12 ? // New HTML5 high resolution timer 49979 (perfAvail ? (performance.now() + performance.timing.navigationStart) : now()) : 49980 // Integer milliseconds since unix epoch 49981 timestamp || now()); 49982 if (drawStart - animationStartTime >= 1000) { 49983 self._updateElems(); 49984 animationStartTime = drawStart; 49985 } 49986 requestAnimationFrame(timerCallBack); 49987 } 49988 var requestAnimationFrame = window.requestAnimationFrame || 49989 window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || 49990 window.oRequestAnimationFrame || window.msRequestAnimationFrame || null; 49991 // This is when we expect a fall-back to setInterval as it's much more fluid 49992 var animationStartTime = 0; 49993 if (!requestAnimationFrame || $.noRequestAnimationFrame) { 49994 $.noRequestAnimationFrame = null; 49995 setInterval(function() { self._updateElems(); }, 980); // Fall back to good old setInterval 49996 } 49997 else { 49998 animationStartTime = window.animationStartTime || 49999 window.webkitAnimationStartTime || window.mozAnimationStartTime || 50000 window.oAnimationStartTime || window.msAnimationStartTime || now(); 50001 requestAnimationFrame(timerCallBack); 50002 } 50003 }, 50004 50005 /** Convert a date/time to UTC. 50006 @param tz {number} The hour or minute offset from GMT, e.g. +9, -360. 50007 @param year {Date|number} the date/time in that timezone or the year in that timezone. 50008 @param [month] {number} The month (0 - 11) (omit if <code>year</code> is a <code>Date</code>). 50009 @param [day] {number} The day (omit if <code>year</code> is a <code>Date</code>). 50010 @param [hours] {number} The hour (omit if <code>year</code> is a <code>Date</code>). 50011 @param [mins] {number} The minute (omit if <code>year</code> is a <code>Date</code>). 50012 @param [secs] {number} The second (omit if <code>year</code> is a <code>Date</code>). 50013 @param [ms] {number} The millisecond (omit if <code>year</code> is a <code>Date</code>). 50014 @return {Date} The equivalent UTC date/time. 50015 @example $.countdown.UTCDate(+10, 2013, 12-1, 25, 12, 0) 50016 $.countdown.UTCDate(-7, new Date(2013, 12-1, 25, 12, 0)) */ 50017 UTCDate: function(tz, year, month, day, hours, mins, secs, ms) { 50018 if (typeof year == 'object' && year.constructor == Date) { 50019 ms = year.getMilliseconds(); 50020 secs = year.getSeconds(); 50021 mins = year.getMinutes(); 50022 hours = year.getHours(); 50023 day = year.getDate(); 50024 month = year.getMonth(); 50025 year = year.getFullYear(); 50026 } 50027 var d = new Date(); 50028 d.setUTCFullYear(year); 50029 d.setUTCDate(1); 50030 d.setUTCMonth(month || 0); 50031 d.setUTCDate(day || 1); 50032 d.setUTCHours(hours || 0); 50033 d.setUTCMinutes((mins || 0) - (Math.abs(tz) < 30 ? tz * 60 : tz)); 50034 d.setUTCSeconds(secs || 0); 50035 d.setUTCMilliseconds(ms || 0); 50036 return d; 50037 }, 50038 50039 /** Convert a set of periods into seconds. 50040 Averaged for months and years. 50041 @param periods {number[]} The periods per year/month/week/day/hour/minute/second. 50042 @return {number} The corresponding number of seconds. 50043 @example var secs = $.countdown.periodsToSeconds(periods) */
50044 periodsToSeconds: function(periods) { 50045 return periods[0] * 31557600 + periods[1] * 2629800 + periods[2] * 604800 + 50046 periods[3] * 86400 + periods[4] * 3600 + periods[5] * 60 + periods[6]; 50047 }, 50048 50049 /** Resynchronise the countdowns with the server. 50050 @example $.countdown.resync() */ 50051 resync: function() { 50052 var self = this; 50053 $('.' + this._getMarker()).each(function() { // Each countdown 50054 var inst = $.data(this, self.name); 50055 if (inst.options.serverSync) { // If synced 50056 var serverSync = null; 50057 for (var i = 0; i < self._serverSyncs.length; i++) { 50058 if (self._serverSyncs[i][0] == inst.options.serverSync) { // Find sync details 50059 serverSync = self._serverSyncs[i]; 50060 break; 50061 } 50062 } 50063 if (serverSync[2] == null) { // Recalculate if missing 50064 var serverResult = ($.isFunction(inst.options.serverSync) ? 50065 inst.options.serverSync.apply(this, []) : null); 50066 serverSync[2] = 50067 (serverResult ? new Date().getTime() - serverResult.getTime() : 0) - serverSync[1]; 50068 } 50069 if (inst._since) { // Apply difference 50070 inst._since.setMilliseconds(inst._since.getMilliseconds() + serverSync[2]); 50071 } 50072 inst._until.setMilliseconds(inst._until.getMilliseconds() + serverSync[2]); 50073 } 50074 }); 50075 for (var i = 0; i < self._serverSyncs.length; i++) { // Update sync details 50076 if (self._serverSyncs[i][2] != null) { 50077 self._serverSyncs[i][1] += self._serverSyncs[i][2]; 50078 delete self._serverSyncs[i][2]; 50079 } 50080 } 50081 }, 50082 50083 _instSettings: function(elem, options) { 50084 return {_periods: [0, 0, 0, 0, 0, 0, 0]}; 50085 }, 50086 50087 /** Add an element to the list of active ones. 50088 @private 50089 @param elem {Element} The countdown element. */ 50090 _addElem: function(elem) { 50091 if (!this._hasElem(elem)) { 50092 this._timerElems.push(elem); 50093 } 50094 }, 50095 50096 /** See if an element is in the list of active ones. 50097 @private 50098 @param elem {Element} The countdown element. 50099 @return {boolean} True if present, false if not. */ 50100 _hasElem: function(elem) { 50101 return ($.inArray(elem, this._timerElems) > -1); 50102 }, 50103 50104 /** Remove an element from the list of active ones. 50105 @private 50106 @param elem {Element} The countdown element. */ 50107 _removeElem: function(elem) { 50108 this._timerElems = $.map(this._timerElems, 50109 function(value) { return (value == elem ? null : value); }); // delete entry 50110 }, 50111 50112 /** Update each active timer element. 50113 @private */ 50114 _updateElems: function() { 50115 for (var i = this._timerElems.length - 1; i >= 0; i--) { 50116 this._updateCountdown(this._timerElems[i]); 50117 } 50118 }, 50119 50120 _optionsChanged: function(elem, inst, options) { 50121 if (options.layout) { 50122 options.layout = options.layout.replace(/</g, '<').replace(/>/g, '>'); 50123 } 50124 this._resetExtraLabels(inst.options, options); 50125 var timezoneChanged = (inst.options.timezone != options.timezone); 50126 $.extend(inst.options, options); 50127 this._adjustSettings(elem, inst, 50128 options.until != null || options.since != null || timezoneChanged); 50129 var now = new Date(); 50130 if ((inst._since && inst._since < now) || (inst._until && inst._until > now)) { 50131 this._addElem(elem[0]); 50132 } 50133 this._updateCountdown(elem, inst); 50134 }, 50135 50136 /** Redisplay the countdown with an updated display. 50137 @private 50138 @param elem {Element|jQuery} The containing division. 50139 @param inst {object} The current settings for this instance. */ 50140 _updateCountdown: function(elem, inst) { 50141 elem = elem.jquery ? elem : $(elem); 50142 inst = inst || this._getInst(elem); 50143 if (!inst) { 50144 return; 50145 } 50146 elem.html(this._generateHTML(inst)).toggleClass(this._rtlClass, inst.options.isRTL); 50147 if ($.isFunction(inst.options.onTick)) { 50148 var periods = inst._hold != 'lap' ? inst._periods : 50149 this._calculatePeriods(inst, inst._show, inst.options.significant, new Date()); 50150 if (inst.options.tickInterval == 1 || 50151 this.periodsToSeconds(periods) % inst.options.tickInterval == 0) { 50152 inst.options.onTick.apply(elem[0], [periods]); 50153 } 50154 } 50155 var expired = inst._hold != 'pause' && 50156 (inst._since ? inst._now.getTime() < inst._since.getTime() : 50157 inst._now.getTime() >= inst._until.getTime()); 50158 if (expired && !inst._expiring) { 50159 inst._expiring = true; 50160 if (this._hasElem(elem[0]) || inst.options.alwaysExpire) { 50161 this._removeElem(elem[0]); 50162 if ($.isFunction(inst.options.onExpiry)) { 50163 inst.options.onExpiry.apply(elem[0], []); 50164 } 50165 if (inst.options.expiryText) { 50166 var layout = inst.options.layout; 50167 inst.options.layout = inst.options.expiryText; 50168 this._updateCountdown(elem[0], inst); 50169 inst.options.layout = layout; 50170 } 50171 if (inst.options.expiryUrl) { 50172 window.location = inst.options.expiryUrl; 50173 } 50174 } 50175 inst._expiring = false;
50176 } 50177 else if (inst._hold == 'pause') { 50178 this._removeElem(elem[0]); 50179 } 50180 }, 50181 50182 /** Reset any extra labelsn and compactLabelsn entries if changing labels. 50183 @private 50184 @param base {object} The options to be updated. 50185 @param options {object} The new option values. */ 50186 _resetExtraLabels: function(base, options) { 50187 for (var n in options) { 50188 if (n.match(/[Ll]abels[02-9]|compactLabels1/)) { 50189 base[n] = options[n]; 50190 } 50191 } 50192 for (var n in base) { // Remove custom numbered labels 50193 if (n.match(/[Ll]abels[02-9]|compactLabels1/) && typeof options[n] === 'undefined') { 50194 base[n] = null; 50195 } 50196 } 50197 }, 50198 50199 /** Calculate internal settings for an instance. 50200 @private 50201 @param elem {jQuery} The containing division. 50202 @param inst {object} The current settings for this instance. 50203 @param recalc {boolean} True if until or since are set. */ 50204 _adjustSettings: function(elem, inst, recalc) { 50205 var serverEntry = null; 50206 for (var i = 0; i < this._serverSyncs.length; i++) { 50207 if (this._serverSyncs[i][0] == inst.options.serverSync) { 50208 serverEntry = this._serverSyncs[i][1]; 50209 break; 50210 } 50211 } 50212 if (serverEntry != null) { 50213 var serverOffset = (inst.options.serverSync ? serverEntry : 0); 50214 var now = new Date(); 50215 } 50216 else { 50217 var serverResult = ($.isFunction(inst.options.serverSync) ? 50218 inst.options.serverSync.apply(elem[0], []) : null); 50219 var now = new Date(); 50220 var serverOffset = (serverResult ? now.getTime() - serverResult.getTime() : 0); 50221 this._serverSyncs.push([inst.options.serverSync, serverOffset]); 50222 } 50223 var timezone = inst.options.timezone; 50224 timezone = (timezone == null ? -now.getTimezoneOffset() : timezone); 50225 if (recalc || (!recalc && inst._until == null && inst._since == null)) { 50226 inst._since = inst.options.since; 50227 if (inst._since != null) { 50228 inst._since = this.UTCDate(timezone, this._determineTime(inst._since, null)); 50229 if (inst._since && serverOffset) { 50230 inst._since.setMilliseconds(inst._since.getMilliseconds() + serverOffset); 50231 } 50232 } 50233 inst._until = this.UTCDate(timezone, this._determineTime(inst.options.until, now)); 50234 if (serverOffset) { 50235 inst._until.setMilliseconds(inst._until.getMilliseconds() + serverOffset); 50236 } 50237 } 50238 inst._show = this._determineShow(inst); 50239 }, 50240 50241 /** Remove the countdown widget from a div. 50242 @param elem {jQuery} The containing division. 50243 @param inst {object} The current instance object. */ 50244 _preDestroy: function(elem, inst) { 50245 this._removeElem(elem[0]); 50246 elem.empty(); 50247 }, 50248 50249 /** Pause a countdown widget at the current time. 50250 Stop it running but remember and display the current time. 50251 @param elem {Element} The containing division. 50252 @example $(selector).countdown('pause') */ 50253 pause: function(elem) { 50254 this._hold(elem, 'pause'); 50255 }, 50256 50257 /** Pause a countdown widget at the current time. 50258 Stop the display but keep the countdown running. 50259 @param elem {Element} The containing division. 50260 @example $(selector).countdown('lap') */ 50261 lap: function(elem) { 50262 this._hold(elem, 'lap'); 50263 }, 50264 50265 /** Resume a paused countdown widget. 50266 @param elem {Element} The containing division. 50267 @example $(selector).countdown('resume') */ 50268 resume: function(elem) { 50269 this._hold(elem, null); 50270 }, 50271 50272 /** Toggle a paused countdown widget. 50273 @param elem {Element} The containing division. 50274 @example $(selector).countdown('toggle') */ 50275 toggle: function(elem) { 50276 var inst = $.data(elem, this.name) || {}; 50277 this[!inst._hold ? 'pause' : 'resume'](elem); 50278 }, 50279 50280 /** Toggle a lapped countdown widget. 50281 @param elem {Element} The containing division. 50282 @example $(selector).countdown('toggleLap') */ 50283 toggleLap: function(elem) { 50284 var inst = $.data(elem, this.name) || {}; 50285 this[!inst._hold ? 'lap' : 'resume'](elem); 50286 }, 50287 50288 /** Pause or resume a countdown widget. 50289 @private 50290 @param elem {Element} The containing division. 50291 @param hold {string} The new hold setting. */ 50292 _hold: function(elem, hold) { 50293 var inst = $.data(elem, this.name); 50294 if (inst) { 50295 if (inst._hold == 'pause' && !hold) { 50296 inst._periods = inst._savePeriods; 50297 var sign = (inst._since ? '-' : '+'); 50298 inst[inst._since ? '_since' : '_until'] =
50299 this._determineTime(sign + inst._periods[0] + 'y' + 50300 sign + inst._periods[1] + 'o' + sign + inst._periods[2] + 'w' + 50301 sign + inst._periods[3] + 'd' + sign + inst._periods[4] + 'h' + 50302 sign + inst._periods[5] + 'm' + sign + inst._periods[6] + 's'); 50303 this._addElem(elem); 50304 } 50305 inst._hold = hold; 50306 inst._savePeriods = (hold == 'pause' ? inst._periods : null); 50307 $.data(elem, this.name, inst); 50308 this._updateCountdown(elem, inst); 50309 } 50310 }, 50311 50312 /** Return the current time periods. 50313 @param elem {Element} The containing division. 50314 @return {number[]} The current periods for the countdown. 50315 @example var periods = $(selector).countdown('getTimes') */ 50316 getTimes: function(elem) { 50317 var inst = $.data(elem, this.name); 50318 return (!inst ? null : (inst._hold == 'pause' ? inst._savePeriods : (!inst._hold ? inst._periods : 50319 this._calculatePeriods(inst, inst._show, inst.options.significant, new Date())))); 50320 }, 50321 50322 /** A time may be specified as an exact value or a relative one. 50323 @private 50324 @param setting {string|number|Date} The date/time value as a relative or absolute value. 50325 @param defaultTime {Date} The date/time to use if no other is supplied. 50326 @return {Date} The corresponding date/time. */ 50327 _determineTime: function(setting, defaultTime) { 50328 var self = this; 50329 var offsetNumeric = function(offset) { // e.g. +300, -2 50330 var time = new Date(); 50331 time.setTime(time.getTime() + offset * 1000); 50332 return time; 50333 }; 50334 var offsetString = function(offset) { // e.g. '+2d', '-4w', '+3h +30m' 50335 offset = offset.toLowerCase(); 50336 var time = new Date(); 50337 var year = time.getFullYear(); 50338 var month = time.getMonth(); 50339 var day = time.getDate(); 50340 var hour = time.getHours(); 50341 var minute = time.getMinutes(); 50342 var second = time.getSeconds(); 50343 var pattern = /([+-]?[0-9]+)\s*(s|m|h|d|w|o|y)?/g; 50344 var matches = pattern.exec(offset); 50345 while (matches) { 50346 switch (matches[2] || 's') { 50347 case 's': second += parseInt(matches[1], 10); break; 50348 case 'm': minute += parseInt(matches[1], 10); break; 50349 case 'h': hour += parseInt(matches[1], 10); break; 50350 case 'd': day += parseInt(matches[1], 10); break; 50351 case 'w': day += parseInt(matches[1], 10) * 7; break; 50352 case 'o': 50353 month += parseInt(matches[1], 10); 50354 day = Math.min(day, self._getDaysInMonth(year, month)); 50355 break; 50356 case 'y': 50357 year += parseInt(matches[1], 10); 50358 day = Math.min(day, self._getDaysInMonth(year, month)); 50359 break; 50360 } 50361 matches = pattern.exec(offset); 50362 } 50363 return new Date(year, month, day, hour, minute, second, 0); 50364 }; 50365 var time = (setting == null ? defaultTime : 50366 (typeof setting == 'string' ? offsetString(setting) : 50367 (typeof setting == 'number' ? offsetNumeric(setting) : setting))); 50368 if (time) time.setMilliseconds(0); 50369 return time; 50370 }, 50371 50372 /** Determine the number of days in a month. 50373 @private 50374 @param year {number} The year. 50375 @param month {number} The month. 50376 @return {number} The days in that month. */ 50377 _getDaysInMonth: function(year, month) { 50378 return 32 - new Date(year, month, 32).getDate(); 50379 }, 50380 50381 /** Default implementation to determine which set of labels should be used for an amount. 50382 Use the <code>labels</code> attribute with the same numeric suffix (if it exists). 50383 @private 50384 @param num {number} The amount to be displayed. 50385 @return {number} The set of labels to be used for this amount. */ 50386 _normalLabels: function(num) { 50387 return num; 50388 }, 50389 50390 /** Generate the HTML to display the countdown widget. 50391 @private 50392 @param inst {object} The current settings for this instance. 50393 @return {string} The new HTML for the countdown display. */ 50394 _generateHTML: function(inst) { 50395 var self = this; 50396 // Determine what to show 50397 inst._periods = (inst._hold ? inst._periods : 50398 this._calculatePeriods(inst, inst._show, inst.options.significant, new Date())); 50399 // Show all 'asNeeded' after first non-zero value 50400 var shownNonZero = false; 50401 var showCount = 0; 50402 var sigCount = inst.options.significant; 50403 var show = $.extend({}, inst._show); 50404 for (var period = Y; period <= S; period++) {
50405 shownNonZero |= (inst._show[period] == '?' && inst._periods[period] > 0); 50406 show[period] = (inst._show[period] == '?' && !shownNonZero ? null : inst._show[period]); 50407 showCount += (show[period] ? 1 : 0); 50408 sigCount -= (inst._periods[period] > 0 ? 1 : 0); 50409 } 50410 var showSignificant = [false, false, false, false, false, false, false]; 50411 for (var period = S; period >= Y; period--) { // Determine significant periods 50412 if (inst._show[period]) { 50413 if (inst._periods[period]) { 50414 showSignificant[period] = true; 50415 } 50416 else { 50417 showSignificant[period] = sigCount > 0; 50418 sigCount--; 50419 } 50420 } 50421 } 50422 var labels = (inst.options.compact ? inst.options.compactLabels : inst.options.labels); 50423 var whichLabels = inst.options.whichLabels || this._normalLabels; 50424 var showCompact = function(period) { 50425 var labelsNum = inst.options['compactLabels' + whichLabels(inst._periods[period])]; 50426 return (show[period] ? self._translateDigits(inst, inst._periods[period]) + 50427 (labelsNum ? labelsNum[period] : labels[period]) + ' ' : ''); 50428 }; 50429 var minDigits = (inst.options.padZeroes ? 2 : 1); 50430 var showFull = function(period) { 50431 var labelsNum = inst.options['labels' + whichLabels(inst._periods[period])]; 50432 return ((!inst.options.significant && show[period]) || 50433 (inst.options.significant && showSignificant[period]) ? 50434 '<span class="' + self._sectionClass + '">' + 50435 '<span class="' + self._amountClass + '">' + 50436 self._minDigits(inst, inst._periods[period], minDigits) + '</span>' + 50437 '<span class="' + self._periodClass + '">' + 50438 (labelsNum ? labelsNum[period] : labels[period]) + '</span></span>' : ''); 50439 }; 50440 return (inst.options.layout ? this._buildLayout(inst, show, inst.options.layout, 50441 inst.options.compact, inst.options.significant, showSignificant) : 50442 ((inst.options.compact ? // Compact version 50443 '<span class="' + this._rowClass + ' ' + this._amountClass + 50444 (inst._hold ? ' ' + this._holdingClass : '') + '">' + 50445 showCompact(Y) + showCompact(O) + showCompact(W) + showCompact(D) + 50446 (show[H] ? this._minDigits(inst, inst._periods[H], 2) : '') + 50447 (show[M] ? (show[H] ? inst.options.timeSeparator : '') + 50448 this._minDigits(inst, inst._periods[M], 2) : '') + 50449 (show[S] ? (show[H] || show[M] ? inst.options.timeSeparator : '') + 50450 this._minDigits(inst, inst._periods[S], 2) : '') : 50451 // Full version 50452 '<span class="' + this._rowClass + ' ' + this._showClass + (inst.options.significant || showCount) + 50453 (inst._hold ? ' ' + this._holdingClass : '') + '">' + 50454 showFull(Y) + showFull(O) + showFull(W) + showFull(D) + 50455 showFull(H) + showFull(M) + showFull(S)) + '</span>' + 50456 (inst.options.description ? '<span class="' + this._rowClass + ' ' + this._descrClass + '">' + 50457 inst.options.description + '</span>' : ''))); 50458 }, 50459 50460 /** Construct a custom layout. 50461 @private 50462 @param inst {object} The current settings for this instance. 50463 @param show {boolean[]} Flags indicating which periods are requested. 50464 @param layout {string} The customised layout. 50465 @param compact {boolean} True if using compact labels. 50466 @param significant {number} The number of periods with values to show, zero for all. 50467 @param showSignificant {boolean[]} Other periods to show for significance. 50468 @return {string} The custom HTML. */ 50469 _buildLayout: function(inst, show, layout, compact, significant, showSignificant) { 50470 var labels = inst.options[compact ? 'compactLabels' : 'labels']; 50471 var whichLabels = inst.options.whichLabels || this._normalLabels; 50472 var labelFor = function(index) { 50473 return (inst.options[(compact ? 'compactLabels' : 'labels') + 50474 whichLabels(inst._periods[index])] || labels)[index]; 50475 }; 50476 var digit = function(value, position) { 50477 return inst.options.digits[Math.floor(value / position) % 10]; 50478 }; 50479 var subs = {desc: inst.options.description, sep: inst.options.timeSeparator, 50480 yl: labelFor(Y), yn: this._minDigits(inst, inst._periods[Y], 1), 50481 ynn: this._minDigits(inst, inst._periods[Y], 2), 50482 ynnn: this._minDigits(inst, inst._periods[Y], 3), y1: digit(inst._periods[Y], 1),
50483 y10: digit(inst._periods[Y], 10), y100: digit(inst._periods[Y], 100), 50484 y1000: digit(inst._periods[Y], 1000), 50485 ol: labelFor(O), on: this._minDigits(inst, inst._periods[O], 1), 50486 onn: this._minDigits(inst, inst._periods[O], 2), 50487 onnn: this._minDigits(inst, inst._periods[O], 3), o1: digit(inst._periods[O], 1), 50488 o10: digit(inst._periods[O], 10), o100: digit(inst._periods[O], 100), 50489 o1000: digit(inst._periods[O], 1000), 50490 wl: labelFor(W), wn: this._minDigits(inst, inst._periods[W], 1), 50491 wnn: this._minDigits(inst, inst._periods[W], 2), 50492 wnnn: this._minDigits(inst, inst._periods[W], 3), w1: digit(inst._periods[W], 1), 50493 w10: digit(inst._periods[W], 10), w100: digit(inst._periods[W], 100), 50494 w1000: digit(inst._periods[W], 1000), 50495 dl: labelFor(D), dn: this._minDigits(inst, inst._periods[D], 1), 50496 dnn: this._minDigits(inst, inst._periods[D], 2), 50497 dnnn: this._minDigits(inst, inst._periods[D], 3), d1: digit(inst._periods[D], 1), 50498 d10: digit(inst._periods[D], 10), d100: digit(inst._periods[D], 100), 50499 d1000: digit(inst._periods[D], 1000), 50500 hl: labelFor(H), hn: this._minDigits(inst, inst._periods[H], 1), 50501 hnn: this._minDigits(inst, inst._periods[H], 2), 50502 hnnn: this._minDigits(inst, inst._periods[H], 3), h1: digit(inst._periods[H], 1), 50503 h10: digit(inst._periods[H], 10), h100: digit(inst._periods[H], 100), 50504 h1000: digit(inst._periods[H], 1000), 50505 ml: labelFor(M), mn: this._minDigits(inst, inst._periods[M], 1), 50506 mnn: this._minDigits(inst, inst._periods[M], 2), 50507 mnnn: this._minDigits(inst, inst._periods[M], 3), m1: digit(inst._periods[M], 1), 50508 m10: digit(inst._periods[M], 10), m100: digit(inst._periods[M], 100), 50509 m1000: digit(inst._periods[M], 1000), 50510 sl: labelFor(S), sn: this._minDigits(inst, inst._periods[S], 1), 50511 snn: this._minDigits(inst, inst._periods[S], 2), 50512 snnn: this._minDigits(inst, inst._periods[S], 3), s1: digit(inst._periods[S], 1), 50513 s10: digit(inst._periods[S], 10), s100: digit(inst._periods[S], 100), 50514 s1000: digit(inst._periods[S], 1000)}; 50515 var html = layout; 50516 // Replace period containers: {p<}...{p>} 50517 for (var i = Y; i <= S; i++) { 50518 var period = 'yowdhms'.charAt(i); 50519 var re = new RegExp('\\{' + period + '<\\}([\\s\\S]*)\\{' + period + '>\\}', 'g'); 50520 html = html.replace(re, ((!significant && show[i]) || 50521 (significant && showSignificant[i]) ? '$1' : '')); 50522 } 50523 // Replace period values: {pn} 50524 $.each(subs, function(n, v) { 50525 var re = new RegExp('\\{' + n + '\\}', 'g'); 50526 html = html.replace(re, v); 50527 }); 50528 return html; 50529 }, 50530 50531 /** Ensure a numeric value has at least n digits for display. 50532 @private 50533 @param inst {object} The current settings for this instance. 50534 @param value {number} The value to display. 50535 @param len {number} The minimum length. 50536 @return {string} The display text. */ 50537 _minDigits: function(inst, value, len) { 50538 value = '' + value; 50539 if (value.length >= len) { 50540 return this._translateDigits(inst, value); 50541 } 50542 value = '0000000000' + value; 50543 return this._translateDigits(inst, value.substr(value.length - len)); 50544 }, 50545 50546 /** Translate digits into other representations. 50547 @private 50548 @param inst {object} The current settings for this instance. 50549 @param value {string} The text to translate. 50550 @return {string} The translated text. */ 50551 _translateDigits: function(inst, value) { 50552 return ('' + value).replace(/[0-9]/g, function(digit) { 50553 return inst.options.digits[digit]; 50554 }); 50555 }, 50556 50557 /** Translate the format into flags for each period. 50558 @private 50559 @param inst {object} The current settings for this instance. 50560 @return {string[]} Flags indicating which periods are requested (?) or 50561 required (!) by year, month, week, day, hour, minute, second. */ 50562 _determineShow: function(inst) { 50563 var format = inst.options.format; 50564 var show = []; 50565 show[Y] = (format.match('y') ? '?' : (format.match('Y') ? '!' : null)); 50566 show[O] = (format.match('o') ? '?' : (format.match('O') ? '!' : null)); 50567 show[W] = (format.match('w') ? '?' : (format.match('W') ? '!' : null)); 50568 show[D] = (format.match('d') ? '?' : (format.match('D') ? '!' : null)); 50569 show[H] = (format.match('h') ? '?' : (format.match('H') ? '!' : null)); 50570 show[M] = (format.match('m') ? '?' : (format.match('M') ? '!' : null)); 50571 show[S] = (format.match('s') ? '?' : (format.match('S') ? '!' : null)); 50572 return show; 50573 }, 50574 50575 /** Calculate the requested periods between now and the target time. 50576 @private 50577 @param inst {object} The current settings for this instance. 50578 @param show {string[]} Flags indicating which periods are requested/required. 50579 @param significant {number} The number of periods with values to show, zero for all. 50580 @param now {Date} The current date and time. 50581 @return {number[]} The current time periods (always positive) 50582 by year, month, week, day, hour, minute, second. */
50583 _calculatePeriods: function(inst, show, significant, now) { 50584 // Find endpoints 50585 inst._now = now; 50586 inst._now.setMilliseconds(0); 50587 var until = new Date(inst._now.getTime()); 50588 if (inst._since) { 50589 if (now.getTime() < inst._since.getTime()) { 50590 inst._now = now = until; 50591 } 50592 else { 50593 now = inst._since; 50594 } 50595 } 50596 else { 50597 until.setTime(inst._until.getTime()); 50598 if (now.getTime() > inst._until.getTime()) { 50599 inst._now = now = until; 50600 } 50601 } 50602 // Calculate differences by period 50603 var periods = [0, 0, 0, 0, 0, 0, 0]; 50604 if (show[Y] || show[O]) { 50605 // Treat end of months as the same 50606 var lastNow = this._getDaysInMonth(now.getFullYear(), now.getMonth()); 50607 var lastUntil = this._getDaysInMonth(until.getFullYear(), until.getMonth()); 50608 var sameDay = (until.getDate() == now.getDate() || 50609 (until.getDate() >= Math.min(lastNow, lastUntil) && 50610 now.getDate() >= Math.min(lastNow, lastUntil))); 50611 var getSecs = function(date) { 50612 return (date.getHours() * 60 + date.getMinutes()) * 60 + date.getSeconds(); 50613 }; 50614 var months = Math.max(0, 50615 (until.getFullYear() - now.getFullYear()) * 12 + until.getMonth() - now.getMonth() + 50616 ((until.getDate() < now.getDate() && !sameDay) || 50617 (sameDay && getSecs(until) < getSecs(now)) ? -1 : 0)); 50618 periods[Y] = (show[Y] ? Math.floor(months / 12) : 0); 50619 periods[O] = (show[O] ? months - periods[Y] * 12 : 0); 50620 // Adjust for months difference and end of month if necessary 50621 now = new Date(now.getTime()); 50622 var wasLastDay = (now.getDate() == lastNow); 50623 var lastDay = this._getDaysInMonth(now.getFullYear() + periods[Y], 50624 now.getMonth() + periods[O]); 50625 if (now.getDate() > lastDay) { 50626 now.setDate(lastDay); 50627 } 50628 now.setFullYear(now.getFullYear() + periods[Y]); 50629 now.setMonth(now.getMonth() + periods[O]); 50630 if (wasLastDay) { 50631 now.setDate(lastDay); 50632 } 50633 } 50634 var diff = Math.floor((until.getTime() - now.getTime()) / 1000); 50635 var extractPeriod = function(period, numSecs) { 50636 periods[period] = (show[period] ? Math.floor(diff / numSecs) : 0); 50637 diff -= periods[period] * numSecs; 50638 }; 50639 extractPeriod(W, 604800); 50640 extractPeriod(D, 86400); 50641 extractPeriod(H, 3600); 50642 extractPeriod(M, 60); 50643 extractPeriod(S, 1); 50644 if (diff > 0 && !inst._since) { // Round up if left overs 50645 var multiplier = [1, 12, 4.3482, 7, 24, 60, 60]; 50646 var lastShown = S; 50647 var max = 1; 50648 for (var period = S; period >= Y; period--) { 50649 if (show[period]) { 50650 if (periods[lastShown] >= max) { 50651 periods[lastShown] = 0; 50652 diff = 1; 50653 } 50654 if (diff > 0) { 50655 periods[period]++; 50656 diff = 0; 50657 lastShown = period; 50658 max = 1; 50659 } 50660 } 50661 max *= multiplier[period]; 50662 } 50663 } 50664 if (significant) { // Zero out insignificant periods 50665 for (var period = Y; period <= S; period++) { 50666 if (significant && periods[period]) { 50667 significant--; 50668 } 50669 else if (!significant) { 50670 periods[period] = 0; 50671 } 50672 } 50673 } 50674 return periods; 50675 } 50676 }); 50677 50678})(jQuery); 50679// Countdown dependency as a manifest 50680 50681 50682; 50683 50684 50685 50686 50687 50688 50689 50690 50691
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.